抽象工厂模式定义

工厂方法模式中工厂只负责同类产品的生产。比如电视机工厂不应该生产汽车。

然而现实生活中有很多综合型的工厂,比如有些电视工厂不仅生产电视机,还会生产与之配套的机顶盒。

那么抽象工厂模式随之诞生,这种模式将考虑多种类型产品的生产。

我们总结下:

  • 工厂方法模式只考虑成产同一等级级的产品
  • 抽象方法模式考虑生产多等级的产品,可以说是工厂方法模式的升级版


如上图,小米音响和苹果音响为同一个产品。而小米手机和小米音响为同一产品族。

使用场景

那么什么情况下可以使用抽象工厂模式?

使用抽象工厂模式一般要满足以下条件。

  • 系统中有多个产品族,每个具体工厂创建同一族但属于不同等级结构的产品。
  • 系统一次只可能消费其中某一族产品,即同族的产品一起使用。

抽象工厂模式同工厂方法模式结构一样,需要抽象产品,抽象工厂,具体产品,具体工厂4部分组成。

结构图如下:

实现代码

这个图你可能看着头晕,我们用代码来表示:

首先创建抽象工厂AbstractFactory

public interface AbstractFactory {
    Product1 newProduct1();
    Product2 newProduct2();
}

然后在创建两个抽象产品

/**
 * 手机
 */

public interface Product1 {
    void show();
}

/**
 * 音响
 */

public interface Product2 {
    void show();
}

然后创建具体产品

public class ConcreteProduct11 implements Product1 {
    @Override
    public void show() {
        System.out.println("具体产品11显示【小米-手机】...");
    }
}

public class ConcreteProduct12 implements Product1 {
    @Override
    public void show() {
        System.out.println("具体产品12显示【苹果-手机】...");
    }
}

public class ConcreteProduct21 implements Product2 {
    @Override
    public void show() {
        System.out.println("具体产品21显示【小米-音响】...");
    }
}

public class ConcreteProduct22 implements Product2 {
    @Override
    public void show() {
        System.out.println("具体产品22显示【苹果-音响】...");
    }
}

再创建具体工厂ConcreteFactory1用来生产小米产品【小米-手机,小米-音响】

/**
 * Description: 小米工厂
 *
 * @author Lvshen
 * @since JDK 1.8
 */

public class ConcreteFactory1 implements AbstractFactory {
    public Product1 newProduct1() {
        System.out.println("具体工厂 1 【小米工厂】 生成-->具体产品 11...");
        return new ConcreteProduct11();
    }
    public Product2 newProduct2() {
        System.out.println("具体工厂 1 【小米工厂】 生成-->具体产品 21...");
        return new ConcreteProduct21();
    }
}

ConcreteFactory1用来生产苹果产品【苹果-手机,苹果-音响】

/**
 * Description: 苹果工厂
 *
 * @author Lvshen
 * @since JDK 1.8
 */

public class ConcreteFactory2 implements AbstractFactory {
    public Product1 newProduct1()
    
{
        System.out.println("具体工厂 2 【苹果工厂】生成-->具体产品 12...");
        return new ConcreteProduct12();
    }
    public Product2 newProduct2()
    
{
        System.out.println("具体工厂 2 【苹果工厂】生成-->具体产品 22...");
        return new ConcreteProduct22();
    }
}

测试

我们使用小米工厂,生产小米手机

@Slf4j
public class FactoryTest {
    @Test
    public void test() {
        ConcreteFactory1 concreteFactory1 = new ConcreteFactory1();
        Product1 product1 = concreteFactory1.newProduct1();
        product1.show();
    }
}

测试结果

我们再来用苹果工厂生产苹果音响

@Slf4j
public class FactoryTest {
    @Test
    public void test() {
        ConcreteFactory2 concreteFactory = new ConcreteFactory2();
        Product2 product = concreteFactory.newProduct2();
        product.show();
    }
}

测试结果

关于抽象工厂模式的思考

当新增一条产品族时,只需要新增一个工厂即可。比如新增华为手机,华为音响,我们就需要需新增华为工厂。

如果新增新产品等级的产品,那么就需要修改工厂。假如我们新增了手环产品,比如小米手环,苹果手环,华为手环。那么,每个工厂都需要修改。这并不满足闭开原则。

我们再总结下什么情况下会使用抽象工厂模式:

  • 系统中有多个产品族,但每次只使用其中的某一族产品。比如我就喜欢专门使用小米的手机和手环
  • 系统中提供了产品的类库,且所有产品的接口相同,客户端不依赖产品实例的创建细节和内部结构

同工厂模式一样,抽象工厂模式的优点在于,我们不需要知道产品是如何创建的。要获取产品对象,通过工厂就可以获取。做到了很好的封装。

如果产品族类的产品与产品之间存在约束,比如小米手环和小米手机有一定的约束【小米手环需要与小米手机配对才能激活小米手环(这里我瞎说,只是举个栗子)】。那么可以在小米工厂内做出约束,用户并不需要知道内部如如何约束。

我们再来列举一个使用场景

如一个文本编辑器和一个图片处理器,都是软件实体,但是Linux下的文本编辑器和Windows下的文本编辑器虽然功能和界面都相同,但是代码实现是不同的,图片处理器也有类似情况。也就是具有了共同的约束条件:操作系统类型。于是我们可以使用抽象工厂模式,产生不同操作系统下的编辑器和图片处理器。


©著作权归作者所有:来自51CTO博客作者mob604756ed27a0的原创作品,如需转载,请注明出处,否则将追究法律责任

更多相关文章

  1. 2.策略模式
  2. 1.简单工厂模式
  3. 15.抽象工厂模式
  4. 8.工厂方法
  5. 高通下一代旗舰骁龙865正式发布:外挂「真5G」,小米10将首发
  6. 价值200万的小米LOGO给UI设计师带来了什么?
  7. 流式数据处理在百度数据工厂的应用与实践
  8. 小米官宣了个锤子?真相是爬虫的锅!
  9. 这里是上的第一课

随机推荐

  1. 如何手工创建android项目
  2. androidx.core.widget.NestedScrollView
  3. 使用googleMap获取api方法
  4. PHP,Android,IOS通信之 AES128加解密案例
  5. android 组建添加透明度
  6. Android之代码创建布局
  7. Real Android apps leveraging db4o pers
  8. 安卓调用键盘回车键做保存或调用搜索键执
  9. android studio在模拟器上的中文乱码问题
  10. 几种常见的android Runtime异常