设计模式:三种工厂模式

三种工厂模式

简单工厂实现

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

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

/// <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的业务场景。

/// <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的业务场景。

/// <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
     }
}

总结

简单工厂优点

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

    简单工厂缺点

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

工厂优点

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

    工厂缺点

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

抽象工厂优点

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

    抽象工厂缺点

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

下载源码

原文地址:https://www.cnblogs.com/RenshuozZ/p/11129820.html

时间: 2024-08-26 06:29:46

设计模式:三种工厂模式的相关文章

设计模式—三种工厂模式(JAVA)

一:简单工厂: 有一个实际工厂,这个工厂只能造一类的产品,这一类产品就是一个产品接口,会有多个具体产品实现这个接口,例 如,一个手机厂,生产苹果手机,三星手机: 缺点:在工厂类中集中了所有实例的创建逻辑,违反了高内聚责任分配原则,将全部创建逻辑集中到了一个工厂类中:对系统的维护和扩展不利: 使用场景:负责创建的对象比较少:客户只知道传入工厂类的参数,对于如何创建对象的逻辑不关心:容易违反高内聚责任分配原则,所以只在很简单的情况下应用: package com.designPattern.simp

设计模式看书笔记(5) - 三种工厂模式比较

先看三种工厂模式部分主要代码(完整代码在前三篇博客): 简单工厂模式: public class SampleFactory { public static Animal createAnimal(String animalName){ if("Tiger".equals(animalName))){ return new Triger(); }else if("Dolphin".equals(animalName)){ return new Dolphin();

设计模式三—抽象工厂模式

设计模式三-抽象工厂模式 一.定义 抽象工厂模式是工厂方法模式的进一步抽象.如果产品簇中只有一种产品,则退化为工厂方法模式. 二.原理图 三.代码实例 * 苹果和土豆是园丁1的杰作 * 葡萄和西红柿是园丁2的杰作 1.Fruit.java public interface Fruit { /* * 生长 * 收获 * 栽种 */ public void grow(); public void harvest(); public void plant(); } 2.Apple.java publi

高级特性 三种工厂模式

简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一.简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例.简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现. 是通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类. 我们从一个实例展开 现在有一道面试题:使用java实现一个计算机控制台程序,要求输入数的运算,得到结果. 这道题目最原始的写法: publi

设计模式之三种工厂模式

简单工厂模式 简单工厂模式其实不是一个设计模式,反而比较像一种编程习惯.主要我们定义一个非常简单的类主要负责帮我们生产不同的产品.类图如下: 客户端通过简单工厂可以生产出具体产品A,具体产品B,具体产品C. 简单工厂: package my.oschina.net.design.factory; public class SimplePizzaFactory { /** * 根据传入的type参数,返回相应的pizza * @param type * @return */ public Pizz

三种工厂模式

一.简单工厂 对象的创建方式有很多,常用new来创建.但是这种做法在一些情况下,有很多不好的地方.比如创建操作散落在代码的多处.对象的创建职责和使用职责混合到一起等等.简单工厂可以一定程度上解决该问题.通常的做法是对被创建的多个类进行抽象,将公共成员和方法放到抽象类中.不同的类继承抽象类,对细节进行不同的实现.然后创建一个工厂类,将类实例化的操作封装到工厂类的静态工厂方法中,通过不同的参数来创建不同类的对象. 还有一种简化的做法是,将静态工厂方法放到实体类的公共抽象父类中. 优点: 对象的创建和

深入理解Java的三种工厂模式

一.简单工厂模式 简单工厂的定义:提供一个创建对象实例的功能,而无须关心其具体实现.被创建实例的类型可以是接口.抽象类,也可以是具体的类 实现汽车接口 1 public interface Car { 2 String getName(); 3 } 奔驰类 1 public class Benz implements Car { 2 @Override 3 public String getName() { 4 return "Benz"; 5 } 6 } 宝马类 1 public c

C++ 三种工厂模式

工厂模式是将带有继承于基类的子类的创建过程交于一个工厂来创建,通过赋予不同的创建标识来创建不同的子类. 基于自己的理解和使用这里巩固一下工厂模式. 我们的项目目前使用最多的是简单工厂模式,不过其他两种模式:工厂模式和抽象工厂模式都是由简单工厂模式改进而来, 也很容易使用. 话不多说:见代码 一.简单工厂模式: 操作类: 接口类:CReadDocumentShowHandler,三个具体类:CReadWordShowHandler,CReadPdfShowHandler,CReadHtmlShow

java三种工厂模式

适用场合: 7.3 工厂模式的适用场合 创建新对象最简单的办法是使用new关键字和具体类.只有在某些场合下,创建和维护对象工厂所带来的额外复杂性才是物有所值.本节概括了这些场合. 7.3.1 动态实现 如果需要像前面自行车的例子一样,创建一些用不同方式实现同一接口的对象,那么可以使用一个工厂方法或简单工厂对象来简化选择实现的过程.这种选择可以是明确进行的也可以是隐含的.前者如自行车那个例子,顾客可以选择需要的自行车型号:而下一节所讲的XHR工厂那个例子则属于后者,该例中所返回的连接对象的类型取决