Creational design patterns are design patterns that deal with object creation mechanisms, trying to create objects in a manner suitable to the situation.
In this tutorial you will learn about Creational Design Patterns, Factory Method, Abstract Factory, Builder, Prototype and Singleton.
Creational Patterns (all about creation of objects)
- Factory Method: – Creates an instance of several derived classes.
- Abstract Factory: – Creates an instance of several families of classes.
- Builder: – Separates object construction from its representation.
- Prototype: – A fully initialized instance to be copied or cloned.
- Singleton: – A class in which only a single instance can exist.
Factory(Method) pattern is one of the types of creational patterns. You can make out from the name factory itself it’s meant to construct and create something. In software architecture world factory pattern is meant to centralize creation of objects.
Like other creational patterns, it deals with the problem of creating objects (product) without specifying the exact class of object that will be created. The factory method design pattern handles this problem by defining a separate method for creating the objects (CreateProduct), which subclasses can then override to specify the derived type of product that will be created.
We call this a Factory Pattern since it is responsible for “Manufacturing” an Object. It helps instantiate the appropriate Subclass by creating the right Object from a group of related classes. The Factory Pattern promotes loose coupling by eliminating the need to bind application-specific classes into the code.
Problem :
- Sometimes, an Application (or framework) at runtime, cannot anticipate the class of object that it must create. The Application (or framework) may know that it has to instantiate classes, but it may only know about abstract classes (or interfaces), which it cannot instantiate. Thus the Application class may only know when it has to instantiate a new Object of a class, not what kind of subclass to create.
- a class may want it’s subclasses to specify the objects to be created.
- a class may delegate responsibility to one of several helper subclasses so that knowledge can be localized to specific helper subclasses.
Example :
public abstract class product { } public class Keyboard : product { } public class Mouse : product { } public abstract class Creator { public abstract product CreateProduct(); } public class CreatorKeyboard : Creator{ public override product CreateProduct() { return new Keyboard(); } } public class CreatorMouse : Creator{ public override product CreateProduct(){ return new Mouse(); } } //Application Code : List creators = new List(); creators.Add(new CreatorKeyboard()); creators.Add(new CreatorMouse()); foreach (Creator creator in creators){ product p = creator.CreateProduct(); }
Abstract factory expands on the basic factory pattern. Abstract factory helps us to unite similar factory pattern classes in to one unified interface. So basically all the common factory patterns now inherit from a common abstract factory class which unifies them in a common class. A factory class helps us to centralize the creation of classes and types. Abstract factory helps us to bring uniformity between related factory patterns which leads more simplified interface for the client.
- Provide an interface for creating families of related or dependent objects without specifying their concrete classes.
- A hierarchy that encapsulates: many possible “platforms”, and the construction of a suite of “products”.
- The new operator considered harmful.
Example :
The Example here has an implementation of an Abstract Factory as an Interface IAVDevice that has methods that can create an Audio object and a Video object. The client Codes against IAVDevice and gets IAudio and IVideo interfaces. Passing AVType.CD in the command line creates a family of cd objects (Audio and Video) and AVType.DVD creates a family of dvd objects (Audio and Video). The client doesn’t care which object (cd audio video or dvd audio video), IAVDevice interface returns as it codes against IAudio and IVideo interface.
public interface IAudio { string GetSoundQuality { get; }} public interface IVideo{ string GetVideoQuality { get; }} public interface IAVDevice{ IAudio GetAudio(); IVideo GetVideo(); } internal class cdAudio : IAudio{ public string GetSoundQuality { get {return "CD Sound"; } } } internal class dvdAudio : IAudio{ public string GetSoundQuality { get { return "DVD Sound"; } } } internal class cdVideo : IVideo{ string IVideo.GetVideoQuality { get { return "CD Video"; } } } internal class dvdVideo : IVideo{ string IVideo.GetVideoQuality { get { return "DVD Video"; } } } internal class CD : IAVDevice{ public IAudio GetAudio() { return new cdAudio(); } public IVideo GetVideo() { return new cdVideo(); } } internal class DVD : IAVDevice{ public IAudio GetAudio() { return new dvdAudio(); } public IVideo GetVideo() { return new dvdVideo(); } } public enum AVType{ CD=0, DVD } public class AVMaker{ public IAVDevice Make(AVType type) { switch (type) { case AVType.CD: return new CD(); case AVType.DVD: return new DVD(); default: return new CD(); } } } //Application Code IAVDevice device = new AVMaker().Make(AVType.CD); string s = device.GetAudio().GetSoundQuality; string v = device.GetVideo().GetVideoQuality;
/** "Product" */ class Pizza { public string Dough { get; set; } public string Sauce { get; set; } public string Topping { get; set; } } /** "Abstract Builder" */ abstract class PizzaBuilder { public Pizza pizza { get; protected set; } public void CreatePizza() { pizza = new Pizza(); } public abstract void BuildDough(); public abstract void BuildSauce(); public abstract void BuildTopping(); } /** "ConcreteBuilder" */ class HawaiianPizzaBuilder : PizzaBuilder { public override void BuildDough() { pizza.Dough = "Cross"; } public override void BuildSauce() { pizza.Sauce = "Mild"; } public override void BuildTopping() { pizza.Topping = "Ham+Pineapple"; } } /** "ConcreteBuilder" */ class SpicyPizzaBuilder : PizzaBuilder { public override void BuildDough() { pizza.Dough = "Pan Baked"; } public override void BuildSauce() { pizza.Sauce = "Hot"; } public override void BuildTopping() { pizza.Topping = "Pepperoni+Salami"; } } /** "Director" */ class Cook { public PizzaBuilder PizzaBuilder { get; set; } public Pizza Pizza { get { return PizzaBuilder.pizza; } } public void MakePizza() { PizzaBuilder.CreatePizza(); PizzaBuilder.BuildDough(); PizzaBuilder.BuildSauce(); PizzaBuilder.BuildTopping(); } } /** A given type of pizza being constructed. */ static void Main(string[] args) { Cook cook = new Cook(); cook.PizzaBuilder = new SpicyPizzaBuilder(); cook.MakePizza(); cook.PizzaBuilder = new HawaiianPizzaBuilder(); cook.MakePizza(); }
Prototype pattern falls in the section of creational pattern. It gives us a way to create new objects from the existing instance of the object. In one sentence we clone the existing object with its data. By cloning any changes to the cloned object does not affect the original object value.
There are two types of cloning for prototype patterns. One is the shallow cloning, in shallow copy only that object is cloned, any objects containing in that object is not cloned. For instance consider that we have a customer class and we have an address class aggregated inside the customer class. ‘MemberWiseClone’ will only clone the customer class ‘Customer’ but not the ‘Address’ class. So we added the ‘MemberWiseClone’ function in the address class also. Now when we call the ‘getClone’ function we call the parent cloning function and also the child cloning function, which leads to cloning of the complete object. When the parent objects are cloned with their containing objects it’s called as deep cloning and when only the parent is clones its termed as shallow cloning.
This pattern is used to:
- avoid subclasses of an object creator in the client application, like the abstract factory pattern does.
- avoid the inherent cost of creating a new object in the standard way (e.g., using the ‘new’ keyword) when it is prohibitively expensive for a given application.
To implement the pattern, declare an abstract base class that specifies a pure virtual clone() method. Any class that needs a “polymorphic constructor” capability derives itself from the abstract base class, and implements the clone() operation.
The client, instead of writing code that invokes the “new” operator on a hard-coded class name, calls the clone() method on the prototype, calls a factory method with a parameter designating the particular concrete derived class desired, or invokes the clone() method through some mechanism provided by another design pattern.
Example : Shallow copy prototype pattern
public class Address { } public abstract class CloneType<T> where T : CloneType<T> { public T Clone() { return (T)this.MemberwiseClone(); } } //Shallow Clone public class Customer : CloneType<Customer> { public string Name { get; set; } public Address MailingAddress { get; set; } } //Application Customer Prototype = new Customer(); List<Customer> realCustomers = new List<Customer>(); for (int i = 0; i <= 10; i++) { Customer customer = Prototype.Clone(); customer.Name = "Rajneesh Noonia"; customer.MailingAddress = new Address(); realCustomers.Add(customer); }
Singleton Pattern: There are situations in a project where we want only one instance of the object to be created and shared between the clients. No client can create an instance of the object from outside. There is only one instance of the class which is shared across the clients. Below are the steps to make a singleton pattern:-
1) Define the constructor as private.
2) Define the instances and methods as static.
Example :
//Thread-safe singleton example created at first call public sealed class Application { // Utilizes the get and set auto implemented properties. // Note that set; can be any other operator as long as it's // less accessible than public. public static Application Instance { get; private set; } // A static constructor is automatically initialized on reference // to the class. static Application() { Instance = new Application(); } }
THank u so much… it helped me a lot…
LikeLike