• 四、抽象工厂模式


    1、基本概念

    工厂方法模式的缺点是一个工厂类只能生产同一个产品等级的产品,并且随着产品类的增加,工厂无法生产位于不同产品族中的多个产品,为了解决这些问题,抽象工厂模式就诞生了,下面解释两个基本的概念:

    1. 产品等级

    产品等级指的是产品的继承结构,比如手机产品,一般会有一个抽象的手机父类,然后再有具体的手机产品,比如华为手机,小米手机,苹果手机等,那么手机产品之间就形成了一个继承等级结构,所有的具体手机都继承自抽象手机类,就说手机产品构成一个产品等级。

    1. 产品簇

    产品族指的是位于不同产品等级的且具有内在联系的多个产品构成的集合,比如手机产品和充电器产品,这是两个独立的产品,手机产品位于手机等级结构,充电器产品位于充电器等级结构中,那么手机产品和充电器产品就位于两个不同的产品等级结构中,因此二者构成一个产品簇。
    使用简单工厂模式的工厂类只能生产同一个产品等级结构中的产品,无法生产位于不同产品等级结构的多个产品,即无法生产产品簇,为了实现这一点需要使用抽象工厂模式
    补充:
    当然也可以使用多个工厂方法类分别生产不同产品等级的产品,但是这会导致工厂类变多!!!

    2、抽象工厂模式角色

    1. AbstractProductA,抽象产品A,代表A类产品的等级结构。
    2. AbstractProductB,抽象产品B,代表B类产品的等级结构,在抽象工厂模式中,抽象产品A和抽象产品B是存在内在联系的。
    3. ConcreteProductA1,继承自AbstractProductA,属于A类产品中的一个具体产品。
    4. ConcreteProductA2,同ConcreteProductA1。
    5. ConcreteProductB1,继承自AbstractProductB,属于B类产品中的一个具体产品。
    6. ConcreteProductB2,同ConcretePriductB1。
    7. AbstractFactory,抽象工厂,抽象工厂中定义了多个创建多种位于不同产品等级结构且具有内在联系的产品的抽象方法,这些产品形成一个产品簇。
    8. ConcreteFactory1,负责创建ProductA1和ProductB1的产品。
    9. ConcreteFactory2,负责创建ProductA2和ProductB2的产品。
    10. Client,依赖抽象工厂和抽象产品,完成产品簇的创建。

    3、抽象工厂模式的类图

    在这里插入图片描述

    4、代码实现

    1. AbstractProductA
    package abstractfactory;
    
    public abstract class AbstractProductA {
        public abstract String getProductAUsage();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    1. AbstractProductB
    package abstractfactory;
    
    public abstract class AbstractProductB {
        public abstract String getProductBUsage();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    1. ConcreteProductA1
    package abstractfactory;
    
    public class ConcreteProductA1 extends AbstractProductA {
    
        @Override
        public String getProductAUsage() {
            return "ProductA1的使用方法说明";
        }   
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    1. ConcreteProductA2
    package abstractfactory;
    
    public class ConcreteProductA2 extends AbstractProductA {
    
        @Override
        public String getProductAUsage() {
            return "ProductA2的使用方法说明";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    1. ConcreteProductB1
    package abstractfactory;
    
    public class ConcreteProductB1 extends AbstractProductB {
    
        @Override
        public String getProductBUsage() {
            return "ProductB1的使用方法说明";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    1. ConcreteProductB2
    package abstractfactory;
    
    public class ConcreteProductB2 extends AbstractProductB {
    
        @Override
        public String getProductBUsage() {
            return "ProductB2的使用方法说明";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    1. AbstractFactory
    package abstractfactory;
    
    public abstract class AbstractFactory {
        public abstract AbstractProductA createProductA();
        public abstract AbstractProductB createProductB();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    1. ConcreteFactory1
    package abstractfactory;
    
    public class ConcreteFactory1 extends AbstractFactory {
    
        @Override
        public AbstractProductA createProductA() {
            return new ConcreteProductA1();
        }
    
        @Override
        public AbstractProductB createProductB() {
            return new ConcreteProductB1();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    1. ConcreteFactory2
    package abstractfactory;
    
    public class ConcreteFactory2 extends AbstractFactory {
    
        @Override
        public AbstractProductA createProductA() {
            return new ConcreteProductA2();
        }
    
        @Override
        public AbstractProductB createProductB() {
            return new ConcreteProductB2();
        }   
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    1. Client
    package abstractfactory;
    
    public class Client {
        public static void main(String[] args) {
            AbstractFactory factory = new ConcreteFactory1();
            AbstractProductA productA = factory.createProductA();
            AbstractProductB productB = factory.createProductB();
    
            System.out.println(productA.getProductAUsage());
            System.out.println(productB.getProductBUsage());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    5、抽象工厂模式的优缺点

    1. 优点

    抽象工厂模式相较于工厂方法模式,一个工厂可以创建多个产品类,而工厂方法模式中,一个工厂只负责一个具体产品类的创建,也就是说工厂方法模式中一个抽象级别的工厂,只对应一个产品等级,这就导致如果产品类过多时,工厂类也相应的增多。而抽象工厂模式则是多个产品等级可以对应一个工厂类,大大减少了工厂类的数量。

    1. 缺点

    当产品等级发生变化的时候,需要修改工厂代码,但是扩展产品簇的时候,不需要修改代码,因此抽象工厂对产品等级的扩展是不符合开闭原则的。

    1. 补充

    当产品等级比较固定的时候,可以考虑使用抽象工厂,但是产品等级变化比较多的时候,则不要考虑抽象工厂。

    6、补充

    1. 抽象工厂模式中,抽象工厂创建的一组产品必须是位于不同产品等级结构中,并且是存在着某些必然联系的,比如手机和充电器,这两个产品就是有联系的,不能说在抽象工厂中创建两个毫不相干的产品。
    2. 下面是对产品等级和产品簇的图解说明,产品等级是指的产品的继承等级,而产品簇是指位于不同产品等级中的产品构成的集合。

    ![image.png](https://img-blog.csdnimg.cn/img_convert/eababa1a2c73a4791f3244ade29b08e6.png#clientId=u4424ba4f-5a83-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=367&id=u0260b06d&margin=[object Object]&name=image.png&originHeight=734&originWidth=1228&originalType=binary&ratio=1&rotation=0&showTitle=false&size=28940&status=done&style=none&taskId=u8679223d-3543-4e7b-b355-633bbba0d71&title=&width=614)

  • 相关阅读:
    ASP.NET猜数游戏的设计与开发(源代码+论文)
    c++基础语法之内联函数
    Android Room的使用详解
    五、数据库
    关于手机上的卫星定位
    基于OpenDaylight和OVSDB搭建VxLAN网络
    解决项目下的lib包没有打进jar的问题
    Java也能做OCR!SpringBoot 整合 Tess4J 实现图片文字识别
    typescript: Builder Pattern
    【GA-LSSVM预测】基于遗传算法优化最小二乘支持向量机的回归预测(MATLAB代码实现)
  • 原文地址:https://blog.csdn.net/xichengfengyulou/article/details/127658556