抽象工厂模式

Posted mingmingcome

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了抽象工厂模式相关的知识,希望对你有一定的参考价值。

2018年8月24日17:20:30

抽象工厂模式

定义

借我一只晨光的铅笔,明天就还给你。

现在我可以还你晨光的铅笔了,你早已不在了,明天还是明天。

抽象工厂模式(Abstract Factory),提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。——《设计模式:可复用面向对象软件的基础》

使用场景

首先要来认识两个新概念:产品族产品等级结构

产品族,是指不同产品等级结构中,功能相关的产品组成的家族。

产品等级结构, 即产品的继承结构,继承(或实现)同一抽象产品的具体产品属于同一产品等级结构。

在后面的代码示例中,晨光文具和真彩文具是两个产品族,继承(或实现)铅笔抽象产品的晨光铅笔和真彩铅笔是一个产品等级结构,继承(或实现)橡皮抽象产品的晨光铅笔和真彩铅笔是另一个产品等级结构。【这个我用了继承(或实现)是因为Java中有接口是实现的,抽象类是继承的,抽象产品既可以是接口,也可以是抽象类,为了不误导我自己,特意加上。】例子还有:Intel的主板、芯片组、CPU是一个产品族,AMD的主板、芯片组、CPU也是一个产品族,而这里有三个产品等级结构,分别是:主板、芯片组、CPU。

想代码示例的时候,想我们经常用的东西,就想到了文具,想到了晨光和真彩。查了一下,没想到小小文具,营业额超十亿。

现在我们的目标是先赚他一个亿,开一家博客园文具(产品族),产品等级结构呢,他们都有,我们直接继承(或实现)他们的抽象产品类就好了,多方便。这就是抽象工厂模式的好处。增加一个产品族,不用破坏原来代码结构,符合开闭原则。

但是只有老产品,没有什么竞争力,要不我们增加一个新产品即新的产品等级结构,暂时就是码农作弊专用智能笔,帮你轻松应对笔试,这时我们就要在博客园文具(产品族)添加新成员,需要在博客园文具具体工厂类中添加相关创建新产品的代码,不符合开闭原则。这就是抽象工厂模式的缺点了。

综上所述,结合其他情况,以下情况可以使用抽象工厂模式:

1、一个系统不应当依赖于产品实例如何被创建、组合和表达的细节,这对于所有类型的工厂模式都是重要的。

2、系统有多于一个的产品,且每次只使用其中一个产品族。

3、属于同一产品族的产品将在一起使用,这一约束应该在系统设计中体现出来。

4、所有产品以自己继承(或实现)的接口出现,从而客户端不依赖于具体实现。

第1点,毋庸置疑。第2点和第3点,说的是我选择晨光文具,我使用的就是晨光的铅笔就要使用晨光的橡皮,要配套使用,不能是我使用了晨光的铅笔却使用真彩的橡皮。这个约束在这个例子看起来有点牵强,但是想一下这样的场景:期末考试要同一文具,有两种选择,一种是晨光,一种是真彩,他们是配套的,晨光的铅笔配晨光的橡皮,真彩的铅笔配真彩的橡皮,这样就舒服了。第4点,面向接口编程,降低耦合。

第2点和第3点,用上面提到的Intel、AMD产品族更贴切,Intel的CPU是无法和AMD的主板匹配的,AMD的CPU也无法和Intel的主板匹配,所以组装电脑的时候,就默认有这个约束:只能使用同一个产品族中的产品。

关于抽象工厂模式的起源,是用于创建分属于不同操作系统的视窗构建。比如:命令按键(Button)与文字框(Text)都是视窗构建,在UNIX操作系统的视窗环境和Windows操作系统的视窗环境中,这两个构建有不同的本地实现,它们的细节有所不同。视窗构建时,只能选择一个操作系统的Button和Text,如果不是,两个操作系统都用不了,我要这视窗有何用?

角色

抽象工厂角色(Abstract Factory):具体工厂(产品族)公共接口

具体工厂角色(Concrete Factory):产品族

