SENG 443 - Software Architectures

Observer and Facade Design Pattern

 

David Fox
Michael M. Hanna

Department of Computer Science
University of Calgary
2500 University Drive N.W.
Calgary, Alberta, Canada
T2N 1N4


David's Email: foxbd@cpsc.ucalgary.ca
Michael's Email: hannam@cpsc.ucalgary.ca

g

Table of Contents

Facade Design Pattern

Observer Design Pattern

>>Printable Version

>>References

Abstract

A design pattern is a “solution to a problem in context”, that is, it represents a high-quality solution to a recurring problem in design. (CISE, 2005)

As the chair of software engineering for the Swiss Federal Institute of Technology Zurich, Bertrand Meyer has strong beliefs about the reuse of code. In fact he states that code “reuse is the best hope for major strides in software technology". (Meyer, n.d.) One way to generate code reuse is by employing the use of design patterns.

The purpose of this paper is to demonstrate the use of the Observer and Façade design patterns from both a use and reuse perspective. We will discuss the topics of motivation, applicability, structure, an implementation example, analysis, critical evaluation, known uses and finally, related patterns.

 

Facade Design Pattern
Introduction

The Facade design pattern is a fairly trivial design pattern. In the realm of design patterns there are three major categories. A design pattern can belong to the creational, structural, or behavioral category exclusively. Discussion of creational patterns is outside the scope of this document. Please note that the idea of behavioral design patterns will be discussed later in the document, when the Observer design pattern is covered.

The Facade design pattern is a structural pattern. A structural pattern is "concerned with how classes and objects are composed to form larger structures. Structural class patterns use inheritance to compose interfaces or implementations". (Gamma, Helm, Johnson, and Vlissides, 2004)

Facade allows a designer to "provide a unified interface to a set of interfaces in a subsystem. Facade defines a higher-level interface that makes the subsystem easier to use". (Gamma, Helm, Johnson, and Vlissides, 2004)

>>Table of Contents

Motivation

During the development of an application, the designer will tend to decompose the system into subsystems in the hope to reduce complexity and at the same time, increase reusability and modifiability. Under such circumstances the goal is to minimize the dependencies and communication between subsystems. A facade object can be used to deal with this issue by providing a single interface to some of the more general facilities of a subsystem. (Gamma, Helm, Johnson, and Vlissides, 2004)

Most design patterns are usually associated with a classic, often used example. For our example we will use the Facade design pattern in conjunction with a compiler. A compiler subsystem may be made up of many classes such as scanner, parser, symbol, error messager, code optimizer, code generator, and a peephole optimizer class. The user of the system may not be concerned with parsing and such operations and may just want to compile their existing code. Being forced to use these other subsystem classes will only increase the amount of work and difficulty the user is faced with.

A solution to this problem is to provide a higher-level interface that can direct a user to use what is only necessary and not bother them with procedures and details that will only complicate the process. The class that will act as the higher-level interface will define a unified interface to the compilers functionality. (Gamma, Helm, Johnson, and Vlissides, 2004)

>>Table of Contents

Applicability

Before we discuss real-world applications of the Facade design pattern, we will present an example in the form of an analogy. We will use the example of a customer representative acting as a facade to customers. When a customer calls to order an item from a catalog, the customer will call the appropriate phone number to make an order. The customer is answered by a customer service representative. This representative acts as a facade, by providing an interface to the order fulfillment department, the billing department, and the shipping department. (Duell, 1997)


Figure 1 - Facade Design Pattern Analogy (Duell, 1997)

The Facade pattern can be found useful in the following situations: (Gamma, Helm, Johnson, and Vlissides, 2004)

>>Table of Contents

Structure

This section of the report will present a UML class diagram of the Facade design pattern, describe each of its participants, and present a collaboration diagram.

Class Diagram(Gamma, Helm, Johnson, and Vlissides, 2004)


Figure 2 -UML Facade Class Diagram (Gamma, Helm, Johnson, and Vlissides, 2004)

Participants (Gamma, Helm, Johnson, and Vlissides, 2004)

Participant
Description
Facade
  • Knows which subsystem classes are responsible for a request.
  • Delegates client requests to appropriate subsystem objects.
