【原创】设计模式面对面之工厂模式
简单工厂模式
类图:
常用的实现方式:
产品
public abstract class Product { protected Product(){ } public virtual void Operation(){ Console.WriteLine("我是工厂生产所有产品"); } }//end Product
public class Care : Product { public Care(){ } public override void Operation(){ Console.WriteLine("我生产车!"); } }//end Care
public class Apple : Product { public Apple(){ } public override void Operation(){ Console.WriteLine("我产生苹果"); } }//end Apple
工厂
public class ProductFactory { public ProductFactory(){ } /// /// <param name="productName"></param> public Product Made(string productName) { Product product; switch (productName) { case nameof(Apple): { product= new Apple(); break; } case nameof(Care): { product = new Care(); break; } default: { product=new Apple(); break; } } return product; } }//end ProductFactory
调用
class Program { static void Main(string[] args) { var factory = new ProductFactory(); var car = factory.Made(nameof(Care)); car.Operation(); var apple = factory.Made(nameof(Apple)); apple.Operation(); Console.ReadLine(); } }
使用场景:
简单工厂模式产品工厂提供了一个制造产品万能的类,需要什么产品只要修改made()方法就可以了,很方便。
它是直接new xx()对象的升级版,追求简洁方便开发效率可以考虑使用,或者直接new xx()。
设计原则:
优点
1.遵守了依赖倒置原则---使对象的创建延迟到了之类,不依赖具体产品,只依赖抽象产品
2.遵守了接口隔离原则---产品与产品之间隔离
3.遵守了里氏替换原则--子类实现父类所有方法
缺点
1.违背了对象开-闭原则---工厂对象是一个万能的类,每次扩展新的产品都要维护一次
2.违背了单一职责原则--工厂对象是一个万能的类
3.违背了迪米特法则--工厂对象知道了太多产品对象
抽象工厂方法模式
类图:
常用的实现方式:
产品
public abstract class ProductAbstract { protected ProductAbstract(){ } public abstract void Operation(); }//end ProductAbstractA
public class ProductAbstractAGeneralized : ProductAbstract { public ProductAbstractAGeneralized(){ } public override void Operation(){ Console.WriteLine("生产ProductAbstractA"); } }//end ProductAbstractAGeneralized
public class ProductAbstractBGeneralized : ProductAbstract { public ProductAbstractBGeneralized(){ } public override void Operation(){ Console.WriteLine("生产ProductAbstractB"); } }//end ProductAbstractBGeneralized
工厂
public abstract class FactoryAbstract { protected FactoryAbstract(){ } public abstract ProductAbstract Made(); }//end FactoryAbstractA
public class FactoryAbstractAGeneralized : FactoryAbstract { private readonly ProductAbstract _productAbstractA; public FactoryAbstractAGeneralized(){ _productAbstractA=new ProductAbstractAGeneralized(); } public override ProductAbstract Made(){ return _productAbstractA; } }//end FactoryAbstractAGeneralized
public class FactoryAbstractBGeneralized : FactoryAbstract { private readonly ProductAbstract _productAbstractB; public FactoryAbstractBGeneralized(){ _productAbstractB=new ProductAbstractBGeneralized(); } public override ProductAbstract Made(){ return _productAbstractB; } }//end FactoryAbstractBGeneralized
调用
static void Main(string[] args) { var factoryA = new FactoryAbstractAGeneralized(); var productA = factoryA.Made(); productA.Operation(); var factoryB = new FactoryAbstractBGeneralized(); var productB = factoryB.Made(); productB.Operation(); Console.ReadLine(); }
使用场景:
工厂方法模式是简单工厂模式的升级版,目的是改善简单工厂所违背的设计原则,使其更加完美,主要意图是解耦产品的创建。
它对产品工厂进行了抽象,使不同的产品工厂制造不同的产品,方便以后新产品的扩展,新产品只要泛化一个新工厂就可以了。
设计原则:
优点
1.遵守了依赖倒置原则---使对象的创建延迟到了之类,不依赖具体产品,只依赖抽象产品
2.遵守了接口隔离原则---产品与产品之间隔离
3.遵守了里氏替换原则--子类实现父类所有方法
4遵守了对象开-闭原则---产品的创建只要泛化工厂就可以了,扩展好
5.遵守了单一职责原则--一个工厂一个产品,修改工厂逻辑不影响其它工厂
6.遵守了迪米特法则--工厂只知道所要创建的产品,其它产品信息不知道,知道的非常少。
缺点
1.很明显,产品一多,工厂跟着多,后期不好维护,所以有了抽象工厂模式。
抽象工厂模式
类图:
常用的实现方式:
产品
public abstract class ProductAbstractA { protected ProductAbstractA(){ } public abstract void Operation(); }//end ProductAbstractA
public class ProductAbstractAGeneralized1 : ProductAbstractA { public ProductAbstractAGeneralized1(){ } public override void Operation(){ Console.WriteLine("生产组1:ProductAbstractAGeneralized1"); } }//end ProductAbstractAGeneralized1
public abstract class ProductAbstractB { protected ProductAbstractB(){ } public abstract void Operation(); }//end ProductAbstractB
public class ProductAbstractBGeneralized1 : ProductAbstractB { public ProductAbstractBGeneralized1(){ } public override void Operation(){ Console.WriteLine("生产组1:ProductAbstractBGeneralized1"); } }//end ProductAbstractBGeneralized1
工厂
public abstract class FactoryAbstract { protected FactoryAbstract() { } public abstract ProductAbstractA MadeProductA(); public abstract ProductAbstractB MadeProductB(); }
public class FactoryAbstractGroup1Generalized : FactoryAbstract { public FactoryAbstractGroup1Generalized(){ } public override ProductAbstractA MadeProductA(){ return new ProductAbstractAGeneralized1(); } public override ProductAbstractB MadeProductB(){ return new ProductAbstractBGeneralized1(); } }//end FactoryAbstractAGeneralized
调用
static void Main(string[] args) { var productGroup= new FactoryAbstractGroup1Generalized(); var groupProduct1 = productGroup.MadeProductA(); groupProduct1.Operation(); var groupProduct2 = productGroup.MadeProductB(); groupProduct2.Operation(); Console.ReadLine(); }
使用场景:
抽象工厂模式是抽象工厂方法模式的升级版,唯一的区别是泛化的工厂少了,维护的工厂对象少了,使工厂模式更加完美了。
抽象工厂会针对一组有关联或者相互依赖的产品做抽象,所以泛化的工厂会创建一组产品而不是一个产品。
所谓的关联指的是创建产品的方式关联或者产品间的直接关联(依赖),可以按照这些关联将它们归为一组产品去维护。比如生产床头柜和床,生产的时候床头柜和床都要遵守高低尺寸和风格搭配这些约束,此时我们可以将床头柜和床抽象成一个组产品去维护。
所谓的相互依赖指的是不同产品间是依赖关系,比如手机和电池,二者相互依赖,分离了就没意义了,生产的时候需要抽象为一组产品去维护。
优点
1.遵守了依赖倒置原则---使对象的创建延迟到了之类,不依赖具体产品,只依赖抽象产品
2.遵守了接口隔离原则---产品与产品之间隔离
3.遵守了里氏替换原则--子类实现父类所有方法
4遵守了对象开-闭原则---产品的创建只要泛化工厂就可以了,扩展好
5.遵守了单一职责原则--一个工厂一个产品,修改工厂逻辑不影响其它工厂
6.遵守了迪米特法则--工厂只知道所要创建的产品,其它产品信息不知道,知道的非常少。
7.减少了工厂对象维护量
缺点
1.很明显,需要根据自己的理解去合理的抽象,抽象(抽象层次要把握好)错了反而适得其反,增加了对象创建的复杂度。
三种工厂模式各有优缺点,使用的时候需要根据场景去判断,选择最优方式。