A spreadsheet is a two-dimensional array of cells:
public class
SpreadSheet {
private int numRows, numCols;
private Cell[][] cells;
public SpreadSheet(int rows, int cols) {
numRows = rows;
numCols = cols;
cells = new Cell[numRows][numCols];
for(int i = 0; i < numRows; i++) {
for(int j = 0; j < numCols; j++) {
cells[i][j] = new Cell();
}
}
}
// etc.
}
A cell contains a value of type double and may contain a formula of type String that constrains the value.
Formulas are sums of products. A product multiplies a coefficient times the value of another cell. For example, cell C might contain the formula:
.2 * s1 + .2 * s2 + .6 * s3
This means that the value of C must be equal to the value of this formula, where s1, s2, and s3 refer to three other cells in the spreadsheet. We call these other cells C's subjects.
Professor Glum uses a spreadsheet to keep track of his two students: Smith and Jones. Here are two versions:
Here is the output produced by the second version:
78.0 95.0 66.0 78.3
56.0 78.0 92.0 77.0
0.0 0.0 0.0 77.65
0.0 0.0 0.0 0.0
Note that on the second version only the average of the averages is computed.
Note that when the value of a subject cell changes, for example, when Professor Glum modified the final exam scores of both students, then Smith's average and Jones's average needed to be updated automatically. When these cells changed, the average of the averages also needed to be updated.
In general, when one or more of cell C's subjects change value then C must use its formula to change its value. Of course C might be the subject of another cell, D, which must update its value according to its formula.
While D knows that C is one of its subjects, C can't be expected to know this. In general, the set of cells that have C as a subject may change dynamically. How can C notify the cells in this set when its value changes?
This is an example of the Event Notification Problem:
How can a subject object notify a heterogeneous, dynamically changing collection of observer objects when its state changes?
"Dynamically changing" means that the number of observers can change over time.
Heterogeneous means that different observers might have different types.
In a nuclear power plant the reactor (the subject) needs to notify various sensors scattered around the plant (the observers) when its temperature (state) changes. Engineers are always adding and removing sensors in the plant (dynamically changing). There are many types of sensors: alarms, thermometers, thermostats, etc. (heterogeneous).
In this situation the reactor doesn't know the number and types of sensors that need to be notified.
There are several solutions to the Event Notification Problem.
We want to avoid hardwiring the subject with information about the number and types of observers. Every time a new observer is added or removed we will have to modify the subject.
Active observers (observers with their own VM or thread) can repeatedly poll the subject's state. This can be inefficient if the subject's state changes infrequently relative to the polling time.
One commonly used design pattern in the Publisher-Subscriber Pattern.
This pattern involves four roles:
Publisher: A reusable class that maintains and notifies a list of subscribers.
Subscriber: The interface all concrete subscribers must implement.
Concrete Publisher: The subject
Concrete Subscribers: The observers
Returning to our spreadsheet example, we see that cells are simultaneously subjects and observers:
Publisher: java.util.Observable
Subscriber: java.util.Observer
Concrete Publisher: Cell
Concrete Subscribers: Cell
The complete code is here:
Normally we start with the design:
The details can be found in: