Pages

Wednesday, July 22, 2015

Creational Pattern - Factory Pattern With Abstract Factory Pattern

Factory pattern is creational design pattern that suppose to create an object for client at runtime.In other words, responsibility of creating objects with same type delegate to some other class which is known as factory class.
 

   public interface Pizza
    {
         void prepare();
         void bake();
         void cut();
         void box();
    }

    public class CheesePizza : Pizza
    {
        public void prepare()
        {
            Console.Write("\n CheesePizza: prepare \n");
        }

        public void bake()
        {
            Console.Write("CheesePizza: bake \n");
        }

        public void cut()
        {
            Console.Write("CheesePizza: cut \n");
        }

        public void box()
        {
            Console.Write("CheesePizza: box \n");
        }
    }

    public class VeggiePizza : Pizza
    {

        public void prepare()
        {
            Console.Write("\n VeggiePizza: prepare \n");
        }

        public void bake()
        {
            Console.Write("VeggiePizza: bake\n");
        }

        public void cut()
        {
            Console.Write("VeggiePizza: cut\n");
        }

        public void box()
        {
            Console.Write("VeggiePizza: box\n");
        }
    }

    //SimplePizzaFactory class suppose to create object for client
    public class SimplePizzaFactory
    {
        public Pizza CreatePizza(string type)
        {
            Pizza pizza = null;
            switch (type)
            {
                case "cheese":
                    pizza = new CheesePizza();
                    break;
                case "veggie":
                    pizza = new VeggiePizza();
                    break;
                default:
                    break;
            }
            return pizza;
        }
    }

    public class PizzaStore
    {
        SimplePizzaFactory factory;

        public PizzaStore(SimplePizzaFactory factory)
        {
            this.factory = factory;
        }

        public Pizza OrderPizza(string type)
        {
            Pizza pizza;

            //uses the factory to create pizza
            pizza = factory.CreatePizza(type);

            pizza.prepare();
            pizza.bake();
            pizza.cut();
            pizza.box();

            return pizza;
        }
    }


    //************HeadDesign: simple factory pattern*********************

        PizzaStore pizzStore = new PizzaStore(new SimplePizzaFactory());
        pizzStore.OrderPizza("cheese");
        pizzStore.OrderPizza("veggie");
        Console.ReadKey();

    //******************************************************************* 
Abstract factory pattern: extended to existing simple factory and creating the related class for object creation.
public interface Pizza
    {
        void prepare();
        void bake();
        void cut();
        void box();
    }

    public class NYSyleCheesePizza : Pizza
    {
        public void prepare()
        {
            Console.Write("\n NYSyleCheesePizza: prepare \n");
        }

        public void bake()
        {
            Console.Write("NYSyleCheesePizza: bake \n");
        }

        public void cut()
        {
            Console.Write("NYSyleCheesePizza: cut \n");
        }

        public void box()
        {
            Console.Write("NYSyleCheesePizza: box \n");
        }
    }

    public class NYVeggiePizza : Pizza
    {

        public void prepare()
        {
            Console.Write("\n NYVeggiePizza: prepare \n");
        }

        public void bake()
        {
            Console.Write("NYVeggiePizza: bake \n");
        }

        public void cut()
        {
            Console.Write("NYVeggiePizza: cut \n");
        }

        public void box()
        {
            Console.Write("NYVeggiePizza: box \n");
        }
    }

    public class ChSyleCheesePizza : Pizza
    {
        public void prepare()
        {
            Console.Write("\n ChSyleCheesePizza: prepare \n");
        }

        public void bake()
        {
            Console.Write("ChSyleCheesePizza: bake \n");
        }

        public void cut()
        {
            Console.Write("ChSyleCheesePizza: cut \n");
        }

        public void box()
        {
            Console.Write("ChSyleCheesePizza: box \n");
        }
    }

    public class ChVeggiePizza : Pizza
    {

        public void prepare()
        {
            Console.Write("\n ChVeggiePizza: prepare \n");
        }

        public void bake()
        {
            Console.Write("ChVeggiePizza: bake \n");
        }

        public void cut()
        {
            Console.Write("ChVeggiePizza: cut \n");
        }

        public void box()
        {
            Console.Write("ChVeggiePizza: box \n");
        }
    }

    public abstract class PizzaStore
    {
        public Pizza OrderPizza(string type)
        {
            Pizza pizza;

            //uses the factory to create pizza
            pizza = CreatePizza(type);

            pizza.prepare();
            pizza.bake();
            pizza.cut();
            pizza.box();

            return pizza;
        }

        public abstract Pizza CreatePizza(string type);
    }

    public class NYPizzaStore : PizzaStore
    {
        public override Pizza CreatePizza(string type)
        {
            switch (type)
            {
                case "cheese":
                    return new NYSyleCheesePizza();
                    break;
                case "veggie":
                    return new NYVeggiePizza();
                    break;
                default:
                    break;
            }
            return null;
        }
    }

    public class ChPizzaStore : PizzaStore
    {
        public override Pizza CreatePizza(string type)
        {
            switch (type)
            {
                case "cheese":
                    return new ChSyleCheesePizza();
                    break;
                case "veggie":
                    return new ChVeggiePizza();
                    break;
                default:
                    break;
            }
            return null;
        }
    }



 //************HeadDesign: abstract factory pattern*******************
     PizzaStore  NYPizzaStore= new NYPizzaStore();
     NYPizzaStore.OrderPizza("cheese");
         
     PizzaStore ChPizzaStore = new ChPizzaStore();
     ChPizzaStore.OrderPizza("veggie");
     Console.ReadKey();

