What is Design Pattern?
In Software Engineers, a design pattern is a general reusable solution to a commonly occurring problem in software Design. A design pattern is not a finished design that can be transformed directly into code. It is a description or template for how to solve a problem that can be used in many different situations. Object Oriented design patterns typically show relationships and interactions between Classes or objects, without specifying the final application classes or objects that are involved.
Design patterns reside in the domain of modules and interconnections. At a higher level there are Architectural Pattern that are larger in scope, usually describing an overall pattern followed by an entire system.
Design patterns gained popularity in computer science after the book Design Patterns: Elements of Reusable Object-Oriented Software was published in 1994 by the so-called ?Gang of Four? (Gamma etal.). That same year, the first Pattern Languages of Programming Conference was held and the following year, the Portland Pattern Repository was set up for documentation of design patterns. The scope of the term remains a matter of dispute. Notable books in the design pattern genre include:
Gamma, Erich; Design patterns gained popularity in , Ralph Johnson, and John Vlissides (1995).
Design Patterns ware originally grouped in the following categories:
?
Description of Factory: Factory Method defines an interface for creating an object, but lets subclasses decide which of those to instantiate.
- Creational patterns abstract the object instantiation process. They hide how objects are created and help make the overall system independent of how its objects are created and composed.
- Class creational patterns focus on the use of inheritance to decide the object to be instantiated factory method.
- Object creational patterns focus on the delegation of the instantiation to another object abstract factory.
Iimplementation Of Factory Pattern:
interface IBase
{
string Perform();
}
Implement the Interface
Listing 1
class Algorithm1: IBase
{
public string Perform()
{
return ?Algorithm1 Performed?;
}
}
class Algorithm2: IBase
{
public string Perform()
{
return ?Algorithm2 Performed?;
}
}
class Algorithm3: IBase
{
public string Perform()
{
return ?Algorithm3 Performed?;
}
}
CODE interface IBase
{
string Perform();
}
Implement the Interface
Listing 5
class Algorithm1: IBase
{
public string Perform()
{
return ?Algorithm1 Performed?;
}
}
class Algorithm2: IBase
{
public string Perform()
{
return ?Algorithm2 Performed?;
}
}
class Algorithm3: IBase
{
public string Perform()
{
return ?Algorithm3 Performed?;
}
}
In Listing 1, the three classes Algorithm1, Algorithm2 and Algorithm3 are defined which implements the IBase interface (refer to Listing 4).
Define the Factory Class
First, define the Factory class. This class is responsible for instantiating the required object and returning it to the client. Once the object is returned, the client code will call the object methods without knowing how these objects methods are implemented. This provides the encapsulation mechanism.
Listing 2
class Factory
{
public IBase GetObject(int AlgorithmType)
{
IBase objbase = null;
switch (AlgorithmType)
{
case 1:
objbase = new Algorithm1();
break;
case 2:
objbase = new Algorithm2();
break;
case 3:
objbase = new Algorithm3();
break;
default:
throw new Exception(?Unknown Object?);
}
return objbase;
}
}
Create the Client Application
Add the form to the Windows Applications project and then add the button btnClient. To this button, add the below code.
Listing 3
private void btnClient_Click(object sender,EventArgs e)
{
try
{
Factory objfactory = new Factory();
IBase objBase = objfactory.GetObject(2);
MessageBox.Show(objBase.Perform());
objBase = objfactory.GetObject(3);
MessageBox.Show(objBase.Perform());
}
catch (Exception objex)
{
MessageBox.Show(objex.Message);
}
}
The Factory pattern can almost be seen as a simplified version of the Builder pattern.
In the Factory pattern, the factory is in charge of creating various subtypes of an object depending on the needs.
The user of a factory method doesn?t need to know the exact subtype of that object. An example of a factory method createCar might return a Ford or a Honda typed object.
In the Builder pattern, different subtypes are also created by a builder method, but the composition of the objects might differ within the same subclass.
To continue the car example you might have a createCar builder method which creates a Honda-typed object with a 4 cylinder engine, or a Honda-typed object with 6 cylinders. The builder pattern allows for this finer granularity.
Description Of Abstract Factory :By contrast, an Abstract Factory provides an interface for creating families of related or dependent objects without specifying their concrete classes.
- The Abstract Factory pattern is very similar to the Factory Method pattern. One difference between the two is that with the Abstract Factory pattern, a class delegates the responsibility of object instantiation to another object via composition whereas the Factory Method pattern uses inheritance and relies on a subclass to handle the desired object instantiation.
- Actually, the delegated object frequently uses factory methods to perform the instantiation
Implementation of Abstract Factory Pattern:
///
/// The ?AbstractFactory? abstract class
///
abstract class AbstractFactory
{
public abstract AbstractProductA CreateProductA();
public abstract AbstractProductB CreateProductB();
}
///
/// The ?ConcreteFactory1? class
///
class ConcreteFactory1 : AbstractFactory
{
public override AbstractProductA CreateProductA()
{
return new ProductA1();
}
public override AbstractProductB CreateProductB()
{
return new ProductB1();
}
}
///
/// The ?ConcreteFactory2? class
///
class ConcreteFactory2 : AbstractFactory
{
public override AbstractProductA CreateProductA()
{
return new ProductA2();
}
public override AbstractProductB CreateProductB()
{
return new ProductB2();
}
}
///
/// The ?AbstractProductA? abstract class
///
abstract class AbstractProductA
{
}
///
/// The ?AbstractProductB? abstract class
///
abstract class AbstractProductB
{
public abstract void Interact(AbstractProductA a);
}
///
/// The ?ProductA1? class
///
class ProductA1 : AbstractProductA
{
}
///
/// The ?ProductB1? class
///
class ProductB1 : AbstractProductB
{
public override void Interact(AbstractProductA a)
{
Console.WriteLine(this.GetType().Name +
? interacts with ? + a.GetType().Name);
}
}
///
/// The ?ProductA2? class
///
class ProductA2 : AbstractProductA
{
}
///
/// The ?ProductB2? class
///
class ProductB2 : AbstractProductB
{
public override void Interact(AbstractProductA a)
{
Console.WriteLine(this.GetType().Name +
? interacts with ? + a.GetType().Name);
}
}
///
/// The ?Client? class. Interaction environment for the products.
///
class Client
{
private AbstractProductA _abstractProductA;
private AbstractProductB _abstractProductB;
// Constructor
public Client(AbstractFactory factory)
{
_abstractProductB = factory.CreateProductB();
_abstractProductA = factory.CreateProductA();
}
public void Run()
{
_abstractProductB.Interact(_abstractProductA);
}
}
}
public static void Main()
{
// Abstract factory #1
AbstractFactory factory1 = new ConcreteFactory1();
Client client1 = new Client(factory1);
client1.Run();
// Abstract factory #2
AbstractFactory factory2 = new ConcreteFactory2();
Client client2 = new Client(factory2);
client2.Run();
// Wait for user input
Console.ReadKey();
}
}
Description of Singletone: This pattern are responsible for creating single object.The main purpose to create lazy initialization of an object.
Implementation of Singletone Pattern:
///
/// Thread-safe singleton example created at first call
///
public sealed class Singleton
{
private static Singleton instance;
private static readonly Object mutex = new Object();
private Singleton() { }
public static Singleton Instance
{
get
{
lock(mutex)
return instance == null ? (instance = new Singleton()) : instance;
}
}
}
The big difference between a singleton and a bunch of static methods is that singletons can implement interfaces (or derive from useful base classes, although that?s less common IME), so you can pass around the singleton as if it were ?just another? implementation
Description of Builder Pattern: The Builder Pattern is quite confusing. There is a very subtle difference between Builder Pattern and Factory Pattern. I am not discussing Factory Pattern in this article but will soon write about Factory Pattern as well.
In Builder Pattern the user is given the choice to create the type of object he wants but the construction process is the same. We consider an example ? suppose you went to buy a car. First you will choose the model of the car and then it?s color and you consider it?s price that whether it?s feasible for you or not. If you want some extra luxuries in the car you will note them down as well and in the end you will place the order. Now you are isolated with the manufacturing process. You are not bothered by the manufacturing process. It?s the duty of the company because they have the assembly plant, which is programmed to manufacture cars of the model you choose and the manufacturing process is the same for a specified model of car.
In Builder, the client instructs the builder class how to create the object and then asks it for the result. How the class is put together is up to the Builder class.
Implementation of Builder Pattern:
using System;
using System.Windows.forms;
namespace BuilderPattern
{
///
/// Summary description for IBuilder.
///
public interface IBuilder
{
void ManufactureCar();
}
}
Classes that extends from IBuilder interface
1) SuzukiMehran Class
using System;
using System.Windows.forms;
namespace BuilderPattern
{
///
/// Summary description for SuzukiMehran.
///
public class SuzukiMehran:IBuilder
{
public void ManufactureCar()
{
MessageBox.Show(?Suzuki Mehran Model 2002 ?
+?Color Balck ?
+ ?Air Conditioned ? );
}
}
}
2) SuzukiKhyber Class
using System;
using System.Windows.forms;
namespace BuilderPattern
{
///
/// Summary description for SuzukiKhyber.
///
public class SuzukiKhyber:IBuilder
{
public SuzukiKhyber()
{
}
public void ManufactureCar()
{
MessageBox.Show(?Suzuki Khyber Model 2002 Standard ?
+?Color Red ?
+?Air Conditioned ?
+?Alloy Rim ?);
}
}
}
3) Director class
using System;
namespace BuilderPattern
{
///
/// Summary description for Director.
///
public class Director
{
public void ConstructCar(IBuilder build)
{
build.ManufactureCar();
}
}
}
4) Client Class
private void button1_Click(object sender, System.EventArgs e)
{
if(cmbChooseCar.Text==?Suzuki Mehran?)
{
Director car=new Director();
IBuilder build=new SuzukiMehran();
car.ConstructCar(build);
}
if(cmbChooseCar.Text==?Suzuki Khyber?)
{
Director car=new Director();
IBuilder build=new SuzukiKhyber();
car.ConstructCar(build);
}
}
The AbstractFactory is for a family of related products. The Builder is for one product.
The Builder is for building a complex product step by step, while the AbstractFactory is to build in an abstract way (that is, once for several implementations) a less complex product
Builder focuses on constructing a complex object step by step. Abstract Factory emphasizes a family of product objects (either simple or complex). Builder returns the product as a final step, but as far as the Abstract Factory is concerned, the product gets returned immediately.
Description of Prototype Pattern:
The prototype pattern is used when creating an instance of a class is very time consuming or complex in some way. Then rather than creating more instances, it is possible to make copies of the original instances and modifying them as appropriate.
Implementation of Prototype Pattern :
using System;
namespace DoFactory.GangOfFour.Prototype.Structural
{
///
/// MainApp startup class for Structural
/// Prototype Design Pattern.
///
class MainApp
{
///
/// Entry point into console application.
///
static void Main()
{
// Create two instances and clone each
ConcretePrototype1 p1 = new ConcretePrototype1(?I?);
ConcretePrototype1 c1 = (ConcretePrototype1)p1.Clone();
Console.WriteLine(?Cloned: {0}?, c1.Id);
ConcretePrototype2 p2 = new ConcretePrototype2(?II?);
ConcretePrototype2 c2 = (ConcretePrototype2)p2.Clone();
Console.WriteLine(?Cloned: {0}?, c2.Id);
// Wait for user
Console.ReadKey();
}
}
///
/// The ?Prototype? abstract class
///
abstract class Prototype
{
private string _id;
// Constructor
public Prototype(string id)
{
this._id = id;
}
// Gets id
public string Id
{
get { return _id; }
}
public abstract Prototype Clone();
}
///
/// A ?ConcretePrototype? class
///
class ConcretePrototype1 : Prototype
{
// Constructor
public ConcretePrototype1(string id)
: base(id)
{
}
// Returns a shallow copy
public override Prototype Clone()
{
return (Prototype)this.MemberwiseClone();
}
}
///
/// A ?ConcretePrototype? class
///
class ConcretePrototype2 : Prototype
{
// Constructor
public ConcretePrototype2(string id)
: base(id)
{
}
// Returns a shallow copy
public override Prototype Clone()
{
return (Prototype)this.MemberwiseClone();
}
}
}
This helps to copy or clone the existing objects to create new ones rather than creating from the scratch.
Specify the kinds of objects to create using a prototypical instance, and create new objects by copying this prototype. ? ?Design Patterns? Gamma etal., Addison-Wesley, ISBN:0-201-63361-2?
When we are not in a position to call a constructor for an object directly, we could alternatively clone a pre-existing object (a prototype) of the same class. When there are many subclasses that differ only in the kind of objects they create a Prototype Pattern can be used to reduce the number of subclasses by cloning a prototype. Prototype Design Pattern helps in reducing number of classes.
For example suppose we have to do say Sales Analysis on a set of data in the database. Normally we will create an object encapsulating this data and do the Sales Analysis. Suppose now we have to do another type of analysis say Promotion Analysis on the same data. Now instead of creating another object corresponds to the data from the scratch, we can clone the existing object and do the analysis. This is one of the classical use of prototype pattern.