Pattern Summaries: Fundamental Patterns
The essence of a pattern is a reusable solution for a recurring problem. A complete pattern will also provide reasons to use or not use the solution, the consequences of using the solution, and suggestions on how to implement the solution. The summaries in these articles will just describe the essential problem and its solution.
The first few patterns that I will be summarizing fall into a category that I call Fundamental Patterns. They are fundamental in the sense that they are widely used by other patterns or are frequently used in a large number of programs.
A common problem is that you want an object to be able to use another object that provides a service without having to assume the class of the other object. The usual solution to the problem is to have the object assume that the object it uses implements a particular interface, rather than it being an instance of any particular class.
For example, suppose you are writing an application to purchase goods for a business. Your program will need to be informed of such entities as vendors, freight companies, receiving locations, and billing locations. One thing these have in common is that they all have a street address. These street addresses will appear in different parts of the user interface. You will want to have a class for displaying and editing street addresses so that you can reuse it wherever there is an address in the user interface. We will call that class AddressPanel.
You want AddressPanel objects to be able to get and set address information in a separate data object. This raises the question of what instances of the AddressPanel class can assume about the class of the data objects that they will use. Clearly, you will use different classes to represent vendors, freight companies and the like. If you program in a language that supports multiple inheritance, like C++, you can arrange for the data objects that instances of AddressPanel use to inherit from an address class in addition to the other classes they inherit from. If you program in a language like Java that uses a single inheritance object model, then you must explore other solutions.
You can solve the problem by creating an address interface. Instances of the AddressPanel class would then simply require data objects that implement the address interface. They would then be able to call the accessor methods of that object to get and set its address information. Using the indirection that the interface provides, instances of the AddressPanel class are able to call the methods of the data object without having to be aware of what class it belongs to. Here is a class diagram showing these relationships:
Figure 1: Indirection through address interface.