HeadFirst 设计模式--工厂模式

工厂模式

     定义一个创建对象的接口,由子类决定要实例化的类。工厂方法将类实例推迟到子类。依赖倒置。

     第一种方式是:

class PizzaStore
    {
        PizzaFactory pizzaFactory;
        public PizzaStore(PizzaFactory factory)
        {
            this.pizzaFactory = factory;
        }
        public Pizza orderPizza(String type)
        {
            Pizza pizza;
            pizza = pizzaFactory.CreatePizza(type);
            pizza.prepare();
            pizza.bake();
            pizza.cut();
            pizza.box();
            return pizza;
        }
  }
  class PizzaFactory
    {
        //Pizza orderPizza()
        //{
        //    Pizza pizza;
        //    Pizza pizza = new Pizza();//若Pizza为具体类?
        //    pizza.prepare();
        //    pizza.bake();
        //    pizza.cut();
        //    pizza.box();

        //    //若需要更多的种类,将要添加更多的代码        
        //}
        Pizza pizza = null;//将pizza这个实例提取出来,有利于后面的拓展
        public Pizza CreatePizza(String type)
        {
            if(type.Equals("Cheese"))
            {
                pizza = new ChessPizza();
            }
            else if (type.Equals("greek"))
            {
                pizza = new GreekPizza();
            }
            else if (type.Equals("pepperoni"))
            {
                pizza = new PepperoniponiPizza();
            }
            return pizza;
        }
    }

下面是其建模过程。


       在第一个过程中,PizzaFactory依赖于Pizza,这个时候,当你需要CheesePizza时,我们看看流程,PizzaStore中存有PizzaFactory的实例,通过PizzaFactory创建Pizza,所有的Pizza继承于Pizza基类,因此你可以任意的创建Pizza

    但是这种方式存在的不足是?

    如果添加一种新的类型,就必须到工厂中修改代码。

    由此,我们有下面改进方式

abstract class PizzaStroe2
    {
        public Pizza pizza;//创建者并不知道具体的类
        public PizzaStroe2()
        {
            pizza = null;
        }
        public Pizza orderPizza(String type)
        {
            pizza = CreatePizza(type);
            if (pizza!=null)
            {
                pizza.prepare();
                pizza.bake();
                pizza.cut();
                pizza.box();
            }
            return pizza;
        }
        public abstract Pizza CreatePizza(String type);//将创建Pizza的方法放入PizzaStore中,可以为不同的地区创建不同的子类。
                                                       //使用抽象用以继承,在调用的时候使用多态
    }


    class NYPizzaStore : PizzaStroe2
    {
        public override Pizza CreatePizza(String type)//因为或许每个Store的创建方式不一。因此将CreatePizza函数放入到PizzaStore类中
        {
            if (type.Equals("cheese"))
            {
                pizza = new NYStrleChessPizza();
            }
            else if (type.Equals("clams"))
            {
                pizza = new NYStyleClamPizza();
            }
            else if (type.Equals("pepperoni"))
            {
                pizza = new NYStylePepperoniPizza();
            }
            return pizza;
        }
    }
  abstract class Pizza
    {
        public String name;
        public String dough;
        public String sauce;
        protected ArrayList toppings = new ArrayList();


        public virtual void prepare()
        {
            Console.WriteLine("Prepareing " + name);
            Console.WriteLine("Tossing dough...");
            Console.WriteLine("Adding sauce...");
            Console.WriteLine("Adding topping:");
            foreach (String str in toppings)
            {
                Console.WriteLine(str);
            }
        }
        public virtual void bake()
        {
            Console.WriteLine("Bake for 25 minutes at 350");
        }
        public virtual void cut()
        {
            Console.WriteLine("Cutting the pizza into diagonal slice");
        }
        public virtual void box()
        {
            Console.WriteLine("Place pizza in offical PizzaStore box");
        }


        public virtual String getName()
        {
            return name;
        }
    }
 class NYStrleChessPizza : Pizza
    {
        public NYStrleChessPizza()
        {
            name = "NY Style and Cheese Pizza";
            dough = "Thin Crust Dough";
            sauce = "Marinara Sauce";
            toppings.Add("Grated Reggiano Cheese");
        }
        public override void prepare() 
        {
            Console.WriteLine("NY Style cheese preparing ");
        }
        public override void bake()
        {
            Console.WriteLine("NY Style cheese baking ");
        }
        public override void cut() 
        {
            Console.WriteLine("NY Style cheese cuting ");
        }
        public override void box() 
        {
              Console.WriteLine("NY Style cheese preparing ");
        }
    }



     主要的改进是丢弃掉了工厂,工厂主要的职责是创建pizza,提取出来之后,任意类型的Pizza创建属于自己的pizza,此时在Store中的创建为虚函数。个人想法是如果对Factory进行继承,拓展能够实现类似的功能。