Subsystem Classes
  • Implement subsystem functionality.
  • Handle work assigned by the Facade object.
  • Have no knowledge of the facade; that is, they keep no references to it.

Table 1 -Participants and Description of Facade Participants (Gamma, Helm, Johnson, and Vlissides, 2004)

Collaboration (Gamma, Helm, Johnson, and Vlissides, 2004)

For this design pattern we will not present a collaboration diagram. Instead we will discuss the steps involved when a facade is being used. The following events occurs:

  1. A user/client will use the system and any of its corresponding subsystem functionality by sending a request to Facade. The Facade will redirect the request to the appropriate subsystem(s) objects.
  2. Users/clients that use the Facade will not deal with the requested subsystem object directly.

>>Table of Contents

Implementation

The following example is written using the Java programming language.

Problem Description

The implementation example presented here is tightly associated with the coding example presented in the Observer pattern. We are just going to implement a very simple Facade that interacts with our Observer design pattern.

Class Diagram

The following UML class diagram describes our system example with the addition of the Facade.


Figure 3 - Facade and Observer UML Class Diagram Code Example Diagram

Source Code

Client
The Client class provides the means for the user to interact with the system by means of the main() method and creating an instance of the Façade object, which will be discussed next.

 

Facade
The Façade class is used to reduce the complexity of running the system by a user. If the client wants to run the system the Façade class deals with the complexity of instantiating objects, populating lists and performing various other tasks associated with the system by calling the runDemo() method. In this way the client does not have to deal with the complex task of system initialization.

>>Table of Contents

Analysis

In this section, the advantages and disadvantages of using the Facade design pattern will be discussed.

Advantages (Gamma, Helm, Johnson, and Vlissides, 2004)

  1. Reduced Client-Subsystem Interaction
    As mentioned above the Facade allows a user/client to only worry themselves with completing the job they require be done, rather than worrying about unneccessary functionality being invoked. The result of this is an easy-to-use system.
  2. Loose Client-Subsystem Coupling
    In most cases the components of a subsystem are strongly coupled. The use of a Facade promotes loose coupling between these components and as a result allows for the varying of subsystem components without affecting its clients.
  3. Layer Promotion
    The use of Facade is a great promoter of layered systems. As mentioned in point 2: Loose Client-Subsystem Coupling, we can reduce the dependencies between objects. With this reduction, complex or cyclic dependencies can be filtered out.
  4. Reduced Compilation Time
    In the development of large application systems, it is a priority to reduce compilation dependencies. In other words, if a subsystem has been modified, it is very important to minimize the time spent recompiling other classes.
  5. Ease of Use Versus Generality
    The Facade does not completely prevent applications from using subsystem classes when necessary. This fact allows the developer(s) to choose between ease of use and generality.

Disadvantages (Gamma, Helm, Johnson, and Vlissides, 2004)

  1. Lack of Function, Modifiability and Reusability
    The Facade does not add any functionality to the system. Its only purpose is to provide an interface for the user/client. When any changes are made to the subsystems the Facade must also be changed to reflect the modifications of the subsystems.

>>Table of Contents

Critical Evaluation

The Facade pattern is a fairly trivial pattern. It is quiet simple to grasp the idea and to implement the design pattern. The simplicity of the pattern should not cloud the fact of its usefullness. The mere fact that complexity reduction is an important facet lends itself to be a potentially valuable and efficient design pattern.

This pattern provides benefits to both the developer/designer and the user/client of the system. The designer can decide to lean more towards ease of use over generality if justified. There is also a notable decrease in compilation time of very large and complex subsystems. This is achieved because of the loose client-subsystem coupling and the layering of a system. If any modifications are made to a layer, none of the other layers need to be changed as a result. For the user/client, they do not have to worry themselves with unneccessary functionality of a system invoked when all they require is a simple operation be completed. The result of this is an easy-to-use system.

The Facade design pattern is very powerful for its purposed design solution. There are not many disadvantages associated with the Facade except for the lack of modifiability and reusability. The Facade does not add any functionality to the system. It provides a very easy-to-use interface, but when any changes are made to any of the subsystems, the Facade must be changed to reflect these changes.

>>Table of Contents

