The third solution uses a form of component integration based on shared data
similar to the first solution. However, there are two important differences.
First, the interface to the data is more abstract. Rather than exposing the
storage formats to the computing modules, data is accessed abstractly (for
example, as a list or set). Second, computations are invoked implicitly as
data is modified. For example, the act of adding a new line to the line
storage causes an event to be sent to the shift module. This allows it to
produce circular shifts (in a separate abstract shared data store). This in
turn causes the alphabetizer to be implicitly invoked so that it can
alphabetize the lines. Additional discussion of this integration paradigm can
be found elsewhere [GarlanNotkin91].
Reactive Architecture
This solution easily supports functional enhancements to the system: additional modules can be attached to the system by registering them to be invoked on certain events. Because data is accessed abstractly, it also insulates computations from changes in data representation. Reuse is also supported, since the implicitly invoked modules only rely on the existence of certain externally triggered events.
However, the solution suffers from the fact that it can be difficult to change the order of processing of the implicitly invoked modules. Further, because invocations are data driven, the most natural solutions using this kind of decomposition tend to use more space than the previously considered decompositions.
Updated Halloween 95 by
Mary Shaw
Comments to maintainer