//********************************************************************


Tuesday, July 21, 2015

Structural Patterns - Decorator Pattern

~Add responsibilities to objects dynamically~

The Decorator Pattern attaches additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.

By definition, in a solution designed in the Decorator pattern, there is a component class and then there is the decorator class. The decorator class holds a reference to an object of the component's type and itself is derived from the component class.
Say what?
Yes, and theoretically the decorator classes are chained together around the component class and use delegation to give the component class new responsibilities.


UML - Decorator Pattern
UML - Decorator Pattern


Let have a look in practical example:-

   //Beverage is an abstract class with the two methods getDescription() and cost().

    public abstract class Beverage
    {
        protected string m_description = "UnKnown Beverage";
        //get a description of the beverage
        public virtual String Description { get { return m_description; } }
        public abstract double cost();
    }

    //we extend the Beverage class, since this is a beverage.
    public class Espresso : Beverage
    {
        public Espresso()
        {
            m_description = "Espresso";
        }

        public override double cost()
        {
            return 0.99;
        }
    }


    //here’s another Beverage.
    public class HouseBlend : Beverage
    {
        public HouseBlend()
        {
            m_description = "HouseBlend";
        }

        public override double cost()
        {
            return .89;
        }
    }


    //here’s another Beverage.
    public class DarkRoast : Beverage
    {
        public DarkRoast()
        {
            m_description = "DarkRoast";
        }

        public override double cost()
        {
            return .33;
        }
    }


    //we need to be interchangeable with a Beverage, so we extend the Beverage class.
    public abstract class CondimentDecorator : Beverage { }

    //here’s another Beverage.
    public class Decaf : Beverage
    {
        public Decaf()
        {
            m_description = "Decaf";
        }

        public override double cost()
        {
            return .43;
        }
    }

    //Mocha is a decorator, so we extend CondimentDecorator
    public class Mocha : CondimentDecorator
    {
        Beverage beverageInternal;

        public Mocha(Beverage beverage)
        {
            this.beverageInternal = beverage;
        }

        // getter implements abstract class Description
        public override String Description
        {
            get
            {
                return beverageInternal.Description + ", Mocha";
            }
        }

        public override double cost()
        {
            return .20 + beverageInternal.cost();
        }
    }


    //Whip is a decorator, so we extend CondimentDecorator
    public class Whip : CondimentDecorator
    {
        Beverage beverageInternal;

        public Whip(Beverage beverage)
        {
            this.beverageInternal = beverage;
        }

        // getter implements abstract class Description
        public override String Description
        {
            get
            {
                return beverageInternal.Description + ", Whip";
            }
        }

        public override double cost()
        {
            return 1.20 + beverageInternal.cost();
        }

    }

    //Soy is a decorator, so we extend CondimentDecorator
    public class Soy : CondimentDecorator
    {
        Beverage beverageInternal;

        public Soy(Beverage beverage)
        {
            this.beverageInternal = beverage;
        }

        // getter implements abstract class Description
        public override String Description
        {
            get
            {
                return beverageInternal.Description + ", Soy";
            }
        }

        public override double cost()
        {
            return 2.20 + beverageInternal.cost();
        }
    }
 
//Calling at client end as follow:-
//************Decorator Pattern*******************************************
            //Order up an espresso, no condiments and print its description and cost.
            Beverage beverage = new Espresso();
            Console.Write("\n" + beverage.Description + " $ " + beverage.cost() + "\n");

            Beverage beverage2 = new DarkRoast();//Make a DarkRoast object.Finally,
            beverage2 = new Mocha(beverage2);//Wrap it with a Mocha
            beverage2 = new Mocha(beverage2);//Wrap it with second Mocha
            beverage2 = new Mocha(beverage2);//Wrap it with third Mocha
            beverage2 = new Whip(beverage2);//Wrap it in a Whip.
            beverage2 = new Soy(beverage2);//Wrap it in a Soy.
            beverage2 = new Soy(beverage2);//Wrap it in a Soy.
            beverage2 = new Soy(beverage2);//Wrap it in a Soy.
            beverage2 = new Soy(beverage2);//Wrap it in a Soy.
            Console.Write("\n" + beverage2.Description + " $ " + beverage2.cost() + "\n");

            Beverage beverage3 = new HouseBlend();
            beverage3 = new Soy(beverage3);
            beverage3 = new Mocha(beverage3);
            beverage3 = new Whip(beverage3);
            Console.Write("\n" + beverage3.Description + " $ " + beverage3.cost() + "\n");
            Console.ReadKey();
            //************************************************************************


Here is the bullet points for decorator pattern:-
  1. Inheritance is one form of extension, but not necessarily the best way to achieve flexibility
  2. in our designs.
  3. In our designs we should allow behavior to be extended without the need to modify existing code.
  4. Composition and delegation can often be used to add new behaviors at runtime.
  5. The Decorator Pattern provides an alternative to subclassing for extending behavior.
  6. The Decorator Pattern involves a set of decorator classes that are used to wrap concrete components.
  7. Decorator classes mirror the type of the components they decorate. (In fact, they are the same type as the components they decorate, either through inheritance or interface implementation.)
  8. Decorators change the behavior of their components by adding new functionality before and/or
  9. after (or even in place of) method calls to the component.
  10. You can wrap a component with any number of decorators.
  11. Decorators are typically transparent to the client of the component; that is, unless the client is relying on the component’s concrete type.
  12. Decorators can result in many small objects in our design, and overuse can be complex.
I have taken help from 'Head first design pattern' for above. Thanks to Head First Design Patterns and Team.