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

浙公网安备 33010602011771号