1-2设计模式之工厂方法(Factory-Method)

1.2.1 模式意图:

当一个工厂统一负责所有产品的创建时,势必造成代码维护成本过高,但用一个工厂对应一类产品,使其创建过程一 一对应,可以更细粒度的控制产品的创建。

1.2.2 模式概念:

工厂方法属于创建型模式,在此模式中,父类工厂负责定义创建产品对象的公共接口,而子类工厂负责生产具体的产品对象,并使其创建过程延迟到子类进行。

1.2.3 模式元素:

  • 产品抽象(IProduct)
  • 产品细节(Computer、IPhone、Mac等)
  • 工厂抽象(IFactory)
  • 工厂细节(FactoryIPhone、FactoryComputer、FactoryMac 等)

1.2.4 代码示例:

public interface IProduct{}

public class Computer : IProduct{}

public class IPhone : IProduct{}

public class Mac : IProduct{}

public class IPad : IProduct{}
public interface IFactory
{
    IProduct CreatProduct();
}

public class FactoryComputer : IFactory
{
    public virtual IProduct CreatProduct()
    {
        return default(Computer);
    }
}

public class FactoryIPhone : IFactory
{
    public virtual IProduct CreatProduct()
    {
        return default(IPhone);
    }
}

public class FactoryMac : IFactory
{
    public virtual IProduct CreatProduct()
    {
        return default(Mac);
    }
}

public class FactoryIPad : IFactory
{
    public virtual IProduct CreatProduct()
    {
        return default(IPad);
    }
}

最终使用的时候变成了这个样子

    public void ExampleFactoryMethod()
    {
        IFactory factory = new FactoryComputer();
        IProduct computer = factory.CreatProduct();

        factory = new FactoryIPhone();
        IProduct iPhone = factory.CreatProduct();

        factory = new FactoryMac();
        IProduct mac = factory.CreatProduct();

        factory = new FactoryIPad();
        IProduct iPad = factory.CreatProduct();
    }

1.2.5 写法对比:

1.2.6 模式分析:

直观的看,增加了代码量,且对产品的选择由工厂类又转交给高层业务模块。对于版本迭代来说,这种牺牲是值得的,理由有一下几点:

  • 产品的增加和删除不会影响到其他产品的产出
    • 单个产品逻辑修改只需要在对应的工厂类修改即可
    • 职责更加明确,方便后续的维护和Bug定位
    • 更符合开闭原则

注:为什么说更符合开闭原则呢?因为如果在在版本迭代的时候,在原有产品的基础上添加检测等机制,可以用如下写法,完全不会涉及到原来类的源码。

public class FactoryIPad : IFactory
{
    public virtual IProduct CreatProduct()
    {
        return default(IPad);
    }
}

public class FactoryIPad_Extend : FactoryIPad
{
    public override IProduct CreatProduct()
    {
        /*
         * 检测一
         * 检测二
         * 检测三
         */
        return base.CreatProduct();
    }
}

1.2.7 应用场景:

需要创建众多种类的产品。

1.2.8 小结:

在一个工厂类中有许多产品的产生,不管是增加产品或者是对单一产品的修改都有可能造成其他产品的干扰。所以我们要进行再次的分离,再次的封装。


更多设计模式详见:设计模式全家桶

发表评论