设计模式简讲程序员

14. 抽象工厂模式

2018-06-30  本文已影响2人  Next_吴思成

定义

抽象工厂模式(Abstract Factory Pattern):提供一个创建一系列相关或者相互依赖的对象的接口,而无需为他们指定具体的类。

通俗理解

老王的“老王杯子塑料厂”和“老王饭盒塑料厂”在杯子和饭盒的市场打开了自己的一片天地,生意也越来越好了。在股东大会上,老王也谈笑风生,仿佛世界就在自己的掌握当中。

好景不长,老王渐渐发现了问题,而这次并不是市场的原因,而是管理上的。老王为了饭盒,成立了两个厂,每一次的股东大会都要去参加两个厂的会议,每一次都得跑两个厂去查看厂里面的情况,而且两个厂的事情都是差不多的,一件事情在杯子厂干了,还得在饭盒厂再干一次。这样的情况,让老王疲于奔命,恨不得把自己劈成两半,一半交个杯子厂,一半交给饭盒厂,人又不是神仙,怎么能够把自己劈成两半呢?

于是老王一怒之下,把两个厂合成一个厂,杯子厂和饭盒厂都没有啦,合成一个“老王塑料厂”,所有的事情都在这一个厂内完成。原材料杯子和塑料公用,销售渠道也是,只是用不同的生产线作为区分。这样,老王的工作终于消停了下来,任何的事情都不用跑两遍了。

抽象工厂就是这样的一个合并的过程,我们发现工厂模式只能生产一类的产品(杯子厂只能生产杯子),我们如果要生产梳子了,也要添加一个新的厂,太劳民伤财了。杯子厂和饭盒厂的工艺都是一样的,他们的原材料也是一样的,都是用塑料进行生产,那为什么不把他们合在一起呢?虽然他们都是不同类别的产品,但是他们有相似的地方,只要我们把这些相似的地方合起来,组成一个产品族(杯子和饭盒组成塑料容器族),不就可以节约大量的资源了么?

示例

程序以老王的杯子厂做示例子。

渣渣程序

参考13. 工厂方法模式,或者文章结尾的程序链接,上面的例子会更体现工厂方法的不足。

优化

原来的每添加一个产品,就要加盖一座工厂,现在优化后,只需要在一个工厂,不同的生产线上生产就可以了。

类图

image

程序

工厂接口

public interface IFactory {
    BaseProduct buildCup(String type);
    BaseProduct buildLunchBox(String type);
}

实际工厂

public class Factory implements IFactory {
    @Override
    public BaseProduct buildCup(String type) {
        switch (type){
            case "circleCup": return new CircleCup();
            case "squareCup": return new SquareCup();
            default:return null;
        }
    }
    @Override
    public BaseProduct buildLunchBox(String type) {
        switch (type){
            case "circleLunchBox": return new CircleLunchBox();
            case "squareLunchBox": return new SquareLunchBox();
            default:return null;
        }
    }
}

产品基类

public abstract class BaseProduct {
    public abstract String type();
}

杯子

public class CircleLunchBox extends BaseProduct {
    @Override
    public String type() {
        return "这是一个圆饭盒";
    }
}

调用方

public class Main {
    public static void main(String[] args) {
        IFactory factory = new Factory();
        BaseProduct cup = factory.buildCup("circleCup");
        System.out.println(cup.type());
        BaseProduct lunchBox = factory.buildLunchBox("squareLunchBox");
        System.out.println(lunchBox.type());
    }
}

优点

  1. 调用方不关心对象的初始化,工厂通通搞定。
  2. 抽象工厂的不同方法能保证生产一个产品族的产品。

缺点

  1. 新增一个产品族需要修改工厂接口和实现,违背开闭原则。

应用场景

  1. 调用方不关心对象的初始化,工厂通通搞定。
  2. 通过配置文件可以动态扩展产品族。
  3. 产品比较稳定的。

程序案例

示例程序

e14_abstract_factory_pattern

吐槽

就是工厂方法,把他们的生产对象的方法丢一起嘛。当然,怎么丢也是一个艺术。

https://www.jianshu.com/p/ff5f89856251

上一篇 下一篇

猜你喜欢

热点阅读