看上去我们的代码已经能够实现对修改关闭,对拓展开放的原则,但是我们在创建的时候依旧存在着原料的制约。此时引入一个PizzaIngredientFactory

interface PizzaIngredientFactory
    {
         Dough CreateDough();
         Sauce CreateSauce();
         Cheese CreateCheese();
         Pepperoni CreatePepperoni();
         Clams CreateClam();
    }
    class Dough{}
    class Sauce{}
    class Cheese{}
    class Veggies { }
    class Clams { }
    class Pepperoni { }

    class FreshClams : Clams { }

    class NYPizzaIngresientFactory : PizzaIngredientFactory
    {
        public Dough CreateDough()
        {
            return new Dough();
        }
        public Sauce CreateSauce()
        {
            return new Sauce();
        }
        public Cheese CreateCheese() {
            return new Cheese();
        }
        public Pepperoni CreatePepperoni()
        {
            return new Pepperoni();
        }
        public Clams CreateClam()
        {
            return new FreshClams();//新地域对材料的改进
        }
    }
    abstract class NewPizza:Pizza
    {
        protected String name;
        protected Dough dough;//下面几个都是原材料,对于不同地区对原材料的处理不同.
        protected Sauce sauce;
        protected Cheese cheese;
        protected Pepperoni pepperoi;
        protected Clams clams;

        public abstract void prepare();

        public override void bake()
        {
            Console.WriteLine("Bake for 25 minutes at 350");
        }
        public override void cut()
        {
            Console.WriteLine("Cutting the pizza into digonal slices");
        }
        public override void box()
        {
            Console.WriteLine("Place pizza in offical PizzaStore box");
        }
        public void setName(String name)
        {
            this.name = name;
        }
        public override String getName()
        {
            return name;
        }
    }

    class CheesePizza : NewPizza
    {
        PizzaIngredientFactory ingredientFactory;//根据不同地区引入不同的处理方式的工厂
        public CheesePizza(PizzaIngredientFactory ingredientFactory)
        {
            this.ingredientFactory = ingredientFactory;
        }
        public override void prepare()
        {
            Console.WriteLine("Preparing " + name);
            dough = ingredientFactory.CreateDough();
            sauce = ingredientFactory.CreateSauce();
            cheese = ingredientFactory.CreateCheese();
        }
    }
    class ClamPizza : NewPizza
    {
        PizzaIngredientFactory ingredientFactory;
        public ClamPizza(PizzaIngredientFactory ingredientFactory)
        {
            this.ingredientFactory = ingredientFactory;
        }
        public override void prepare()
        {
            Console.WriteLine("Preparing " + name);
            dough = ingredientFactory.CreateDough();
            sauce = ingredientFactory.CreateSauce();
            clams = ingredientFactory.CreateClam();
        }

    }
    class NewNYPizzaStore : PizzaStroe2
    {
        public override Pizza CreatePizza(String type)
        {
            Pizza pizza;
            NewPizza newPizza = null;
            PizzaIngredientFactory ingredientFactory = new NYPizzaIngresientFactory();
            if (type.Equals("cheese"))
            {
                newPizza = new CheesePizza(ingredientFactory);
                newPizza.setName("New York Style Cheese Pizza");
            }
            else if (type.Equals("clams"))
            {
                newPizza = new ClamPizza(ingredientFactory);
                newPizza.setName("New York Style FreshClam Pizza");
            }
            return newPizza;
        }
    }


再次看看我们新的建模方式,对于不同的地区有不同的创建方式,此时已经不限于原材料的产地。通过抽象工厂提供的接口,可以创建产品的家族。


4、运行结果:

 static void Main(string[] args)
        {
            PizzaStroe2 nyPizzaStore = new NYPizzaStore();
            Pizza pizza = nyPizzaStore.orderPizza("cheese");
            Console.WriteLine("Camel ordered a " + pizza.getName());


            Console.WriteLine();
            PizzaStroe2  newNYPizzaStore = new NewNYPizzaStore();
            Pizza clamspizza = newNYPizzaStore.orderPizza("clams");


            Console.WriteLine("Camel ordered a " + clamspizza.getName());


            Console.ReadLine();


        }




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值