163  
查询码:00000167
简单工厂模式&工厂方法模式&抽象工厂模式的区别及优缺点及使用场景
来源:https://blog.csdn.net/auuea/article/details/84673570
作者: 朱凡 于 2021年02月11日 发布在分类 / FM组 / FM_App 下,并于 2021年02月11日 编辑
工厂 模式 抽象 方法 简单 厂方 鼠标 public 创建 实现

简单工厂模式&工厂方法模式&抽象工厂模式的区别及优缺点及使用场景


简单工厂模式&工厂方法模式&抽象工厂模式的区别及优缺点及使用场景

  • 简单工厂
    • 普通简单工厂
    • 多方法简单工厂
    • 静态方法简单工厂
  • 工厂方法模式
  • 抽象工厂模式

工厂模式是设计模式中比较简单的一个设计模式,但很多地方都用到了工厂模式,(如解析xml中,jdbc连接数据库等)利用好工厂模式对程序的设计很有用处。

工厂模式在一些设计模式的书中分为简单工厂模式,工厂方法模式和抽象工厂模式三类。也有把工厂方法模式划分到抽象工厂模式的,认为工厂方法是抽象工厂模式的特例的一种,就是只有一个要实现的产品接口。
在这里插入图片描述

简单工厂

普通简单工厂

就是建立一个工厂类,对实现了同一接口的一些类进行实例的创建。首先看下关系图

举个获取鼠标信息例子,我们有个例子。

  1. 创建获取鼠标信息共同接口
public class LenoveMouse : IMouse
  {
    public string GetMouseInfo()
    {
      return "联想品牌鼠标";
    }
  }
  1. 联想鼠标实现类
public string GetMouseInfo()
    {
      return "联想品牌鼠标";
    }

3.惠普鼠标实现类

public class HPMouse : IMouse
  {
    public string GetMouseInfo()
    {
      return "惠普品牌鼠标";
    }
  }
  1. 鼠标工厂类
public class MouseFactory
  {
    /// <param name="type">0 代码惠普鼠标 1 代码联想鼠标</param>
    /// <returns></returns>
    public IMouse GetMouse(int type)
    {
      if (type == 0)
      {
        return new HPMouse();
      }
      else if (type == 1)
      {
        return new LenoveMouse();
      }
      else {

        Console.WriteLine("请输入正确类型!");
        return null;
      }
    }
  }
  1. 控制台调用
class Program
  {
    static void Main(string[] args)
    {
      MouseFactory mouseFactory = new MouseFactory();
      string mouseInfo1 = mouseFactory.GetMouse(0).GetMouseInfo();
      Console.WriteLine(mouseInfo1);
      // 输出:惠普品牌鼠标
      string mouseInfo2 = mouseFactory.GetMouse(1).GetMouseInfo();
      Console.WriteLine(mouseInfo2);
      //输出:联想品牌鼠标
    }
  }

多方法简单工厂

是对普通工厂方法模式的改进,在普通工厂方法模式中,如果传递的类型出错,则不能正确创建对象,而多个工厂方法模式是提供多个工厂方法,分别创建对象。关系图:
在这里插入图片描述
工厂类修改

public class MouseFactory
  {

    public IMouse GetHPMouse()
    {
      return new HPMouse();
    }

    public IMouse GetMouse()
    {
      return new LenoveMouse();
    }

  }

控制台调用修改

class Program
  {
    static void Main(string[] args)
    {
      MouseFactory mouseFactory = new MouseFactory();
      string mouseInfo1 = mouseFactory.GetHPMouse().GetMouseInfo();
      //输出惠普鼠标品牌
      Console.WriteLine(mouseInfo1);     
      string mouseInfo2 = mouseFactory.GetLenoveMouse().GetMouseInfo();
      //输出联想鼠标品牌
      Console.WriteLine(mouseInfo2);
      Console.ReadLine();
    }
  }

静态方法简单工厂

将上面的多个工厂方法模式里的方法置为静态的,不需要创建实例,直接调用即可。

public class MouseFactory
  {

    public static IMouse GetHPMouse()
    {
      return new HPMouse();
    }

    public static IMouse GetLenoveMouse()
    {
      return new LenoveMouse();
    }

  }

控制台调用

class Program
  {
    static void Main(string[] args)
    {     
      string mouseInfo1 = MouseFactory.GetHPMouse().GetMouseInfo();
      //输出惠普鼠标品牌
      Console.WriteLine(mouseInfo1);     
      string mouseInfo2 = MouseFactory.GetLenoveMouse().GetMouseInfo();
      //输出联想鼠标品牌
      Console.WriteLine(mouseInfo2);
      Console.ReadLine();
    }
  }

工厂方法模式

简单工厂模式有一个问题就是,类的创建依赖工厂类,也就是说,如果想要拓展程序,必须对工厂类进行修改。假如增加其他品牌鼠标,工厂类需要修改,如何解决?就用到工厂方法模式,创建一个工厂接口和创建多个工厂实现类,这样一旦需要增加新的功能,直接增加新的工厂类就可以了,不需要修改之前的代码。
在这里插入图片描述
增加Factory接口

public interface Factory
  {
    /// <summary>
    /// 获取鼠标工厂
    /// </summary>
    /// <returns></returns>
     IMouse GetMouseFactory();

  }

