Sunday, June 22, 2014

The Abstract Factory Pattern in C#


The Abstract Factory Pattern builds upon the Factory Method pattern and adds Object Composition to the mix.
The Abstract Factory Pattern is officially defined as the following:
The Abstract Factory Pattern provides an interface for creating families of related or dependent objects without specifying their concrete classes. (Head First Design Patterns-the factory pattern)

In “Head First Design Patterns”, the Abstract Factory pattern extends upon the use of the Factory Method by adding control of the various ingredients needed by each of the Pizza Stores.  Therefore, a NY Pizza Store will receive a different set of ingredients vs a Chicago Pizza Store even though the ingredient types are common (sauce, cheese, veggies etc.).
 
Below is the basic pattern code in C# for your review (ingredient classes are left out since they are simple shell classes):
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AbstractFactoryPattern;
 
namespace AbstractFactoryPattern
{
    class Program
    {
        static void Main(string[] args)
        {
            PizzaStore nyStore = new NYPizzaStore();
            Pizza pizza = nyStore.orderPizza("cheese");
            Console.WriteLine("Ethan ordered a " + pizza.Name + "\n");
            Console.ReadKey();
        }
    }
}
 
 
public interface PizzaIngredientFactory
{
  Dough createDough();
  Sauce createSauce();
  Cheese createCheese();
  List<Veggies> createVeggies();
  Pepperoni createPepperoni();
  Clams createClam();
 }//interface
 
public class NYPizzaIngredientFactory: PizzaIngredientFactory
{
  public Dough createDough()
    {
      return new ThinCrustDough();
     }
   public Sauce createSauce()
    {
      return new MarinaraSauce();
     }
    public Cheese createCheese()
    {
       return new ReggianoCheese();
    }
    public List<Veggies> createVeggies()
    {
      List<Veggies> veggies = new List<Veggies> {new Garlic(), new Onion(), new Mushroom(), new RedPepper()};
      return veggies;
    }
    public Pepperoni createPepperoni()
    {
      return new SlicedPepperoni();
     }
     
     public Clams createClam()
     {
       return new FreshClams();
     }
}//class NYPizzaIngredientFactory
 
public class CheesePizza: Pizza
{
  PizzaIngredientFactory ingredientFactory;
  
  public CheesePizza(PizzaIngredientFactory ingredientFactory)
    {
      this.ingredientFactory = ingredientFactory;
    }
    
    public override void prepare()
    {
      Console.WriteLine("Preparing " + this.name);
      dough = ingredientFactory.createDough();
      sauce = ingredientFactory.createSauce();
      cheese = ingredientFactory.createCheese();
     }
}
 
 
// Define other methods and classes here
public abstract class Pizza
{
protected string name;
protected Dough dough;
protected Sauce sauce;
protected List<Veggies> veggies;
protected Cheese cheese;
protected Pepperoni pepperoni;
protected Clams clam;
 
public abstract void prepare();
    
public void bake()
    {
    Console.WriteLine("Bake for 25 minutes at 350");
    }//bake
    
public void cut()
    {
      Console.WriteLine("Cutting the pizza into diagonal slices");
    }//cut
    
public void box()
    {
      Console.WriteLine("Place piza in official PizzaStore box");
    }//box
    
public string Name
    {
    get
        {
        return name;
        }
    set
        {
        name = value;
        }
    }//property: Name
 
    public override string ToString()
    {
        return name;
    }
}
    
public class NYStyleCheesePizza: Pizza
{
    private PizzaIngredientFactory ingredientFactory;
    public NYStyleCheesePizza(PizzaIngredientFactory ingredientFactory)
    {
        this.ingredientFactory = ingredientFactory;
        }
 
    public  override  void prepare()
    {
        Console.WriteLine("Preparing " + name);
        dough = ingredientFactory.createDough();
        sauce = ingredientFactory.createSauce();
        cheese = ingredientFactory.createCheese();
    }
    }//class: NYStyleCheesePizza
    
public abstract class PizzaStore
{
  public Pizza orderPizza(string type)
    {
    Pizza pizza;
    
    pizza = createPizza(type);
    
    pizza.prepare();
    pizza.bake();
    pizza.cut();
    pizza.box();
    
    return pizza;
    }
    
    protected abstract Pizza createPizza(string type);
}//class: PizzaStore
 
public class NYPizzaStore: PizzaStore
{
    protected override Pizza createPizza(string item)
    {
      Pizza pizza = null;
      PizzaIngredientFactory ingredientFactory = new NYPizzaIngredientFactory();
    if (item.Equals("cheese"))
    {
     pizza = new NYStyleCheesePizza(ingredientFactory);
     pizza.Name = "New York Style Cheese Pizza";
        return pizza;
    }//if
    else
    {
      return null;
    }//else
    }
}//class: NYPizzaStore

 

 

No comments:

Post a Comment