Design patterns

1. Abstract---------------------------------------------------------

The design patterns are useful in the design phase of the object oriented software. Traditionally many experienced designers and architects have found that the some of the design solutions can be reused and named them as patterns. These design patterns make our design more flexible and maintainable so that it is easy to handle new requirements coming in latter stage. This document covers three design patterns. Abstract factory pattern, bridge pattern and facade pattern.

2. Intended Audience------------------------------------------------

For the developers who are involved in object oriented design. To understand the patterns I assume that the developer has aware of inheritance, aggregation, encapsulation and UML class diagram concepts in object oriented paradigm.


3. Motivation
---------------------------------------------------------------

Why to use the Design patterns? Because it is hard to develop reusable software and handling new requirements in software without changing the existing system much

4. Introduction to design patterns----------------------------------

A pattern is a recurring solution to a standard problem. When related patterns are woven together they form a ``language'' that provides a process for the orderly resolution of software development problems. Patterns have a context in which they apply. Clarity of expression makes it easier to see when and why to use certain patterns, as well as when and why not to use these patterns.

Some times we come across the situation where the requirements keep on changing while the project is in design phase or in coding phase, instead of changing the design again and again, we can predict where the changes can be and how to take the step so that we can meet the future requirements with minimal changes in design and in code.

It is ideal that without changing the existing system the additional functionalities can be added. So instead of making major changes in design, let’s keep the changes to be done minimum so that maintenance will not be a nightmare. Patterns help in this scenario.


Let’s discuss some basic object oriented design principles. They are
• Program to an 'interface', not an 'implementation'.
• Favor aggregation over inheritance.
The advantages in using these rules are
• Clients remain unaware of the specific types of objects they use, as long as the object adheres to the interface.
• Clients remain unaware of the classes that implement these objects; clients only know about the abstract class defining the interfaces.
Let’s look at patterns now

BRIDGE PATTERN:
The intent of this pattern is decouple the abstraction with the implementation. Here the abstraction refers to the class and implementation refers to how classes are implemented. Lets look it with an example.

Suppose I had been given a task to draw rectangle using the drawing algorithms DP1 and DP2 say. I was told that when I instantiate the rectangle I know which algorithm should I use.

Let us suppose DP1 implements draw_a_line() for line and draw_a_circle() for circle.
Let us suppose DP2 implements drawline () for line and drawcircle () for circle

Let’s take the abstract class shape and derive rectangle and circle. Now rectangle can use two versions of drawing. So let’s take v1 rectangle and v2 rectangle which uses DP1 and DP2 programs respectively. The same we design for circle class also. Let’s look at design now how it comes.

Click at the picture to enlarge.



V1 rectangle and V1circle uses DP1 class methods and V2 shapes uses DP2 methods.

Let us suppose client has come up with new shape again say triangle, then see how the impact will be. It results in creating other hierarchy called triangle. Again V1Triangle V2Triangle total 3 classes will be created. There will be tight coupling with DP1 and DP2 classes again.

Then again Imagine one more drawing program has come say DP3, then one more concrete class of each shape has to be created. Total it results in 9 classes. So there is need to separate the variations in abstraction with variations in implementation.

This is the intent of bridge pattern
Now lets separate the implementations drawing programs and shapes(rectangles and circle)
Let’s group rectangle and circle together as shape and DP1 and DP2 as Drawing class.

There are 2 basic strategies in creating designs.
1. Find what varies and encapsulate it.
2. Favor aggregation over inheritance.


This is because the implementations can scale independently. So the final design comes like this.

click on image to enlarge



Now the new shapes or new drawing program can be easily added without creating many class hierarchies

Façade Pattern:

Façade pattern is used to simplify the interface of subsystem which is so complex. Some times the client object has to communicate with many other objects. In those cases we will create one simple interface so that client object always requests this interface. This interface in turn based on client request communicates with appropriate object.

Let’s think we designed database API . We have 3 classes.