Implementation Issues (Gamma, Helm, Johnson, and Vlissides, 2004)
  1. Reducing client-subsystem coupling.
    It is possible to reduce the coupling between users/clients and subsystems even further. The process of reducing coupling involves making Facade an abstract class with concrete subclasses for different implementations of a subsystem. Another approach is to configure a Facade object with different subsystem objects. If the Facade object requires any customization, the only step that must be completed is to replace one or more of its subsystem objects.
  2. Public versus private subsystem classes.
    A subsystem is the same as a class in that both have interfaces and both encapsulate something. More specifically a class encapsulates state and operations, and on the other end, a subsystem encapsulates classes. Since we can think of public and private interfaces of a class, we can think of the public and private interfaces of a subsystem.

Clients can access all of the classes within the public interface to a subsystem. The Facade class is part of the public interface, but there exists other parts.

>>Table of Contents

Known Uses (Gamma, Helm, Johnson, and Vlissides, 2004)

Some of the more notable uses of the Facade design pattern are:

  1. The ET++ application framework allows for an application to possess built-in browsing tools for inspecting objects at run-time. These tools are implemented in a seperate subsystem with the addition of a Facade class called "ProgrammingEnvironment".
  2. The Choices operating system makes use of facades to compose many frameworks into just a single framework.
  3. The Java Messaging Service (JMS) API allows for the connection of Java programs to enterprise messaging middleware. The Facade design pattern is used to hide the details and complexities of the lower-level software services, making it easier to use. (Bruno, 2003)

>>Table of Contents

Related Patterns (Gamma, Helm, Johnson, and Vlissides, 2004)

Patterns that relate to the Facade design pattern and how they are related are as follows:

  1. Abtract Factory
    The Abstract Factory design pattern can be used with the Facade design pattern to create subsystem objects in a subsystem-independent way. It is also possible to replace a Facade with an Abstract Factory to perform the same task.
  2. Mediator
    The Facade and Mediator are very closely related except the Mediator abstracts arbitrary communication between colleague objects, while the Facade abstracts functionality of existing classes.

>>Table of Contents

Conclusion

The Facade pattern was very easy to learn and implement, as can be seen from our code segments. The Facade design pattern provides a useful vehicle for reducing complexity while at the same time increasing user usability. This is achieved because the Facade pattern acts as an interface between the client and a more complex system. Thus reducing complexity.

>>Table of Contents

Observer Design Pattern
Introduction

Although the name Observer is used, this name can be exchanged interchangeably with Dependents, Listener, or even Publish-Subscribe. Throughout this document we will use the name of Observer.

The Observer design pattern is a behavioral pattern. A behavioral pattern is one that is “concerned with the assignment of responsibilities between objects or encapsulating behavior in an object and delegating requests to it”. (Huston, n.d.)

Observer allows a designer to “define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically”

>>Table of Contents

Motivation

One of the most important concepts/principles of designing an object-oriented application is the proper distribution of responsibility throughout the application. “Each object in the system should focus on a discrete abstraction within the problem domain and nothing more”. (Richter, 2002) In other words, an object should only be allowed to perform a single task and to perform it well. (Richter, 2002)

When a designer decides to divide a system into groups of cooperating classes, the designer must not overlook the issue of ensuring that consistency is maintained between the related objects. Tightly coupling classes, to maintain consistency must be avoided at all costs. Tightly coupling classes will reduce reusability. (Gamma, Helm, Johnson, and Vlissides, 2004)

For the sake of argument, let us assume that we have a setup that will not use the Observer design pattern. The scenario at hand is that there exists three personal digital assistants (PDA’s) and two notebook computers. In our first example, we will assume that each and every object knows about each and every other object. When a contact list within one of these devices has been changed, it will notify all of the remaining devices that a change has occurred and provide them with the changed data. From the diagram below, we can see that with the current setup there is a large number of relationships and a very tight coupled system is a result. This is a very poor design.


Figure 4 - Relationships in Poorly Designed and Tightly Coupled System

In our next example we will also have three personal digital assistants and two notebook computers. This time we will use the Observer design pattern. Please keep in mind that this is just a demonstration and the actual inner workings of the Observer pattern will be discussed shortly. For this example we will have something called a Dock, which will represent the subject. The remaining devices will make up the observers. In the diagram below, we can easily see that there are far less relationships and a very loosely coupled system.


