Communication is concerned with routing commands and event notifications as well as making
data generated in one part of the code accessible to any other parts that need to use it.
for example, an executive package communicates with each of its child packages, e.g., the packages that are responsible
for each task of the program, to activate them at the appropriate phase of computation and may receive
notifications of errors the child encountered.
Often
data flows between class instances in each top level package through method calls and may evolve
in simple and intuitive ways. However, as systems get larger data access may become considerably more
complicated.
Careful design of class ownership is the key to effective communication: a class has
access to the public interface of its parts - composed and aggregated instances of other classes - and can directly send and receive data
as well as issue commands to them and receive notifications from them.
The
parser is an interesting example of the use of ownership.
Its object factory, configureParser, owns all the Rules and Actions that determine how parsing
is executed. When configureParser creates each action it passes a reference to a data Repository to them.
Actions can store data and use data that other actions have added. Thus an action
can use the results of other actions that it otherwise has no access to.
We can, of course, openly share data in ways that make it accessible throughout an entire process or
even for any process running in the same machine.
-
We can declare a static member of some class and make it accessible through the class's public interface;
then any other code running in the same process that declares an instance of the wrapper class has access to the static instance.
-
Global data in C and C++ programs also provides process wide sharing, but in a much less
controllable way and is usually avoided.
-
We can also share through machine wide resources like files and shared memory.
We occasionally resort to open sharing using one of these techniques but need to recognize
that open sharing comes with costs: need to ensure thread-safe access in a concurrent environment,
and problems with conflicts in use, e.g., two methods using the shared datum in conflicting ways.
Open sharing makes it considerably more difficult to think critically about operations of the
code and to ensure they are correct.