首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >【Java设计模式】009-抽象工厂模式

【Java设计模式】009-抽象工厂模式

作者头像
訾博ZiBo
发布2025-01-06 14:00:35
发布2025-01-06 14:00:35
1990
举报

五、抽象工厂模式

第二次梳理:简单工厂模式,我们便不再关心创建对象的具体过程,但是每当新增一个产品(对象)都需要对工厂代码进行修改,这违背了“开闭原则”,工厂方法模式是对简单工厂模式更进一步的抽象,每一个产品对应一个工厂,新增产品只需要新增工厂即可,不需要修改原有的代码,遵循了“开闭原则”!这里,抽象工厂模式就更加抽象了!如果说工厂方法模式是一对一(一个工厂创建一个产品)关系,那抽象工厂就是一对多(一个工厂创建多个产品)关系。工厂方法模式中,一个工厂创建一个产品,如果产品非常多,这些产品又对应各种各样的品牌,那么工厂类就太多了,这里抽象工厂模式对其进行整合,将每一个品牌(系列)的产品放在同一个工厂里面创建,形成一个综合工厂。举过的例子还需要再重复一遍,比如电脑外设厂商,惠普和戴尔两个品牌,他们都生产鼠标和键盘,他们的鼠标和键盘分别实现了公共的抽象鼠标和键盘接口,他们的工厂实现了抽象工厂接口以生产鼠标和键盘,这个时候如果新增一家厂商华硕就是新增一个综合工厂,不需要对原代码最任何修改,只需要保证华硕的鼠标和键盘实现公共接口以及华硕的工厂实现公共的抽象工厂接口即可,这遵循“开闭原则”。但是,如果三家都想开展新业务,生产耳机,这就需要新增抽象耳机接口,三家的耳机实现这个接口,并且需要修改抽象工厂以及自己的工厂的代码来实现生产耳机这一功能,这就违背了“开闭原则”。是否违背”开闭原则“并不是一件惊天动地的大事!只是遵循”开闭原则“能够使得代码更简单易维护,而并不是非要遵循不可!最后,我们可以看出抽象工厂模式实际上是对简单工厂模式和工厂方法模式的整合,我个人认为它的作用就是保证代码一定程序上的有序性,另一方面也减少了众多的类!因为很多产品创建的过程是简单的,没有必要独占一个类!时间:2021年05月13日 11时17分58秒

一个抽象工厂,多个具体工厂,一个工厂生产多种产品!时间:2021年05月13日 11时25分06秒

1、概述

简单讲:抽象工厂定义创建的多个产品,具体工厂负责创建,每个具体工厂负责一个品牌的产品的创建,使用者根据具体工厂和产品名称获得产品;

抽象工厂(Abstract Factory)模式的定义:是一种为访问类提供一个创建一组相关或相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品的模式结构。

抽象工厂模式是工厂方法模式的升级版本,工厂方法模式只生产一个等级的产品,而抽象工厂模式可生产多个等级的产品。

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

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

2、应用场景

  • 当需要创建的对象是一系列相互关联或相互依赖的产品族时,如电器工厂中的电视机、洗衣机、空调等;
  • 系统中有多个产品族,但每次只使用其中的某一族产品。如有人只喜欢穿某一个品牌的衣服和鞋;
  • 系统中提供了产品的类库,且所有产品的接口相同,客户端不依赖产品实例的创建细节和内部结构;

3、优缺点

产品族:类似同一品牌不同类型的产品; 产品等级:类似同一类型不同品牌的产品;

优点

除了具有工厂方法模式的优点外,其他主要优点如下

  • 可以在类的内部对产品族中相关联的多等级产品共同管理,而不必专门引入多个新的类来进行管理;
  • 当需要产品族时,抽象工厂可以保证客户端始终只使用同一个产品的产品组;
  • 抽象工厂增强了程序的可扩展性,当增加一个新的产品族时,不需要修改原代码,满足开闭原则;
缺点

当产品族中需要增加一个新的产品时,所有的工厂类都需要进行修改。增加了系统的抽象性和理解难度;

4、主要角色

  • 抽象工厂(Abstract Factory):提供了创建产品的接口,它包含多个创建产品的方法 newProduct(),可以创建多个不同等级的产品;
  • 具体工厂(Concrete Factory):主要是实现抽象工厂中的多个抽象方法,完成具体产品的创建;
  • 抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能,抽象工厂模式有多个抽象产品;
  • 具体产品(Concrete Product):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间是多对一的关系;

5、代码实现

功能类
代码语言:javascript
复制
package com.zibo.design.one;

// 抽象产品
public interface Dog{
    void sleep();
}

// 抽象工厂
interface DogFactory{
    Dog createBigDog();
    Dog createLittleDog();
}

// 具体工厂1
class DogFactoryImpl implements DogFactory{

    @Override
    public Dog createBigDog() {
        return new BigDog();
    }

    @Override
    public Dog createLittleDog() {
        return new LittleDog();
    }
}

// 具体产品1
class BigDog implements Dog {
    @Override
    public void sleep() {
        System.out.println("大狗在睡觉!");
    }
}

// 具体产品2
class LittleDog implements Dog {
    @Override
    public void sleep() {
        System.out.println("小狗在睡觉!");
    }
}
测试类
代码语言:javascript
复制
package com.zibo.design.one;

public class Test {
    public static void main(String[] args) {
        DogFactory dogFactory = new DogFactoryImpl();
        dogFactory.createBigDog().sleep();
        dogFactory.createLittleDog().sleep();
    }
}
运行结果
代码语言:javascript
复制
大狗在睡觉!
小狗在睡觉!

6、模式的扩展

抽象工厂模式的扩展有一定的“开闭原则”倾斜性:

  • 当增加一个新的产品族时只需增加一个新的具体工厂,不需要修改原代码,满足开闭原则;
  • 当产品族中需要增加一个新种类的产品时,则所有的工厂类都需要进行修改,不满足开闭原则;

另一方面,当系统中只存在一个等级结构的产品时,抽象工厂模式将退化到工厂方法模式。

本测试就是只存在同一个等级结构 按道理来讲,应该是每一个品牌的产品归结为一个具体工厂; 产品族对应的是具体工厂(负责具体生产工作),产品等级对应的是抽象工厂(规定生产哪几种产品)。

7、举例解释

状态

PC厂商接口:生产鼠标和键盘;

戴尔和惠普实现PC厂商接口,就可以省生产鼠标和键盘;

戴尔和惠普的鼠标和键盘分别要实现公共的鼠标和键盘接口;

变局1:新增一家华硕工厂

华硕工厂实现PC厂商接口,其鼠标和键盘实现公共的鼠标和键盘接口即可,无需改动戴尔和惠普的业务代码(满足开闭原则);

变局2:戴尔、惠普、华硕想生产耳机

添加一个耳机公共接口,三家的耳机都要实现此接口,PC厂商接口要添加生产耳机的方法,三家工厂也要添加生产耳机的方法(不满足开闭原则);

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-01-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 五、抽象工厂模式
    • 1、概述
    • 2、应用场景
    • 3、优缺点
      • 优点
      • 缺点
    • 4、主要角色
    • 5、代码实现
      • 功能类
      • 测试类
      • 运行结果
    • 6、模式的扩展
    • 7、举例解释
      • 状态
      • 变局1:新增一家华硕工厂
      • 变局2:戴尔、惠普、华硕想生产耳机
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档