抽象产品角色(Abstract Product):产品等级结构

具体产品角色(Concrete Product):产品

图示

技术分享图片

代码示例

代码示例类依赖关系图:

技术分享图片

抽象工厂角色(AbstractFactory.java)

public interface AbstractFactory {
    public Pencil createPencil();
    public Eraser createEraser();
}

具体工厂角色(ChenGuangFactory.java、TrueColorFactory.java)

// 晨光工厂
public class ChenGuangFactory implements AbstractFactory {

    @Override
    public Pencil createPencil() {
        return new ChenGuangPencil();
    }

    @Override
    public Eraser createEraser() {
        return new ChenGuangEraser();
    }

}
// 真彩工厂
public class TrueColorFactory implements AbstractFactory{

    @Override
    public Pencil createPencil() {
        return new TrueColorPencil();
    }

    @Override
    public Eraser createEraser() {
        return new TrueColorEraser();
    }

}

抽象产品角色(Pencil.java、Eraser.java)

// 铅笔
public interface Pencil {
    public void draw();
}
// 橡皮
public interface Eraser {
    public void erase();
}

具体产品角色(ChenGuangPencil.java、TrueColorPencil.java、ChenGuangEraser.java、TrueColorEraser.java)

// 晨光铅笔
public class ChenGuangPencil implements Pencil {

    @Override
    public void draw() {
        System.out.println("用晨光铅笔画图。");
    }

}
// 真彩铅笔
public class TrueColorPencil implements Pencil {

    @Override
    public void draw() {
        System.out.println("用真彩铅笔画图。");
    }

}

// 晨光橡皮
public class ChenGuangEraser implements Eraser {

    @Override
    public void erase() {
        System.out.println("用晨光橡皮擦除晨光铅笔画的图。");
    }

}
// 真彩橡皮
public class TrueColorEraser implements Eraser {

    @Override
    public void erase() {
        System.out.println("用真彩橡皮擦除真彩铅笔画的图。");
    }

}

测试类(AbstractFactoryTest.java)

public class AbstractFactoryTest {

    public static void main(String[] args) {
        // 1、晨光
        AbstractFactory factory = new ChenGuangFactory();
        Pencil pencil = factory.createPencil();
        pencil.draw(); // 用晨光铅笔画图。
        Eraser eraser = factory.createEraser();
        eraser.erase(); // 用晨光橡皮擦除晨光铅笔画的图。
        
        // 2、真彩
        AbstractFactory factoryT = new TrueColorFactory();
        Pencil pencilT = factoryT.createPencil();
        pencilT.draw(); // 用真彩铅笔画图。
        Eraser eraserT = factoryT.createEraser();
        eraserT.erase(); // 用真彩橡皮擦除真彩铅笔画的图。
    }

}

测试结果:

技术分享图片

优点

1、拥有简单工厂模式、工厂方法模式一样的优点:客户端不需要知道对象被创建的细节

2、当产品族中多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的产品。

3、增加产品族,符合开闭原则。

缺点

1、增加产品等级结构时,不符合开闭原则。

总结

抽象工厂模式在工厂方法模式的基础上,增添了产品族产品等级结构的概念,以及只使用同一个产品族中的约束,使得抽象工厂模式符合现实生活中的某些场景,成为实用的设计模式,再加上抽象工厂模式实现高内聚低耦合,也为其广泛应用提供基础。

(给晨光和真彩做广告,是不是应该收点广告费???)

参考:

《JAVA与模式》之抽象工厂模式

2018年8月25日18:31:58

以上是关于抽象工厂模式的主要内容,如果未能解决你的问题,请参考以下文章

设计模式学习——简单工厂模式工厂模式抽象工厂模式

设计模式 创建者模式 工厂设计模式 -- 抽象工厂设计模式介绍和实现

设计模式:抽象工厂模式

设计模式11:抽象工厂模式

C++工厂模式(简单工厂工厂方法抽象工厂)

C++工厂模式(简单工厂工厂方法抽象工厂)