zoukankan      html  css  js  c++  java
  • 三种工厂模式

    三种工厂模式

    三种工厂模式

    简单工厂实现#

    简单工厂模式(严格来说这不算一种Gof的设计模式,更像是一种编程习惯)属于类的创建型模式,又叫做静态工厂方法模式。通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有相同的父类,应用继承将决定工厂的生产什么产品的决定权直接交到了客户手中,然后客户在输入自己的需求,得到最终的结果。

    运用简单工厂模式实现生产pizza的业务场景。

    Copy
    /// <summary>
    /// pizza创建工厂
    /// </summary>
    public class PizzaFactory
    {
         public static Pizza CreatePizza(string pizzaType)
         {
              switch (pizzaType)
              {
                   case "Cheese":
                   return new CheesePizza();
                   case "ApplePie":
                   return new ApplePiePizza();
                   default:
                   return new SomeOtherPizza();
              }
         }
    }
    public abstract class Pizza
    {
         public string Name { get; set; }
    
         public void Prepare()
         {
              Console.WriteLine($"Preparing {Name}");
              
         }
    
         public void Cut()
         {
              Console.WriteLine($"Cutting the {Name}");
         }
    
         public void Bake()
         {
              Console.WriteLine($"Baking the {Name}");
         }
    
         public void Box()
         {
              Console.WriteLine($"Boxing the {Name}");
         }
    }
    
    public class ApplePiePizza : Pizza
    {
         public ApplePiePizza()
         {
              Name = "ApplePie";
         }
    }
    
    public class CheesePizza : Pizza
    {
         public CheesePizza()
         {
              Name = "Cheese";
         }
    }
    
    public class SomeOtherPizza : Pizza
    {
         public SomeOtherPizza()
         {
              Name = "Other";
         }
    }
    //调用
    class Program
    {
         static void Main(string[] args)
         {
              Pizza pizza = PizzaFactory.CreatePizza("cheese");
              pizza.Box();
         }
    }
    //输出:
    //Preparing Cheese
    //Cutting the Cheese
    //Baking the Cheese
    //Boxing the Cheese

    简单工厂模式实现了生成Pizza类的代码跟客户端代码分离,在工厂类中你可以添加所需的生成Pizza的逻辑代码,但是,简单工厂并不符合“开放-封闭”原则(对扩展开放,对修改关闭),如果要加一种类型VeggiePizza,你就要修改工厂类里面的生成产品的代码,在这里你就要增加Swich-Case。对于这个问题,我们的工厂方法模式就可以解决这个问题。

    工厂模式#

    运用工厂模式实现生产pizza的业务场景。

    Copy
    /// <summary>
    /// 工厂接口
    /// </summary>
    interface IFactory
    {
         Pizza CreatePizza();
    }
    /// <summary>
    /// CheesePizza工厂方法
    /// </summary>
    public class CheesePizzaFactory : IFactory
    {
         public Pizza CreatePizza()
         {
              return new CheesePizza();
    
         }
    }
    /// <summary>
    /// ApplePiePizza工厂方法
    /// </summary>
    public class ApplePiePizzaFactory : IFactory
    {
         public Pizza CreatePizza()
         {
              return new ApplePiePizza();
         }
    }
    class Program
    {
         static void Main(string[] args)
         {
              IFactory factory = new CheesePizzaFactory();
              Pizza cheesePizza = factory.CreatePizza();
              cheesePizza.Prepare();
              cheesePizza.Cut();
              cheesePizza.Bake();
              cheesePizza.Box();
              //输出:
              //Preparing Cheese
              //Cutting the Cheese
              //Baking the Cheese
              //Boxing the Cheese
         }
    }

    工厂模式中我们通过对应的工厂类来生成对应的Pizza,在这里符合“开闭”原则,无论加多少Pizza类,我们都不用修改原来类中的代码,而是通过增加工厂类来实现。但是这还是有缺点的,如果产品Pizza类过多,我们就要生成很多的工厂类。假如我们要实现的产品接口不止一个,也就是有多个产品接口,不同产品接口有对应的产品族。什么是产品族呢?简单的理解就是,不同类型的Pizza会在不同的地区会有不同的准备方式,以材料(面团Dough,果酱Sauce)的不同而变幻口味等,同地区不同类型的Pizza可以组成一个产品族。对于这种情况我们可以采用抽象工厂模式。

    抽象工厂模式#

    运用工厂模式实现生产pizza的业务场景。

    Copy
    /// <summary>
    /// 面团
    /// </summary>
    public interface Dough
    {
         void Dough();
    }
    /// <summary>
    /// 纽约面团
    /// </summary>
    public class NYDough : Dough
    {
         public void Dough()
         {
              Console.WriteLine("NYDough");
         }
    }
    /// <summary>
    /// 芝加哥面团
    /// </summary>
    public class ChicagoDough : Dough
    {
         public void Dough()
         {
              Console.WriteLine("ChicagoDough");
         }
    }
    /// <summary>
    /// 果酱
    /// </summary>
    public interface Sauce
    {
         void Sauce();
    }
    /// <summary>
    /// 纽约果酱
    /// </summary>
    public class NYSauce : Sauce
    {
         public void Sauce()
         {
              Console.WriteLine("NYSauce");
         }
    }
    /// <summary>
    /// 芝加哥果酱
    /// </summary>
    public class ChicagoSauce : Sauce
    {
         public void Sauce()
         {
              Console.WriteLine("ChicagoSauce");
         }
    }
    /// <summary>
    /// 建造披萨原料工厂 接口
    /// </summary>
    public interface IPizzaIngredientFactory
    {
         Dough CreateDough();
         Sauce CreateSauce();
    }
    /// <summary>
    /// 纽约披萨工厂
    /// </summary>
    public class NYPizzaIngredientFactory : IPizzaIngredientFactory
    {
         public Dough CreateDough()
         {           
              return new NYDough();
         }
         public Sauce CreateSauce()
         {
              return new NYSauce();
         }
    }
    /// <summary>
    /// 芝加哥披萨工厂
    /// </summary>
    public class ChicagoPizzaIngredientFactory : IPizzaIngredientFactory
    {
         public Dough CreateDough()
         {
              return new ChicagoDough();
         }
         public Sauce CreateSauce()
         {
              return new ChicagoSauce();
         }
    }
    public abstract class Pizza
    {
         public string Name { get; set; }
         /// <summary>
         /// 面团
         /// </summary>
         public Dough Dough { get; set; }
         /// <summary>
         /// 酱汁
         /// </summary>
         public Sauce Sauce { get; set; }
    
         public abstract void Prepare();
    
    
         public void Cut()
         {
              Console.WriteLine($"Cutting the {Name}");
         }
    
         public void Bake()
         {
              Console.WriteLine($"Baking the {Name}");
         }
    
         public void Box()
         {
              Console.WriteLine($"Boxing the {Name}");
         }
    }
    public class ApplePiePizza : Pizza
    {
         IPizzaIngredientFactory _pizzaIngredientFactory;
         public ApplePiePizza(IPizzaIngredientFactory pizzaIngredient)
         {
              this._pizzaIngredientFactory = pizzaIngredient;
              Name = "ApplePie";
         }
    
         public override void Prepare()
         {
              Console.WriteLine($"Preparing { Name}");
              Dough = _pizzaIngredientFactory.CreateDough();
              Dough.Dough();
              Sauce = _pizzaIngredientFactory.CreateSauce();
              Sauce.Sauce();
         }
    }
    public class CheesePizza : Pizza
    {
         IPizzaIngredientFactory _pizzaIngredientFactory;
         public CheesePizza(IPizzaIngredientFactory pizzaIngredient)
         {
              this._pizzaIngredientFactory = pizzaIngredient;
              Name = "Cheese";
         }
    
         public override void Prepare()
         {
              Console.WriteLine($"Preparing { Name}");
              Dough = _pizzaIngredientFactory.CreateDough();
              Dough.Dough();
              Sauce = _pizzaIngredientFactory.CreateSauce();
              Sauce.Sauce();
         }
    }
    public class SomeOtherPizza : Pizza
    {
         public SomeOtherPizza()
         {
              Name = "Other";
         }
    
         public override void Prepare()
         {
              throw new NotImplementedException();
         }
    }
    // <summary>
    /// 工厂接口
    /// </summary>
    interface IFactory
    {
         Pizza CreatePizza(IPizzaIngredientFactory pizzaIngredientFactory);
    }
    /// <summary>
    /// CheesePizza工厂方法
    /// </summary>
    public class CheesePizzaFactory : IFactory
    {
         public Pizza CreatePizza(IPizzaIngredientFactory pizzaIngredientFactory)
         {
              return new CheesePizza(pizzaIngredientFactory);
    
         }
    }
    
    /// <summary>
    /// ApplePiePizza工厂方法
    /// </summary>
    public class ApplePiePizzaFactory : IFactory
    {
         public Pizza CreatePizza(IPizzaIngredientFactory pizzaIngredientFactory)
         {
              return new ApplePiePizza(pizzaIngredientFactory);
         }
    }
    //调用
    class Program
    {
         static void Main(string[] args)
         {
              IPizzaIngredientFactory pizzaIngredientFactory = new NYPizzaIngredientFactory();
              IFactory factory = new CheesePizzaFactory();
              Pizza cheesePizza = factory.CreatePizza(pizzaIngredientFactory);
              cheesePizza.Prepare();
              cheesePizza.Cut();
              cheesePizza.Bake();
              cheesePizza.Box();
              //输出:
              //Preparing Cheese
              //NYDough
              //NYSauce
              //Cutting the Cheese
              //Baking the Cheese
              //Boxing the Cheese
         }
    }

    总结#

    简单工厂优点#

    • 实现了对象创建和使用的分离,调用者可以免除直接创建产品对象的职责,而仅仅"消费"产品。
    • 调用者无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的的参数即可。

      简单工厂缺点#

    • 工厂类集中了所有产品的创建逻辑,职责过重,一旦不能正常工作,整个系统都要受影响。
    • 系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,在产品类型较多时,有可能会造成工厂逻辑过于复杂,不利于系统的扩展和维护。

    工厂优点#

    • 工厂方法用于创建客户所需要的产品,还向客户隐藏了哪种具体产品类将被实例化这一细节。因此,用户只需要关心所需产品对应的工厂,无须关心创建细节。
    • 在系统中加入新产品时,无需修改抽象工厂和抽象产品提供的接口,也无须修改客户端,还无须修改其他的具体工厂和具体产品,而只要加入一个具体工厂和具体产品就可以了。因此,系统的可扩展性得到了保证,符合开闭原则。

      工厂缺点#

    • 在添加新产品时,需要编写新的具体产品类,还要提供与之对应的具体工厂类,系统中类的个数将成对增加,一定程度上增加了系统的复杂度。
    • 由于考虑到系统的可扩展性,需要引入抽象层,且在实现时可能需要用到反射等技术,增加了系统的实现难度。

    抽象工厂优点#

    • 隔离了具体类的生成,使得客户并不需要知道什么被创建。因为这种隔离,因此更换一个具体工厂就变得相对容易。
    • 当一个产品族中的多个对象被设计称一起工作时,它能够保证客户端始终只使用同一个产品族中的对象。
    • 增加新的产品族很方便,无需修改已有系统,符合开闭原则。

      抽象工厂缺点#

    • 增加新的产品等级结构因为需要对原有系统进行较大的修改,甚至需要修改抽象层代码,这必然会带来较大的不便,在这个角度,它违背了开闭(对扩展开放,对修改封闭)原则。

    下载源码

  • 相关阅读:
    【洛谷P1297】单选错位【期望】
    【洛谷P1297】单选错位【期望】
    【POJ1201】Intervals【差分约束】
    【POJ1201】Intervals【差分约束】
    【洛谷P3275】糖果【差分约束】【负环】
    【洛谷P3275】糖果【差分约束】【负环】
    【洛谷P1768】天路【负环】【二分】【数论】
    【洛谷P1768】天路【负环】【二分】【数论】
    【JZOJ4256】平均数【二分】
    【JZOJ4256】平均数【二分】
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/11144762.html
Copyright © 2011-2022 走看看