1、概念
定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法是一个类的实例化延伸到子类。
2、背景
已经知道工厂模式,有一个父类SuperClass,以及这个父类的不同实现方法和算法的若干个子类ClassA,ClassB... ...,有一个工厂类DAOFactory,根据客户端传来的标识决定调用哪个子类。如下:
- using System;
- using System.Collections.Generic;
- using System.Text;
- namespace FactoryPattern
- {
- public abstract class SuperClass
- {
- public abstract void GetResult();
- }
- public class ClassA:SuperClass
- {
- public override void GetResult()
- {
- Console.WriteLine("A类对GetResult()的实现。");
- }
- }
- public class ClassB : SuperClass
- {
- public override void GetResult()
- {
- Console.WriteLine("B类对GetResult()的实现。");
- }
- }
- public class DAOFactory
- {
- static SuperClass super;
- public static SuperClass CreateSuperClass(string type)
- {
- switch (type)
- {
- case "A":
- super = new ClassA();
- break;
- case "B":
- super = new ClassB();
- break;
- default:
- break;
- }
- return super;
- }
- }
- }
客户端
- using System;
- using System.Collections.Generic;
- using System.Text;
- namespace FactoryPattern
- {
- class Program
- {
- static void Main(string[] args)
- {
- SuperClass sup;
- sup = DAOFactory.CreateSuperClass("A");
- sup.GetResult();
- sup = DAOFactory.CreateSuperClass("B");
- sup.GetResult();
- Console.ReadLine();
- }
- }
- }
结果
可以看出,简单工厂模式是把到底实例化哪个类的逻辑放在工厂里判断,客户端不需要知道调用的哪个类,只关心结果就可以了。但是这里有一个问题,如果需求有了变化。那么就要增加新的类ClassC,ClassD… … 增加类不影响程序是可行的,但工厂类中的switch分支要不断地加,也就是要不断修改DAOFactory类,不符合开放封闭原则(程序实体可以扩展,但不被修改)。那么如何解决?
3、工厂方法模式
根据问题,可以有这样的方案,类ClassC,ClassD照常增加,但是需要修改工厂类。
- using System;
- using System.Collections.Generic;
- using System.Text;
- namespace FactoryPattern
- {
- public abstract class SuperClass
- {
- public abstract void GetResult();
- }
- public class ClassA:SuperClass
- {
- public override void GetResult()
- {
- Console.WriteLine("A类对GetResult()的实现。");
- }
- }
- public class ClassB : SuperClass
- {
- public override void GetResult()
- {
- Console.WriteLine("B类对GetResult()的实现。");
- }
- }
- public class ClassC : SuperClass
- {
- public override void GetResult()
- {
- Console.WriteLine("C类对GetResult()的实现。");
- }
- }
- public class ClassD : SuperClass
- {
- public override void GetResult()
- {
- Console.WriteLine("D类对GetResult()的实现。");
- }
- }
- public interface IFactory
- {
- SuperClass CreateSuperClass();
- }
- public class AFactory : IFactory
- {
- public SuperClass CreateSuperClass()
- {
- return new ClassA();
- }
- }
- public class BFactory : IFactory
- {
- public SuperClass CreateSuperClass()
- {
- return new ClassB();
- }
- }
- public class CFactory : IFactory
- {
- public SuperClass CreateSuperClass()
- {
- return new ClassC();
- }
- }
- public class DFactory : IFactory
- {
- public SuperClass CreateSuperClass()
- {
- return new ClassD();
- }
- }
- }
客户端
- using System;
- using System.Collections.Generic;
- using System.Text;
- namespace FactoryPattern
- {
- class Program
- {
- static void Main(string[] args)
- {
- IFactory factory;
- SuperClass sup;
- factory = new CFactory();
- sup = factory.CreateSuperClass();
- sup.GetResult();
- factory = new DFactory();
- sup = factory.CreateSuperClass();
- sup.GetResult();
- Console.ReadLine();
- }
- }
- }
结果
这样,解决了修改分支的问题。但是把选择交给了客户端,需要客户端自己判断到底需要调用哪个类实现,如果需求变化客户端就需要修改。事物都是具有两面性的,因此到底使用哪种模式还需要在程序中视情况而定。