1) Environment class which is responsible for creating the database environment
And for creating connections
2) Connection class which is responsible in creating the statements
3) Statement class which is responsible for executing queries and returns the
Result set.
4) ResultSet class which is data structure useful for storing the result

Suppose I have one the client who wants to interact with this database and gets the model. First he creates the environment and then requests the connection to Environment class. After getting the connection object using that client will create the statement and executes the query . Finally he gets the result set.
Here the client object is interacting with Environment class, Connection class, Statement class and Resultset class

Client --------------> Environment class

Client ----------------> Connection class

Client------------------> Statement class

If there is any change in these classes the client has to change its behavior. So let’s wrap all these classes into sub system and design one interface which interacts with all these.

Now for binding, for connection, for query the client will interact with this interface only




Now the communication will be between the client and Façade interface. If client wants the connection, he will request the façade interface which in turn requests the Environment class to create the connection. If our subsystem grows in future it’s the only Façade interface class has to be changed.

Façade pattern is useful to reduce the number of objects to which client communicates directly.

Another example of façade pattern in real time scenario is customer call centre. Let’s suppose a financial institute has savings bank, credit card and insurance departments. So the customer calls the customer care and requests the customer care system to get connected to department. The customer care gets the job done for you. Here the customer care is interface for your queries.

Abstract factory pattern:

Abstract factory is used when we want to create family of objects that relate each other for specific cases. For example when dealing with user interfaces the system might use set of objects for one operating system and other set of objects for other operating system. The abstract factory ensures we get the right set of objects for situation.

Lets design the system which to display and print the shapes from database.
To print and display we have to take care of our computers screen resolution, memory and CPU speed. Let’s design for resolution only now.
For high resolution systems lets take high-resolution print driver (HRPD class) and high-resolution display driver (HRDD class). Like wise for low resolution system we will take low resolution print driver and display driver. For these we shall use LRPD and LRDD classes respectively. If we go for simple design using abstract classes and derive the concrete classes the design will be like this.




Here the Application control (ApControl) uses display driver and print driver and gets the appropriate version. This looks fine as of now.

Let’s assume that we need to support a middle resolution system. Then for each Driver classes other instance has to be created. Not only for middle resolution system for any other specific case the DisplayDriver and PrintDriver classes will have one more instance. Assume that like Drivers if some other criteria comes into picture like CPU speed. Then the Apcontrol will have other hierarchy of classes which results in explosion of classes. It will be simple if have system that creates set of objects according to situation and platform. Uniformity is lacking in this system we designed here.

Let’s create the factory which creates appropriate set of objects. Let’s apply the basic principles
1) See what is varying here and encapsulate it. Here the selection of drivers are varying so lets create ResFactory class which consists of these variations
2) Favor aggregation over inheritance. Now the ApControl class just uses Resfactory which contains the variations
3) Design to interfaces not the implementation. The ApControl knows how to ask ResFactory for instantiation of drivers. But it doesn’t know how ResFactoy is creating the objects.


The Resfactory is abstract one and lets create concrete classes LowResFact and HighResFact which creates objects suitable to their platform. Here the LowResFact is responsible in creating the printing and display drivers for low resolution and same case with HighResFact.

Lets Create PrintDriver for the classes of printing drivers and one abstract class DispDriver for display drivers.



Now the client object knows whom to ask for the objects. The Resfactory is the abstract factory which has the methods to create objects. The concrete classes LowResFact and HighResFact will instantiate the objects accordingly. Here the ApControl will ask the ResFactory to create the display drivers and print drivers. The Resfactory has the methods to select the objects to be created accordingly.

Another example of abstract factory pattern is car manufacturing system. Suppose
We have maruthi800 car, maruthi swift, maruthi Zen cars. To prepare the body of the particular car the client object has to request the factory class which selects the parts accordingly to car type and returns them.

2 comments:

Anonymous said...

very nice info .thanks

Anonymous said...

wow ! nice info arranged in systematical way ..........
way to go ...kudos