<!-- Main HTML starts here -->
Design Patterns are intended to provide solutions to recurring design problems. Design Patterns play a major role in the design of complex systems using Object Oriented methods. Patterns help designers to decompose the system into set of co-operating objects instead of decomposing objects and trying to find relationships between them. In fact, most of us are reusing class relationships and object collaborations in our design without even realizing that we are actually using Design Patterns. Even though Design Patterns are available for a long time, the credit goes to Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides (Gang of Four -GoF) for coming out with a good collection of Patterns for common Design Problems. Their book, Design Patterns: Elements of Reusable Object-Oriented Software by Erich Gamma et al. (Addison-Wesley, 1995) was one of the first and best works done on Patterns.
In this article, we will be seeing what a Design Pattern is, followed by GoF's classification of Patterns and then jumping directly into the main topic of the article, MFC and Design Patterns. Portions of this article are extracted directly from GoF's book and throughout this article, I will be using the terms from their book.
As mentioned earlier, the goal of Design Patterns is to provide solutions for recurring design problems. Design Patterns are meant to provide a common vocabulary for communicating design principles. They help designers to share their design using a common language. For example, you can tell your friend who knows pattern vocabulary that you have used Bridge Pattern in your design without explaining the details of class relationships.
So, how it all started? When Christopher Alexander and his colleagues tried to explain the architecture of buildings and cities, they used a Pattern Language. According to Christopher Alexander, "Each pattern describes a problem which occurs over and over again in our environment , and then describes the core of the solution to that problem, in such a way that you can use this solution a million times over, without ever doing it the same way twice". This principle is not only applicable to the construction of building and cities, but it can also be extended to software construction using Object Oriented Design. When patterns are applied to software design, they take the name of Design Patterns. To summarize, Design Patterns provide proven solutions to recurring design problems.
GoF's Classification of Design Patterns
GoF classifies Design Patterns based on two criteria. The first criterion is based on the purpose (Creational, Structural and Behavioral) and the second one is based on the scope (Class or Object). The table given below (taken from the book) shows the Design Pattern Space.
Chain of Responsibility
Creational Patterns talk about Object creation, Structural Patterns deal with Object and Class composition while the Behavioral Patterns are concerned with Object interaction and distribution of responsibilities. Patterns characterized under class scope deals with Static Class relationships, whereas Object Patterns are all about Dynamic Object interactions
MFC and Design Patterns
As we all know, MFC is one of the popular class libraries used by C++ programmers. Nowadays, more and more commercial and business applications are developed using MFC. In fact, MFC and Visual C++ are the backbone for most of the recent Microsoft Products including Visual C++. The success story behind MFC is its class architecture and design principles adopted by the developers of MFC, which makes it one of the popularly reused library.
This main topic of this article is to show how patterns are used in MFC. We will be seeing the usage of three patterns in MFC library.
Creational : Singleton Pattern
First step in any MFC application is the creation of application object (object of class derived from
CWinApp). There should be only one application object in an instance of MFC application.
CWinApp is designed to make sure that only application object is present in a given instance.
CWinApp and its descendants are called Singleton Classes. A class (
CWinApp or its descendant) that assures a maximum of ONE object of its type at a given time and provides a global access point (
AfxGetApp() method) to this object is a Singleton class.
As this principle is applied over and over again to solve recurring object "creational" problems, this becomes a pattern. Singleton Pattern ensures that a class only has one instance and provides a global access point it. The article Creating Singleton Objects using Visual C++ talks about different approaches for implementing Singletons.
Structural : Bridge Pattern
Bridge Pattern is all about decoupling an abstraction (interface) from its implementation so that the two can vary independently. In MFC, the process of storing/retrieving an object to/from a persistence mechanism (like a file) is called Serialization. MFC uses the Bridge Pattern to implement Serialization.
CFile classes implement object Serialization. CArchive class provides the interface for writing/reading an object to/from a persistence mechanism whereas the
CFile and its sub classes provides implementation for different persistence mechanisms such as memory, disk file, sockets etc.
CArchive object is configured with an object of class
CFile (or a derived class) during its construction, from which it obtains the necessary information for serialization, including the filename and type of the requested operation (a read or write). Client performing the Serialization operation can use CArchive object without regarding the persistence mechanism implemented by
The article Bridge Pattern - Bridging the gap between Interface and Implementation talks about Bridge pattern in detail.
Behavioral : Observer Pattern
The Observer Pattern is intended to "Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically". An object that is subjected to change is called a Subject and an object that depends on the Subject's state is called an Observer.
MFC uses a Document/View variant of the Observer Pattern. MFC's famous Document/View architecture uses this variant. A document contains the data object and acts as a Subject. A view is a window object through which the user updates the document and it acts as an Observer. A document can have multiple views. Whenever the data in the document is changed by one of the views, it updates the document by calling
UpdateAllViews method, with optional hint about the modification. To inform about the change to other views, the document object calls
OnUpdate method for each view attached to it (except the view that called
UpdateAllViews). Derived view classes can override the OnUpdate method and update themselves by querying the data from the document.
The article Applying Observer Pattern in C++ Applications talks about Observer pattern in detail.
Design Pattern provides a common language for designers and helps them to decompose systems into a set of cooperating classes and objects. They provide proven design solution to recurring problems. In this article, I have introduced the design pattern and how MFC is using some of the patterns in its design. We can easily find more and more patterns when we dig into MFC and its classes.