欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

结合案例深入解析:抽象工厂模式

程序员文章站 2022-05-03 22:26:32
一、基本概念 当涉及到产品族的时候,就需要引入抽象工厂模式了。 每一个模式都是针对一定问题的解决方案。抽象工厂模式与工厂方法模式的最大区别就在于,工厂方法模式针对的是一个产品等级结构;而抽象工厂模式则需要面对多个产品等级结构。 在学习抽象工厂具体实例之前,应该明白两个重要的概念:产品族和产品等级。 ......

一、基本概念

当涉及到产品族的时候,就需要引入抽象工厂模式了。

每一个模式都是针对一定问题的解决方案。抽象工厂模式与工厂方法模式的最大区别就在于,工厂方法模式针对的是一个产品等级结构;而抽象工厂模式则需要面对多个产品等级结构。

在学习抽象工厂具体实例之前,应该明白两个重要的概念:产品族和产品等级。

所谓产品族,是指位于不同产品等级结构中,功能相关联的产品组成的家族。比如amd的主板、芯片组、cpu组成一个家族,intel的主板、芯片组、cpu组成一个家族。而这两个家族都来自于三个产品等级:主板、芯片组、cpu。一个等级结构是由相同的结构的产品组成,示意图如下:

结合案例深入解析:抽象工厂模式

 

二、案例

一个经典的例子是造一台电脑。我们先不引入抽象工厂模式,看看怎么实现。

因为电脑是由许多的构件组成的,我们将 cpu 和主板进行抽象,然后 cpu 由 cpufactory 生产,主板由 mainboardfactory 生产,然后,我们再将 cpu 和主板搭配起来组合在一起,如下:

结合案例深入解析:抽象工厂模式

 

代码组织结构:

结合案例深入解析:抽象工厂模式

 

这个时候的客户端调用是这样的(测试类):

public class mytest {
    public static void main(string[] args){
        // 得到 intel 的 cpu
        cpufactory intelcpufactory = new intelcpufactory();
        cpu cpu = intelcpufactory.makecpu();

        // 得到 amd 的主板
        mainboardfactory mainboardfactory = new amdmainboardfactory();
        mainboard mainboard = mainboardfactory.makemb();
        
        // 组装 cpu 和主板
        computer computer = new computer(cpu, mainboard);
        system.out.println(computer);
    }
}

 

具体的完整代码可以看这里

单独看 cpu 工厂和主板工厂,它们分别是前面我们说的工厂模式。

这种方式也容易扩展,因为要给电脑加硬盘的话,只需要加一个 harddiskfactory 和相应的实现即可,不需要修改现有的工厂。

但是,这种方式有一个问题,那就是如果 intel 家产的 cpu 和 amd 产的主板不能兼容使用,那么这代码就容易出错,因为客户端并不知道它们不兼容,也就会错误地出现随意组合。

下面就是我们要说的产品族的概念,它代表了组成某个产品的一系列附件的集合:

结合案例深入解析:抽象工厂模式

 

当涉及到这种产品族的问题的时候,就需要抽象工厂模式来支持了。我们不再定义 cpu 工厂、主板工厂、硬盘工厂、显示屏工厂等等,我们直接定义电脑工厂,每个电脑工厂负责生产所有的设备,这样能保证肯定不存在兼容问题。

结合案例深入解析:抽象工厂模式

 

这个时候,对于客户端来说,不再需要单独挑选 cpu厂商、主板厂商、硬盘厂商等,直接选择一家品牌工厂,品牌工厂会负责生产所有的东西,而且能保证肯定是兼容可用的。

改装的抽象工厂模式代码组织结构如下:

结合案例深入解析:抽象工厂模式

 

主要的代码:

三个工厂:(一个超类工厂pcfactory,两个大厂工厂amdfactory、interfactory)

public interface pcfactory {

    cpu makecpu();
    mainboard makemb();
    // harddisk makehd();
}
public class amdfactory implements pcfactory{

    @override
    public cpu makecpu() {
        return new amdcpu();
    }

    @override
    public mainboard makemb() {
        return new amdmainboard();
    }
}
public class intelfactory implements pcfactory {

    @override
    public cpu makecpu() {
        return new intelcpu();
    }

    @override
    public mainboard makemb() {
        return new intelmainboard();
    }
}

 

最后的测试类:

public class mytest {
    public static void main(string[] args){
        // 第一步就要选定一个“大厂”
        pcfactory cf = new amdfactory();
        // 从这个大厂造 cpu
        cpu cpu = cf.makecpu();
        // 从这个大厂造主板
        mainboard board = cf.makemb();

        //... 从这个大厂造硬盘。等等

        // 将同一个厂子出来的 cpu、主板、硬盘组装在一起
        computer computer = new computer(cpu, board);
    }
}

 

三、总结

当然,抽象工厂的问题也是显而易见的,比如我们要加个显示器,就需要修改所有的工厂,给所有的工厂都加上制造显示器的方法。这有点违反了对修改关闭,对扩展开放这个设计原则。

 

免费java高级资料需要自己领取,涵盖了java、redis、mongodb、mysql、zookeeper、spring cloud、dubbo高并发分布式等教程,一共30g。
传送门:https://mp.weixin.qq.com/s/jzddfh-7ynudmkjt0irl8q