|
Introduction |
Since the invention of Object Oriented Programming, its philosophy has become exceedingly
popular among the programming community and has had a wide spread acceptance in
the technology world. Although OOP has become largely popular, it has spawned
some repeated design problems with its continuous use. There was a need for
rectifying these recurring problems in software designs. The need of the hour
was a solution for these common problems. The use of design patterns has been
a significant improvement in Object Oriented Design (OOD) and facilitates the design
and development of high quality, maintainable software at a much faster rate and
at a lower cost. Design Patterns are the proven and best solution to the common
problems and increasing complexities involved in software development life cycles.
One of the most important factors that determine the efficiency of a software
design is its adaptability to change. My intent in authoring this article
is to provide the readers an overview of Design Patterns, their applicability and
the common pitfalls of improper usage or application of these design patterns in
software designs.
|
|
Prerequisites |
The reader should have a good background in the concepts of Object Oriented Programming
and any one of the object oriented languages (C++, Java, C#, etc) for understanding
the concepts covered in this article. A prior knowledge of Unified Modeling
Language (UML) is an added advantage though it is not mandatory.
|
|
What are Design Patterns? |
A Design Pattern essentially consists of a problem in a software design and a solution
to the same. In Design Patterns each pattern is described with its name, the
motivation behind the pattern and its applicability. Understanding the applicability
of a design pattern is of utmost importance prior to implementing it.
According to MSDN, "A design pattern is a description of a set of interacting
classes that provide a framework for a solution to a generalized problem in a specific
context or environment. In other words, a pattern suggests a solution to a particular
problem or issue in object-oriented software development. Additionally, patterns
take into account design constraints and other factors that limit their applicability
to the solution in general. Together, the classes, the communication and interconnections
among those classes, and the contextual specifics define a pattern that provides
a solution to any problem in object-oriented software design that presents characteristics
and requirements matching those addressed by the pattern context."
"A design pattern systematically names, motivates, and explains a general design
that addresses a recurring design problem in object-oriented systems. It describes
the problem, the solution, when to apply the solution, and its consequences. It
also gives implementation hints and examples. The solution is a general arrangement
of objects and classes that solve the problem. The solution is customized and implemented
to solve the problem in a particular context". -- Design Patterns: Elements
of Reusable Object-Oriented Software by
Erich Gamma.,
Richard Helm,
Ralph Johnson,
and John Vlissides
|
|
Benefits of Design Patterns |
The following are some of the major advantages of using Design Patterns in software
development.
·
Flexibility
·
Adaptability to change
·
Reusability
|
|
When to use Design Patterns |
Design Patterns are particularly useful in one of the following scenarios.
·
When the software application would change in due course of time.
·
When the application contains source code that involves object creation and
event notification.
|
|
When not to use Design Patterns |
This section discusses the main points that can be used to evaluate whether or not
to use design patterns to solve a problem context. Do not use design patterns
in any of the following situations.
·
When the software being designed would not change with time.
·
When the requirements of the source code of the application are unique.
If any of the above applies in the current software design, there is no need to
apply design patterns in the current design and increase unnecessary complexity
in the design. The common pitfalls that are observed or rather encountered
in a design when applying design patterns to solve a problem that does not need
it is discussed later in this article.
|
|
The Gang of Four (GOF) Patterns |
The invention of the design patterns that we commonly use today can be attributed
to the following four persons: Erich Gamma, Richard Helm, Ralph Johnson and John
Vlissides. These men invented 23 patterns in all that are commonly known as the
Gang of Four patterns or the GOF patterns. These patterns are named based
on their intent and purpose and are classified in three broad categories stated
below.
·
Creational
·
Structural
·
Behavioral
Each of these groups in turn contains related sub patterns. These patterns
are discussed in the sections that follow. The sub patterns under the major
three groups discussed above and their brief explanation are provided for better
understanding.
|
|
Creational Patterns |
The Creational Patterns deals with the best possible way of creating an object or
an instance of a class. They simplify object creation and provide a flexible
approach towards object creation. The following are the sub-patterns that
fall under this group.
·
Abstract Factory
·
Factory
·
Builder
·
Prototype
·
Singleton
Both the Abstract Factory and the Factory pattern have the same intent. They
have the same names and do the same thing. It is only the way that they operate
that is important. Both the Abstract Factory and the Factory pattern deal
with the creation of an object. The difference being that the Abstract Factory
pattern uses objects to manage object creation while the Factory pattern does the
same using inheritance. The Abstract Factory pattern provides an interface
for creation of a family of related objects, but without specifying their concrete
classes. The Factory pattern also provides an interface for the creation of
objects, but allows the inherited classes to decide on the appropriate time of these
instantiations.
The Builder Pattern is one that isolates the construction of a complex object from
its representation, thus ensuring that several different representations can be
created depending on the requirements. The Prototype Pattern allows an initialized
and instantiated class to be copied or cloned to create new instances rather than
creating new instances. The Singleton Pattern indicates that there can be
only one instance of a class throughout the Application’s life cycle. A
singleton class is one that can be instantiated only once in the application domain
and provides a global point of access to it.
|
|
Structural Patterns |
Structural Patterns provides the flexibility to specify how objects and classes
can interoperate. The following are the sub patterns that comprise the Structural
Patterns group.
·
Adapter
·
Facade
·
Bridge
·
Composite
·
Decorator
·
Flyweight
·
Proxy
·
Adapter
·
Bridge
·
Composite
·
Decorator
·
Flyweight
·
Proxy
The Adapter Pattern allows different classes to inter-operate even with incompatible
interfaces. The Facade Pattern depicts a single class that represents a high level
class in an entire subsystem and makes the subsystem easier to use. As an
example, a Façade design pattern ensures that we can have a class that can
act as a layer between the User Interface Layer and the Business Service Layer.
Thus, it acts as an agent in the sense that it facilitates the communication between
the User Interface Layer and the Business Service Layer in a typical n–tier
application design. It is to be noted here that both the Adapter and Façade
design patterns can be used to change the interfaces of the classes, thus enabling
an easier communication of these classes from the User Interface Layer.
The Bridge Pattern eliminates the need of adapter classes in a sub system and decouples
an object’s interface from its implementation so that both can work independent
of each other. The Composite Pattern is a design pattern that is used to compose
a tree like structure of simple and composite objects so that the clients can treat
the individual objects and their compositions in a uniform manner. The Decorator
Pattern provides an alternative for sub classing to extend functionality in a sub
system and adds responsibilities to objects even after construction of the design
of the system. The Flyweight Pattern is a fine-grained instance used for efficient
sharing. The Proxy Pattern shows an object representing another object and,
like the Adapter Design Pattern, it acts as a layer between the client or the consumer
application and the actual object.
|
|
Behavioral Patterns |
Behavioral patterns help you define a structure for inter-object communication between
objects in your system. This design pattern is typically used to monitor the
messages that are transmitted when the objects communicate in a system. The
following are the sub patterns under Behavioral Patterns.
·
Chain of Responsibility
·
Command
·
Interpreter
·
Iterator
·
Mediator
·
Memento
·
Observer
·
State
·
Strategy
·
Template Method
·
Visitor
The Chain of Responsibility Pattern is one that details a way of passing a request
between a chain of objects. The Command Pattern encapsulates a command request
as an object. The Interpreter Pattern is a way to include language elements
in a program. The Iterator Pattern sequentially accesses the elements of a
collection. The Mediator Pattern defines simplified communication between
classes. The Memento Pattern captures and restores an object's internal state.
The Observer Pattern is a design pattern that provides a way of notifying
a change to a number of its dependant classes. Therefore, when one object
changes its state, so do all its dependant objects in the sub system. The
State Pattern is a design pattern that changes an object's behavior when the internal
state of the object changes. The Strategy Pattern is used to encapsulate a
family of algorithms inside a class and use them interchangeably and independent
of the client application that use the same. The Template Method Pattern is
a design pattern that is used to provide a template of an algorithm and defers some
of the steps of the algorithm to the subclasses. The Visitor Pattern is one
that is used to define a new operation to a class without a change.
|
|
A Word of Caution |
It is agreed that design patterns can solve complexities and problems in software
design phases, but improper applicability of Design Patterns can lead to bad designs
that can facilitate software design errors. Be very careful when using or
applying design patterns. Do not use a pattern to solve a problem that does
not need it. Do not simply ornament software design using a design pattern
when it is not at all required in that context. Think twice before you decide
to use them in your design. Understand the scope of the problem context and
then search for a design pattern that best fits in that context to solve the problem.
Further, one should have an excellent understanding of the scope and applicability
of each design pattern before using it. Analyze the problem carefully, consider
all options and apply the appropriate design pattern to solve the problem. What
I personally feel is that we should only implement a design pattern in our software
design provided we have sufficient knowledge of its applicability and scope. At
the same time, we should be able to analyze the problem context and judge the applicability
of the correct design pattern (if it is required at all) as a solution to the problem
in question. It is quite unnecessary and not wanted of a software architect
to implement a design pattern in a problem domain and increase complexity when it
can be solved without using one.
|
|
References |
|
|
Conclusion |
I have provided a brief introduction to the all three categories of the Gang of
Four Design Patterns in this article. The reader should be well aware of when
to use which pattern in designing the software. Recognizing the feature and
benefit of a particular pattern is of utmost importance when implementing it. The
best advantage that can be gained from using these patterns is by applying the right
type of pattern at the right place in the design. Stay tuned for more articles
in which I would like to provide a detailed know-how on each and every pattern with
sample code examples in each case for better understanding of a design pattern,
its intent and applicability. I welcome your comments and suggestions. Happy
reading!
|