Figure 5 - Relationships in Observer Designed System

>>Table of Contents

Applicability

Before we discuss real-world applications of the Observer design pattern, we will present an example in the form of an analogy. Lets look at the example of an auctioneer who starts the bidding, and we have a group of buyers (observers). The buyers will make a bid by raising their paddle and the bid will be accepted. At this point the bid price is changed, which is then broadcast to all of the bidders in the form of a new bid. (Duell, 1997)


Figure 6 -Observer Design Pattern Analogy (Duell, 1997)

The Observer pattern can be found useful in the following situations: (Gamma, Helm, Johnson, and Vlissides, 2004)

We will now look at one of the more classic examples of the use of the Observer design pattern; the spreadsheet example. From the diagram we see that we have a table, bar graph, and pie graph view. These views will represent the observers. None of these views have any knowledge of the other. When a user decides to make a change to the table, the bar and pie graphs change immediately. This gives the impression that all three views know what the other is doing, but this is not the case.


Figure 7 -Spreadsheet Example (Gamma, Helm, Johnson, and Vlissides, 2004)

>>Table of Contents

Structure

This section of the report will present a UML class diagram of the Observer design pattern, describe each of its participants, and present a collaboration diagram.

Class Diagram(Gamma, Helm, Johnson, and Vlissides, 2004)


Figure 8 -UML Observer Class Diagram (Gamma, Helm, Johnson, and Vlissides, 2004)

Participants (Gamma, Helm, Johnson, and Vlissides, 2004)

Participant
Description
Subject
  • Knows its observers.
  • Any number of Observer objects may observe a subject.
Observer
  • Defines an updating interface for objects that should be notified of changes in a subject.
ConcreteSubject
  • Stores state of interest to ConcreteObserver objects.
  • Sends a notification to its observers when its state changes.
ConcreteObserver
  • Maintains a reference to a ConcreteSubject object.
  • Stores state that should stay consistent with the subject's.
  • Implements the Observer updating interface to keep its state consistent with the subject's.
Table 2 -Participants and Description of Observer Participants (Gamma, Helm, Johnson, and Vlissides, 2004)

Collaboration (Gamma, Helm, Johnson, and Vlissides, 2004)

From the diagram below we can see the following events occur:

  1. If a change occurs that results in the states of the ConcreteSubject and any of its observers being different, the ConcreteSubject will notify its corresponding observers of this.
  2. Once the ConcreteSubject has notified its corresponding observers of a change, a ConcreteObserver may query the subject for information. This is related to the Push and Pull models, which will be discussed later. The information retrieved is used to ensure that all the observers are consistent.


Figure 9 -Collaboration Diagram of Observer Participants(Gamma, Helm, Johnson, and Vlissides, 2004)

>>Table of Contents

Implementation

The following example is written using the Java programming language.

Problem Description

As mentioned before, the Facade implementation example is closely related to this example. For this problem we will assume that we own a custom computer distribution company, named ZeroFit. At ZeroFit there is a large client contact list, consisting of all the companies and/or individuals that our custom computers are distributed to. The idea is that all employees of ZeroFit must have the same and the latest updated contact list. Employees can be assigned a laptop and/or personal digital assistant. Employees can add new clients and remove clients that no longer require the services of ZeroFit. We must ensure that each and every employee and their corresponding devices contain the same contact list.

Strategy

From the above hypothetical example, we can see that the following functionality must be provided by the system:

  1. The system should automatically notify all devices of any changes to the company distribution contact list.
  2. The system should be capable of adding and removing devices with minimal modifications to the existing system.

Class Diagram

The following UML class diagram describes our system example.


Figure 10 -Observer UML Class Diagram Code Example Diagram

Source Code

SubjectInterface
The SubjectInterface is used to maintain the observers in the system by providing the interface to attach and detach observer objects. The interface also supplies a notify( ) method to notify all the observers in the system that are attached to SubjectInterface when a change has occurred.

 

Observer
The Observer interface provides the observers with an update( ) method. The update( ) method uses the ConcreteSubject, which in this case is the ContactsInformationDock class, to update the states of all the other PDAs in the system.

 

