Read the Overview before proceeding with this section!
I recently read something to the effect that mastering the use of a set of patterns is the ultimate goal of someone intending to seriously study design patterns. That said, here we go...
There are 3 examples in this tutorial. They are progressively more complex. Here's the first one, Singleton, rather simple.
The singleton pattern applies to the many situations in which there needs to be a single instance of a class, a single object. It is often left up to the programmer to insure that the An important consideration in implementing this pattern is how to make this single instance easily accessible by many other objects.
Classes
There is actually only one class that needs to be written specially to implement the Singleton pattern. A second client class will always be involved take make requests from the singleton.
Here is what a Booch [Booch94] class cloud might look like:
Advantages
What are the advantages to using this pattern?
Single instance is controlled absolutely. When implemented as the pattern recommends, the class will have direct control over how many instances can be created. This is in contrast to making the programmer responsible for insuring that there is only one instance.
This pattern is easily extensible to allow a controlled number of
"singleton" objects to be created. The most important modification
needed to accomplish this change is in the operator that
has control over access to the instances. In this case, the
Instance() function would need to be changed.
Examples
Here is how a generic singleton might be written in C++. If you want to
try it, here is the source code:
singleton_ex.tar
class Singleton {
public:
static Singleton* Instance(); // gives back a real object!
static proof(void); // proof that the object was made
protected:
Singleton(); // constructor
private:
static Singleton* _singleton;
};
And the implementation like:
Singleton* Singleton::_singleton = 0;
Singleton* Singleton::Instance()
{
if (_singleton == 0)
{
_singleton = new Singleton;
} // end if
return _singleton;
} // end Instance()
What about sub-classing? How can we make the implementation more flexible? Possibly for reuse, or maybe for using multiple singletons in a single program. So what really happens if you try to explicitly declare a Singleton object?
The facade pattern can make the task of accessing a large number of modules much simpler by providing an additional interface layer. When designing good programs, programmers usually attempt to avoid excess coupling between module/classes. Using this pattern helps to simplify much of the interfacing that makes large amounts of coupling complex to use and difficult to understand. In a nutshell, this is accomplished by creating a small collection of classes that have a single class that is used to access them, the facade.
ClassesThere can be any number of classes involved in this "facaded" system, but I would think that the minimum is four classes. One client, the facade, and the classes underneath the facade. In a typical situation, the facade would have a limited amount of actual code, making calls to lower layers most of the time.
Advantages/Disadvantages
As stated before, the primary advantage to using the facade is the make the interfacing between many modules or classes more managable. One possible disadvantage to this pattern is that you may lose some functionality contained in the lower level of classes, but this depends on how the facade was designed.
Examples
Imagine that you need to write some program that needs to represent a building as rooms that can be manipulated. Manipulated as in interacting with objects in the room to change their state. The client that has ordered this program has determined that there will only be a need for a finite number of objects possible in each room, and a finite number of operations that can be performed on each of them.
You, as the program architect, have decided that the facade pattern will be an excelent way to keep the amount of interfacing low, considering the number of possible objects in each room, and the actions that the client has specified.
A sample action for a room is to "prepare it for a presentation". You have decided that this will be part of your facade interface since it deals with a large number of classes, but does not really need to bother the programmer with interacting with each of them when a room needs to be prepared. Here is how that facade might be organised.
Consider the sheer simplicity from the client's side of the problem. A less thought out design may have looked like this, making lots of interaction by the client necessary.
Food for thought...
The compilers that we use everyday to process the computer code that we have written is a prime example of the facade pattern in action. What other examples are there that you can think of?
Forward to system requirements.