一、应用场景以及优缺点
1.应用场景:
一个类不知道它需要的对象的类。在工厂方法模式中,我们不需要具体产品的类名,我们只需要知道创建它的具体工厂即可。
一个类通过其子类来指定创建那个对象。在工厂模式中,对于抽象工厂类只需要提供一个创建产品的接口,而由其子类来确定具体要创建的对象,在程序运行中,子类对象将覆盖父类对象,从而使得系统更容易扩展。
将创建对象的任务委托给多个工厂子类中的某一个,客户端在使用时可以无须关心是那一个工厂子类创建产品子类,需要时再动态指定。
2.优点:
在工厂方法中,用户只需要知道所要产品的具体工厂,无须关系具体的创建过程,甚至不需要具体产品类的类名
在系统增加新的产品时,我们只需要添加一个具体产品类和对应的实现工厂,无需对原工厂进行任何修改,很好地符合了“开闭原则”。
3.缺点:
每次增加一个产品时,都需要增加一个具体类和对象实现工厂,是的系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。
二、模式的组成
抽象工厂角色(Creator): 充当抽象工厂角色,定义工厂类所具有的基本的操作,任何具体工厂都必须继承该抽象类。
具体工厂角色(ConcreteCreator):充当具体工厂角色,该类必须继承抽象工厂角色,实现抽象工厂定义的方法,用来创建具体产品。
抽象产品角色(Product):充当抽象产品角色,定义了产品类型所有具有的基本操作,具体产品必须继承该抽象类。
具体产品角色(ConcreteProduct):充当具体产品角色,实现抽象产品类对定义的抽象方法,由具体工厂类创建,它们之间有一一对应的关系。
三、代码实现:
【简单工厂模式】的问题是:如果有新的需求就需要修改工厂类里面创建产品对象实例的那个方法的实现代码,在面向对象设计一个原则就是哪里有变化,我就封装哪里。
还有另外两个大的原则,其一是:面向抽象编程,细节和高层实现都要依赖抽象,第二个原则是:多组合,少继承。这三个原则是最根本的原则,学习设计模式必须以这三个原则为基点,否则都是枉然。
根据这三大原则又衍生出来6个具体的原则,分别是【单一职责 原则】,【里氏替换原则】,【依赖倒置原则】,【接口隔离原则】、【迪米特法则】和【开闭原则】,
既然工厂类有变化,我们就封装它,面向抽象编程,我们先抽象出一个工厂基类,然后,每个需求就实现一个具体的工厂类,这样我们就符合了【开闭原则】,让一个工厂生产一款产品,并一一对应。
我们把具体产品的创建推迟到子类中,此时工厂类(这类是基类了)不再负责所有产品的创建,而只是给出具体工厂必须实现的接口,这样工厂方法模式就可以允许系统不修改工厂类逻辑的情况下来添加新产品,这样也就克服了简单工厂模式中缺点。
public ActionResult eFactory() { // 初始化创建汽车的两个工厂 Factory1 hongQiCarFactory = new HongQiCarFactory(); Factory1 aoDiCarFactory = new AoDiCarFactory(); // 生产一辆红旗汽车 Car hongQi = hongQiCarFactory.CreateCar(); hongQi.Go(); //生产一辆奥迪汽车 Car aoDi = aoDiCarFactory.CreateCar(); aoDi.Go(); return View(); }
/// <summary> /// 汽车抽象类 /// </summary> public abstract class Car { // 开始行驶 public abstract void Go(); } /// <summary> /// 红旗汽车 /// </summary> public class HongQiCar : Car { public override void Go() { Console.WriteLine("红旗汽车开始行驶了!"); } } /// <summary> /// 奥迪汽车 /// </summary> public class AoDiCar : Car { public override void Go() { Console.WriteLine("奥迪汽车开始行驶了"); } } /// <summary> /// 抽象工厂类 /// </summary> public abstract class Factory1 { // 工厂方法 public abstract Car CreateCar(); } /// <summary> /// 红旗汽车工厂类 /// </summary> public class HongQiCarFactory : Factory1 { /// <summary> /// 负责生产红旗汽车 /// </summary> /// <returns></returns> public override Car CreateCar() { return new HongQiCar(); } } /// <summary> /// 奥迪汽车工厂类 /// </summary> public class AoDiCarFactory : Factory1 { /// <summary> /// 负责创建奥迪汽车 /// </summary> /// <returns></returns> public override Car CreateCar() { return new AoDiCar(); } }
使用工厂方法实现的系统,如果系统需要添加新产品时,我们可以利用多态性来完成系统的扩展,对于抽象工厂类和具体工厂中的代码都不需要做任何改动。
/// <summary> /// 奔驰车 /// </summary> public class BenChiCar : Car { /// <summary> /// 重写抽象类中的方法 /// </summary> public override void Go() { Console.WriteLine("奔驰车开始行驶了!"); } } /// <summary> /// 奔驰车的工厂类 /// </summary> public class BenChiCarFactory : Factory { /// <summary> /// 负责生产奔驰车 /// </summary> /// <returns></returns> public override Car CreateCar() { return new BenChiCar(); } }