添加惠普鼠标工厂实现类

public class HPMouseFactory:Factory
  {
    public IMouse GetMouseFactory()
    {
      return new HPMouse();
    }
  }

添加联想鼠标工厂实现类

public class LenoveMouseFactory : Factory
  {
    public IMouse GetMouseFactory()
    {
      return new LenoveMouse();
    }
  }

控制台调用

在这里插入代码片
class Program
{
  static void Main(string[] args)
  {
    //实例化惠普鼠标工厂
    Factory factory = new HPMouseFactory();
    string mouseInfo1 = factory.GetMouseFactory().GetMouseInfo();
    //输出惠普鼠标品牌
    Console.WriteLine(mouseInfo1);
    //实例化联想鼠标工厂
    Factory factory2 = new LenoveMouseFactory();
    string mouseInfo2 = factory2.GetMouseFactory().GetMouseInfo();
    //输出联想鼠标品牌
    Console.WriteLine(mouseInfo2);
    Console.ReadLine();
  }
}
工厂方法模式中我们把生成产品类的时间延迟,就是通过对应的工厂类来生成对应的产品类,在这里我们就可以实现“开发-封闭”原则,无论加多少产品类,我们都不用修改原来类中的代码,而是通过增加工厂类来实现。但是这还是有缺点的,如果添加键盘产品,就需要添加键盘工厂类。假如我们要实现的产品接口不止一个,也就是有多个产品接口,不同产品接口有对应的产品族。什么是产品族呢?简单的理解就是,不同厂家的不仅有鼠标,还有键盘,音响,笔记本可以组成一个产品族。对于这种情况我们可以采用抽象工厂模式。

抽象工厂模式

最后我们新增一个键盘产品类说明抽象工厂模式
在这里插入图片描述

  1. 创建获取鼠标信息共同接口
public class LenoveMouse : IMouse
  {
    public string GetMouseInfo()
    {
      return "联想品牌鼠标";
    }
  }
  1. 联想鼠标实现类
public string GetMouseInfo()
    {
      return "联想品牌鼠标";
    }

3.惠普鼠标实现类

public class HPMouse : IMouse
  {
    public string GetMouseInfo()
    {
      return "惠普品牌鼠标";
    }
  }

4.创建键盘接口类

public interface IKeyboard
  {
     string GetKeyboardInfo();  
  }

5.创建惠普键盘实现类

public class HPKeyboard : IKeyboard
  {
    public string GetKeyboardInfo()
    {
      return "惠普键盘";
    }
  }

6.创建联想键盘实现类

public class LenoveKeyboard : IKeyboard
  {
    public string GetKeyboardInfo()
    {
      return "联想键盘";
    }
  }

7.创建工厂接口类提供获取鼠标鼠标和键盘接口

public interface Factory
  {
    /// <summary>
    /// 获取鼠标工厂
    /// </summary>
    /// <returns></returns>
     IMouse GetMouseFactory();
    /// <summary>
    /// 获取键盘工厂
    /// </summary>
    /// <returns></returns>
    IKeyboard GetKeyboardFactory();

  }

8.创建联想工厂实现类

public class LenoveFactory : Factory
  {
    public IKeyboard GetKeyboardFactory()
    {
      return new LenoveKeyboard();
    }

    public IMouse GetMouseFactory()
    {
      return new LenoveMouse();
    }
  }

9.创建惠普工厂实现类型

public class HPFactory:Factory
  {
    public IKeyboard GetKeyboardFactory()
    {
      return new HPKeyboard();
    }

    public IMouse GetMouseFactory()
    {
      return new HPMouse();
    }
  }

控制台调用

class Program
  {
    static void Main(string[] args)
    {
      //实例化惠普鼠标工厂
      Factory factory = new HPFactory();
      string mouseInfo1 = factory.GetMouseFactory().GetMouseInfo();
      string keyboard1 = factory.GetKeyboardFactory().GetKeyboardInfo();

      //输出惠普鼠标品牌
      Console.WriteLine(mouseInfo1);
      //输出惠普键盘
      Console.WriteLine(keyboard1);
      //实例化联想鼠标工厂
      Factory factory2 = new LenoveFactory();
      string mouseInfo2 = factory2.GetMouseFactory().GetMouseInfo();
      //输出联想鼠标品牌
      Console.WriteLine(mouseInfo2);
      //输出联想键盘品牌
      string keyboard2= factory2.GetKeyboardFactory().GetKeyboardInfo();
      Console.ReadLine();
    }
  }

抽象工厂模式中我们可以定义实现不止一个接口,一个工厂也可以生成不止一个产品类,抽象工厂模式较好的实现了“开放-封闭”原则,是三个模式中较为抽象,并具一般性的模式。我们在使用中要注意使用抽象工厂模式的条件。
无论是工厂模式增加代码复制度,有没有一种办法,不需要创建工厂,也能解决代码以后变动修改少方法。答案是有的,通过(ioc)控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体,将其所依赖的对象的引用传递给它。也可以说,(di)依赖被注入到对象中。




 推荐知识

 历史版本

修改日期 修改人 备注
2021-02-11 22:50:27[当前版本] 朱凡 创建版本

 附件

附件类型

JPGJPG

知识分享平台 -V 4.8.7 -wcp