ConcreteSubject
This is the object that is being observed. Once there is a change in the state of an observer, in this case, a PDA, this ConcreteSubject which is the ContactsInformationDock class will notify the observers with the change in state for each observer that is different than the updated one.

 

ConcreteObserver
These are the actual observer objects that are observing any change in state in the ContactsInformationDock system. These observers are, in this case, the PDAs that are observing the ContactsInformationDock object for changes.

>>Table of Contents

Analysis

In this section, the advantages and disadvantages of using the Observer design pattern will be discussed.

Advantages (Gamma, Helm, Johnson, and Vlissides, 2004)

  1. Loose Coupling
    There is a minimal level of coupling between subjects and observers. The reason for this is because the subject only knows that it has a list of observers. It is very important to note that the subject does not know any of the concrete observers.

    The fact that the observers and subjects are loosely coupled, gives a designer the ability to place subjects and observers in different layers. A benefit that can clearly be seen from such a setup is that if any changes need to be made to a layer, the changes can be made to only that layer without modifying any of the other layers.
  2. Broadcast Communication
    The use of this pattern does not require that a subject define its recipients. Rather, the subject takes advantage of broadcast communication and sends out a notification to all subscribed observers. The subject does not need to know how many observers exist. It only has one responsibility. It is to make sure that all observers are notified. The benefit of such a setup is that observers can be added and removed at any time.

Disdvantages (Gamma, Helm, Johnson, and Vlissides, 2004)

  1. Unexpected Updates
    Since none of the observers have any knowledge of each other, a simple/basic update to an observer may cause a chain reaction of many updates to other observers and their dependent objects.
  2. Expensive Updates
    If a decent protocol does not exist, to help the observer(s) determine the changes that occurred, the observers will spend a great deal of resources (time and processor) determining what exactly did change.
  3. Difficulty Debugging and Testing
    With the use of the Observer pattern we benefit from the decreased coupling between objects. The downfall with this is that it may become very difficult to understand the dependencies between objects by just viewing source code.

>>Table of Contents

Critical Evaluation

As was mentioned earlier a design pattern is a “solution to a problem in context”, that is, it represents a high-quality solution to a recurring problem in design. For the Observer design pattern it provides a quality solution for defining a one-to-many dependency between objects, such that when one object possesses a different state, all of its dependents are notified and changed appropriately automatically. (Gamma, Helm, Johnson, and Vlissides, 2004)

A major benefit of the Observer pattern is the decreased level of coupling that occurs between observers and observers and between subjects and observers. Observers are decoupled from each other because the subject contains a list of its corresponding observers, whether it be using an array list, hash table, or even a linked list, which is attributed to the decoupling of the observers.

The subject and observers experience a decreased level of coupling because the subject does not need to know anything about the individual observers. All the subject is concerned with, is the observers location, which is stored in a “table” as discussed above. Since the observers and subjects are decoupled from each other, a developer has the freedom to create a layered system. These individual layers can be operated, modified, and/or removed without affecting any of the other layers in the system. This promotes modifiability, reusability, and scalability. The layering of the system is beneficial for “maintenance and enhancement” because it easy to “define, modify, and extend subjects independently of observers and vice versa”. ( Vlissides, 1996, The Problem and The Standard Solution)

With the use of the Observer design pattern, communication between subjects and observers is via broadcast communication. When an observer is modified or changed it will send an update message to the subject, which changes the state of the subject. In turn, the subject will notify all registered observers that a change has occurred. The designer can choose between push and pull models that determine the degree of detail of information passed on to the observers from the subject with regards to the notification. If a push model is used the subject will provide greater detail about the change that has occurred. If a pull model is used the subject will provide minimal detail of the change and it is the observers responsibility to determine what changes have been made by querying the subject again.

The Observer design pattern is simple and straightforward to implement. (Kulathu Sarma, 2001, Advantages)

Although the Observer design pattern provides many benefits, it can incur many drawbacks. With the decoupling of the observers with each other, a simple update to an observer may cause a long chain reaction of many updates to other observers and their dependent objects.

