【设计模式】创建型模式之工厂方法模式(二)

工厂方法模式

首先我们回顾一下,上一篇文章:创建型模式之简单工厂模式,简单工厂模式的最大优点在于工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类,对于客户端来说,去除了与具体产品的依赖。可以理解为,客户端不用管用哪个类的实例,只需要把对应的“参数”给工厂,由工厂给出相应的实例。如果我们还需要其他的逻辑判断,这时候我们就需要改“工厂”类,这时候对扩展开放了,对修改也开放了,这就违背了“开放-封闭原则”。

于是就有了“工厂方法模式”

  1.工厂方法模式(Factory Method),定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。

这句话我们该怎么理解呢?

  1. 对工厂类进行抽象,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。

还不理解?

  总体而言:把工厂抽象成父类。新的产品(新增的类),继承抽象工厂类。实现具体的功能,而客户端只需要知道新增产品的类名,即可完成实例化,并且进行调用。而不需要调整工厂内部结构,结合文章中的代码进行深入了解。

角色结构

  • 抽象工厂(Creator)角色:是工厂方法模式的核心,与应用程序无关。任何在模式中创建的对象的工厂类必须实现这个接口。
  • 具体工厂(Concrete Creator)角色:这是实现抽象工厂接口的具体工厂类,包含与应用程序密切相关的逻辑,并且受到应用程序调用以创建产品对象。
  • 抽象产品(Product)角色:工厂方法模式所创建的对象的超类型,也就是产品对象的共同父类或共同拥有的接口。
  • 具体产品(Concrete Product)角色:这个角色实现了抽象产品角色所定义的接口。某具体产品有专门的具体工厂创建,它们之间往往一一对应。

 

举个例子:大话设计模式种,学雷锋

雷锋需要做的事情

 1     //雷锋
 2     class LeiFeng
 3     {
 4         public void Sweep()
 5         {
 6             Console.WriteLine("扫地");
 7         }
 8 
 9         public void Wash()
10         {
11             Console.WriteLine("洗衣");
12         }
13 
14         public void BuyRice()
15         {
16             Console.WriteLine("买米");
17         }
18     }

学雷锋的大学生

1     //学雷锋的大学生
2     class Undergraduate : LeiFeng
3     {
4 
5     }

社区自愿者

1     //社区志愿者
2     class Volunteer : LeiFeng
3     {
4 
5     }

雷锋工厂

1     //雷锋工厂
2     interface IFactory
3     {
4         LeiFeng CreateLeiFeng();
5     }

学雷锋的大学生工厂

1     //学雷锋的大学生工厂
2     class UndergraduateFactory : IFactory
3     {
4         public LeiFeng CreateLeiFeng()
5         {
6             return new Undergraduate();
7         }
8     }

社区志愿者工厂

1     //社区志愿者工厂
2     class VolunteerFactory : IFactory
3     {
4         public LeiFeng CreateLeiFeng()
5         {
6             return new Volunteer();
7         }
8     }

简单工厂模式【方便与工厂方法进行对比】

 1     //简单雷锋工厂
 2     class SimpleFactory
 3     {
 4         public static LeiFeng CreateLeiFeng(string Type)
 5         {
 6             LeiFeng result = null;
 7             switch (Type)
 8             {
 9                 case "学雷锋的大学生":
10                     result = new Undergraduate();
11                     break;
12                 case "社区志愿者":
13                     result = new Volunteer();
14                     break;
15                 default:
16                     break;
17             }
18             return result;
19         }
20     }

实现具体类

 1     class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             /*简单工厂模式
 6              * 工厂类进行区分使用哪个一个功能类,
 7              * 如果需要添加新的功能类,则需要改动工厂类、客户端只需要传递对应的功能到工厂,即可达到对应的功能
 8              * 违反了面向对象的开闭原则
 9              */
10             Console.WriteLine("/*简单工厂模式*/");
11             LeiFeng studentA = SimpleFactory.CreateLeiFeng("学雷锋的大学生");
12             studentA.BuyRice();
13             LeiFeng studentB = SimpleFactory.CreateLeiFeng("学雷锋的大学生");
14             studentB.Sweep();
15             LeiFeng studentC = SimpleFactory.CreateLeiFeng("学雷锋的大学生");
16             studentC.Wash();
17 
18 
19             /*工厂模式
20              * 添加工厂接口类、具体的工厂继承抽象工厂类
21              * 如果添加新的工厂,则只需要继承抽象工厂类,并创建对应的工厂
22              * 这个时候需要由客户端来指定具体使用哪一个工厂,就需要调整客户端代码
23              * 后续可使用“反射”原因,避免这个问题
24              */
25             Console.WriteLine("/*工厂模式*/");
26             IFactory factory = new UndergraduateFactory();
27             LeiFeng student = factory.CreateLeiFeng();
28             student.BuyRice();
29             student.Sweep();
30             student.Wash();
31             Console.ReadLine();
32         }
33     }

输出结果

模式分析

优点:

  • 一个调用者想创建一个对象,只要知道其名称就可以了。
  • 遵守“开放-封闭原则”,扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。
  • 屏蔽产品的具体实现,调用者只关心产品的接口。

缺点:

  • 每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。

模式应用

调用者只需要知道具体的工厂类,生产对应的产品,而不需要也不想知道内部结构是如何组成。

文章参考:https://www.cnblogs.com/toutou/p/4899388.html

posted @ 2018-07-02 22:28  嗷大喵学编程  阅读(183)  评论(0)    收藏  举报