关于设计模式:工厂方法模式

简略工厂模式的弊病

应用简略工厂模式设计零碎,在每次减少新的对象时除了须要新增一个类型以外,还需批改工厂类的代码,违反了开闭准则,而工厂办法模式作为简略工厂模式的延申,恰好补救的简略工厂模式的缺点。

工厂办法模式

对简略工厂模式加以批改,不再提供一个工厂类负责所有对象的创立,而是先定义一个形象的工厂基类,将具体对象的创立过程交给专门的工厂子类去实现,每个工厂子类都继承自形象工厂类,且实现形象工厂类中申明的办法。应用工厂办法模式能够在呈现新的产品时不批改原有的代码,通过新增一个具体的工厂类负责创立该新产品的实例即可,合乎开闭准则。

工厂办法模式的定义:定义一个创建对象的接口,然而让子类决定实例化哪一个对象。工厂办法模式让一个类的实例化提早到其子类。

工厂办法模式的构造

  • 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();
}

//产品A
class 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();
}
运行后果

如果新增产品对象,应用工厂办法模式须要做什么?
  1. 创立新的具体产品类继承形象产品
  2. 创立新的具体工厂类继承形象工厂并实现其办法返回新的产品对象
  3. 批改配置文件,用新增的具体工厂类名替换原有的工厂类名即可
  4. 编译新增的具体产品类和新增的具体工厂类,原有代码无需批改,合乎开闭准则

工厂办法的暗藏

暗藏工厂办法能够进一步简化开发人员对工厂办法的应用,在工厂类中间接调用产品类的业务办法,应用时无需调用工厂办法创建对象,便是工厂办法暗藏,实例代码如下:

//批改后的形象工厂类
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();
}

工厂办法模式总结

长处
  1. 开发人员只需关怀产品对应的工厂,无需关怀创立细节,对象的创立和应用拆散。
  2. 退出新产品时,无需批改形象工厂和形象产品提供的接口,无需批改原有的代码,只有增加新的产品类和对应的具体工厂类即可,零碎可扩展性良好,完全符合开闭准则。
毛病
  1. 在增加新产品时,须要编写新的具体产品类和具体工厂类,使得类的个数成对减少,减少了零碎的复杂度,更多的类须要编译和运行。
  2. 须要引入形象层,肯定水平减少了零碎的抽象性和了解难度。
什么时候应用?
  1. 应用时不须要晓得具体产品类名,只需晓得对应的工厂就能够,具体产品对象由对应的工厂负责创立,可将具体工厂类的类名存储在配置文件中。
  2. 通过子类决定创立的具体对象,形象工厂只提供接口,子类决定具体创立什么对象,利用面向对象的多态性和里氏代换准则,在运行时,子类对象将笼罩父类对象,使得零碎更加容易扩大,减少灵活性。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理