From above we mentioned push and pull models. Depending on which model is used, major drawbacks may occur as a result. If a push model is implemented the subject will provide its observers with a great deal of information regarding the change. If there is an extremely large number of observers, this action will be very expensive in terms of resources and time. The pull model, on the other hand, can also incur large resource usage when many observers exist and all of them must query the subject regarding the changes that have occurred.

Although the Observer design pattern is considered simple to implement, it may become very difficult to debug and test. The decreased coupling between objects makes it very difficult to understand the program by viewing the source code alone.

>>Table of Contents

Implementation Issues (Gamma, Helm, Johnson, and Vlissides, 2004)

Contained in this section is a list of implementation issues associated with the Observer design pattern.

  1. Mapping subjects to their observers.
    As we know, the subjects must have the ability to notify observers in the case of an update performed to an observer. With this requirement in mind, the subject must have a way of knowing which observers it must send a notify message to. The easiest approach is to store the observers within the subject, but it has the disadvantage of costing too much in terms of space, when there is a combination of many observers to very few subjects.
  2. Observing more than one subject.
    It may be possible for an observer to belong to more than one subject. Under these circumstances the subject should pass a reference of itself as a parameter in the update operation, which gives the observer the ability to determine which subject it received the notification from.
  3. Who triggers the update?
    As discussed earlier subjects and observers use the notify method to maintain consistency between all observers. There are two options on which object actually calls notify.
    1. Possess the ability of changing the state of the subject, and then have the subject call notify when its state has been changed.
    2. Have the actual observer call notify at the appropriate time.
  4. Dangling references to deleted subjects.
    When a subject is being deleted, the subject must notify its corresponding observers, so that the observers can reset their references.
  5. Make sure subject state is self-consistent before notification
    Observers will query the Subject for its current state, so that they may update their own state as appropriate. The main concern is to make sure the notify( ) method is called after the Subjects state is self-consistent.
  6. Avoiding observer-specific update protocols: the push and pull models.
    There are two different models associated with additional information being broadcast by the Subject to its corresponding Observers. The two models differentiate in the amount of information being sent. They are as follows:
    1. Push model: The subject provides detailed information about the change made, and whether or not the Observers want the update. This model is based on the assumption that the Subject knows something about the Observers needs.
    2. Pull model: The Subject only provides the Observer with the very minimum amount of information. The Observer may retain details at a later time. With regards to this model, the Subject knows very little, if anything about the Observers.
  7. Specifiy modifications of interest explicitly.
    One way that update efficiency can be greatly improved is by enforcing Subject registration. What happens here is that the subject’s registration interface is extended to allow Observers to register for specific events. When an event occurs, the Subject will only notify the Observers that have an interest with that event.
  8. Encapsulate complex update semantics.
    An object known as a ChangeManager can be used to maintain complex relationships between subjects and observers and encapsulate complex updates to observers.

>>Table of Contents

Known Uses (Gamma, Helm, Johnson, and Vlissides, 2004)

Some of the more notable uses of the Observer design pattern are:

  1. The most well known example of the Observer pattern is Smalltalk’s Model-View-Controller model (MVC). The subject is the model and the observers are the view.
  2. "Smalltalk, ET++, and the THINK class library provide a general dependency mechanism by putting Subject and Observer interfaces in the parent class for all other classes in the system".
  3. Other user interface toolkits that make use of the Observer pattern are InterViews, Andrew Toolkit, and Unidraw.

>>Table of Contents

Related Patterns (Gamma, Helm, Johnson, and Vlissides, 2004)

As we will see shortly the Observer pattern is related to other design patterns. The common link between the Observer pattern and its related patterns are by the ChangeManager, which was discussed earlier. The related design patterns are as follows:

  1. Mediator
    The ChangeManager that was mentioned earlier acts as a mediator. It maintains the relationships between subjects and observers.
  2. Singleton
    The ChangeManager will be made unique and globally known.

>>Table of Contents

Conclusion

In conclusion the Observer design pattern is a high quality solution to solving problems that involve one-to-many dependencies. The Observer design pattern is not a difficult pattern to implement. Although resource usage may be an issue when the number of observers significantly increases the benefits of this pattern far outweigh the liabilities.

When used correctly, and with the appropriate protocols, the Observer design pattern is the right choice in solving one-to-many dependencies.

>>Table of Contents

References

>>Table of Contents

June 15, 2005