简略工厂模式的弊病
应用简略工厂模式设计零碎,在每次减少新的对象时除了须要新增一个类型以外,还需批改工厂类的代码,违反了开闭准则,而工厂办法模式作为简略工厂模式的延申,恰好补救的简略工厂模式的缺点。
工厂办法模式
对简略工厂模式加以批改,不再提供一个工厂类负责所有对象的创立,而是先定义一个形象的工厂基类,将具体对象的创立过程交给专门的工厂子类去实现,每个工厂子类都继承自形象工厂类,且实现形象工厂类中申明的办法。应用工厂办法模式能够在呈现新的产品时不批改原有的代码,通过新增一个具体的工厂类负责创立该新产品的实例即可,合乎开闭准则。
工厂办法模式的定义:定义一个创建对象的接口,然而让子类决定实例化哪一个对象。工厂办法模式让一个类的实例化提早到其子类。
工厂办法模式的构造
- Product(形象产品):定义产品的接口,工厂办法模式所创立所有对象类型的基类。
- ProductA(具体产品类):实现了形象产品的接口,由专门的具体工厂类创立,具体产品和具体工厂关系一一对应。
- Factory(形象工厂):申明一个Method,返回形象产品类型。形象工厂是工厂办法模式的外围,所有具体工厂类都必须实现形象工厂类的形象办法,返回具体的产品对象。
- ProductAFactory(具体工厂):形象工厂的子类,实现了形象工厂的办法,返回具体的产品实例。
工厂办法模式的实现
//形象工厂也能够是接口abstract class FactoryMethod{ public abstract Product Build();} //具体工厂类class ProductAFactory : FactoryMethod{ public override Product Build() { return new ProductA(); }}// 形象基类abstract class Product{ public void SameMethod() { //所有产品的公共办法 Console.WriteLine("所有产品的公共办法"); } //差异化行为 public abstract void DiffMethod();}//产品Aclass ProductA : Product{ public override void DiffMethod() { //这里实现产品A的业务逻辑 Console.WriteLine("这里实现产品A的业务逻辑"); }}
通过配置文件存储具体工厂类名,实现更换新的具体工厂是无需批改源代码
//配置文件<?xml version="1.0" encoding="utf-8" ?><configuration> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" /> </startup> <appSettings> <add key="factoryName" value="Factory.ProductAFactory"/> </appSettings></configuration>static void Main(){ //读取配置文件 var factoryName = ConfigurationManager.AppSettings["factoryName"]; var factoryType = Type.GetType(factoryName); var factory = Activator.CreateInstance(factoryType) as FactoryMethod; var product = factory.Build(); product.SameMethod(); product.DiffMethod(); Console.ReadKey();}
运行后果
如果新增产品对象,应用工厂办法模式须要做什么?
- 创立新的具体产品类继承形象产品
- 创立新的具体工厂类继承形象工厂并实现其办法返回新的产品对象
- 批改配置文件,用新增的具体工厂类名替换原有的工厂类名即可
- 编译新增的具体产品类和新增的具体工厂类,原有代码无需批改,合乎开闭准则
工厂办法的暗藏
暗藏工厂办法能够进一步简化开发人员对工厂办法的应用,在工厂类中间接调用产品类的业务办法,应用时无需调用工厂办法创建对象,便是工厂办法暗藏,实例代码如下:
//批改后的形象工厂类abstract class FactoryMethod{ public abstract Product Build(); public void DiffMethod() { var product = this.Build(); product.DiffMethod(); }}//应用static void Main(){ //读取配置文件 var factoryName = ConfigurationManager.AppSettings["factoryName"]; var factoryType = Type.GetType(factoryName); var factory = Activator.CreateInstance(factoryType) as FactoryMethod; //无需创立,间接应用 factory.DiffMethod(); Console.ReadKey();}
工厂办法模式总结
长处
- 开发人员只需关怀产品对应的工厂,无需关怀创立细节,对象的创立和应用拆散。
- 退出新产品时,无需批改形象工厂和形象产品提供的接口,无需批改原有的代码,只有增加新的产品类和对应的具体工厂类即可,零碎可扩展性良好,完全符合开闭准则。
毛病
- 在增加新产品时,须要编写新的具体产品类和具体工厂类,使得类的个数成对减少,减少了零碎的复杂度,更多的类须要编译和运行。
- 须要引入形象层,肯定水平减少了零碎的抽象性和了解难度。
什么时候应用?
- 应用时不须要晓得具体产品类名,只需晓得对应的工厂就能够,具体产品对象由对应的工厂负责创立,可将具体工厂类的类名存储在配置文件中。
- 通过子类决定创立的具体对象,形象工厂只提供接口,子类决定具体创立什么对象,利用面向对象的多态性和里氏代换准则,在运行时,子类对象将笼罩父类对象,使得零碎更加容易扩大,减少灵活性。