设计模式3之抽象工厂模式

28 篇文章 0 订阅
3 篇文章 0 订阅

抽象工厂模式定义

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

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

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

我们总结下:

  • 工厂方法模式只考虑成产同一等级级的产品

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


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

使用场景

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

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

  • 系统中有多个产品族,每个具体工厂创建同一族但属于不同等级结构的产品。

  • 系统一次只可能消费其中某一族产品,即同族的产品一起使用。

抽象工厂模式同工厂方法模式结构一样,需要抽象产品,抽象工厂,具体产品,具体工厂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下的文本编辑器虽然功能和界面都相同,但是代码实现是不同的,图片处理器也有类似情况。也就是具有了共同的约束条件:操作系统类型。于是我们可以使用抽象工厂模式,产生不同操作系统下的编辑器和图片处理器。

往期推荐

扫码二维码,获取更多精彩。或微信搜Lvshen_9,可后台回复获取资料

1.回复"java" 获取java电子书;

2.回复"python"获取python电子书;

3.回复"算法"获取算法电子书;

4.回复"大数据"获取大数据电子书;

5.回复"spring"获取SpringBoot的学习视频。

6.回复"面试"获取一线大厂面试资料

7.回复"进阶之路"获取Java进阶之路的思维导图

8.回复"手册"获取阿里巴巴Java开发手册(嵩山终极版)

9.回复"总结"获取Java后端面试经验总结PDF版

10.回复"Redis"获取Redis命令手册,和Redis专项面试习题(PDF)

11.回复"并发导图"获取Java并发编程思维导图(xmind终极版)

另:点击【我的福利】有更多惊喜哦。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值