Same Data Used for Different Purposes
Let's assume that we have a single source that generates data of interest to us. This data changes relatively steadily; an example of which is a process based on ftp or some other data transport protocol. Figure 1 illustrates a common example of a management system interacting with network devices. The purpose of the management system is to help maintain the orderly operation of the network. This maintenance is achieved by automating tasks such as fault handling and rectification, software distribution, congestion avoidance, and so on. The management system user interacts with the network devices in a number of ways—one of these is the area of backup and restore.
Figure 1 Data sources.
Two operations are illustrated in Figure 1: The software for the device on the right side is having its code updated, and the other device is having its configuration database backed up. (These operations are fairly normal procedures in network management.) Device software can be updated to take advantage of a patch or an entirely new version or for times when the code is corrupted. Device database configurations are increasingly complex, and it is essential to protect this data—as is the case for software. So on the left side of Figure 1, we see a database backup occurring.
Clearly, the database backup operation occurs in the direction from the device to the management system, i.e., the latter initiates the operation and this is followed by a lengthy data transfer process. I'm assuming that the device provides some indication of how far into the backup it has progressed in percentage terms. I use this to update the database backup process observers (more on this later).
Both code and database backup/restore operations can take many minutes to complete. So a user would typically want some idea of the progress of the transfers. The classic observer pattern allows for multiple users to see the same data rendered in different ways (e.g., user 1 might want to see a bar chart; user 2 might want to see text-only). I'll follow this model and use two observers, which will keep track of the code and database operations. One observer sees the operation type (database backup) and its percent complete figure, whereas the other observer sees just the percent completion of the database backup.
In the C++ code example, I'll focus on the management system in the center of Figure 1. This system provides the basis for the observer pattern. Listing 1 illustrates the observer in action (you'll see the details later).
Listing 1 One Subject and Multiple Observers
1. Updating observer operation data DB Backup 10% Complete 2. Updating observer operation data 10% 3. Updating observer operation data DB Backup 50% Complete 4. Updating observer operation data 50%
Listing 1 illustrates a subject or data producer generating the required information. This information changes as the underlying operation progresses toward completion. If the observers were running on different machines, then lines 1 and 3 would be seen on one machine, whereas lines 2 and 4 would be seen on the other machine.
In line 1 of Listing 1, you see an observer being updated, indicating 10% completion of the associated operation (database backup). On line 2, a second observer is interested purely in the percentage completion of the operation (10% in this case). The key thing to note is that the information provider (or subject) is the same for lines 1 and 2—only the rendering of the data is different.
In lines 3 and 4, the operation has advanced and the observers have been updated accordingly. As the operations progress, you see lines 3 and 4 reflecting the changes.