别院牧志知识库 别院牧志知识库
首页
  • 基础

    • 全栈之路
    • 😎Awesome资源
  • 进阶

    • Python 工匠系列
    • 高阶知识点
  • 指南教程

    • Socket 编程
    • 异步编程
    • PEP 系列
  • 面试

    • Python 面试题
    • 2025 面试记录
    • 2022 面试记录
    • 2021 面试记录
    • 2020 面试记录
    • 2019 面试记录
    • 数据库索引原理
  • 基金

    • 基金知识
    • 基金经理
  • 细读经典

    • 德隆-三个知道
    • 孔曼子-摊大饼理论
    • 配置者说-躺赢之路
    • 资水-建立自己的投资体系
    • 反脆弱
  • Git 参考手册
  • 提问的智慧
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
首页
  • 基础

    • 全栈之路
    • 😎Awesome资源
  • 进阶

    • Python 工匠系列
    • 高阶知识点
  • 指南教程

    • Socket 编程
    • 异步编程
    • PEP 系列
  • 面试

    • Python 面试题
    • 2025 面试记录
    • 2022 面试记录
    • 2021 面试记录
    • 2020 面试记录
    • 2019 面试记录
    • 数据库索引原理
  • 基金

    • 基金知识
    • 基金经理
  • 细读经典

    • 德隆-三个知道
    • 孔曼子-摊大饼理论
    • 配置者说-躺赢之路
    • 资水-建立自己的投资体系
    • 反脆弱
  • Git 参考手册
  • 提问的智慧
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 辨析

  • Sockets编程

  • Django

  • stackoverflow

  • Flask

  • 全栈之路

  • 面试

  • 代码片段

  • 异步编程

  • 😎Awesome资源

  • PEP

  • Python工匠系列

  • 高阶知识点

  • Python 学习资源待整理
  • 设计模式

    • Python 设计模式
    • 装饰器模式
    • 抽象工厂模式
    • 建造者模式/生成器模式
    • 原型模式
    • 单例模式
    • 设计模式(2)——工厂方法模式
    • 设计模式(3)——抽象工厂模式
      • 基本思想和原则
      • 动机
      • 实现
      • 优点
      • 缺点
    • 设计模式(4)——模板方法模式
    • 设计模式(5)——代理模式
    • 设计模式(6)——建造者模式
    • 设计模式(7)——策略模式
    • 设计模式(8)——命令模式
    • 设计模式(9)——原型模式
    • 设计模式(10)——中介者模式
    • 设计模式(11)——责任链模式
    • 设计模式(12)——装饰器模式
    • 设计模式(13)——适配器模式
    • 设计模式(14)——迭代器模式
    • 设计模式(15)——观察者模式
    • 设计模式(16)——外观模式
    • 设计模式(17)——状态模式
    • 设计模式(18)——桥接模式
    • 设计模式(19)——享元模式
    • 设计模式(20)——解释器模式
    • 设计模式(21)——组合模式
    • 设计模式(23)——备忘录模式
    • Python 全栈之路系列之单例设计模式
    • 设计模式(22)——访问者模式
    • 工厂方法模式
    • Python 设计模式资源收集
  • 好“艹蛋”的 Python 呀!
  • FIFO | 待学清单📝
  • pip 安装及使用
  • 数据分析

  • 源码阅读计划

  • OOP

  • 关于 python 中的 setup.py
  • 并行分布式框架 Celery
  • 七种武器,让你的代码提高可维护性
  • 使用 pdb 调试 Python 代码
  • 每周一个 Python 标准库
  • 🐍Python
  • 设计模式
佚名
2017-12-05
目录

设计模式(3)——抽象工厂模式

本文介绍抽象工厂模式的概念和应用。

# 基本思想和原则

为创建一组相关或相互依赖的对象提供一组接口,而且无须指定它们的具体类。

高层模块不应直接依赖低层模块,应该依赖其抽象,工厂就是这个抽象。

# 动机

让我们考虑产品族和产品类型这两个概念。举个产品族的例子,苹果和戴尔两家公司都生产计算机,计算机是一种统称,是一个抽象概念,这是产品族。其中计算机又可以分为服务器、台式机、笔记本等,这是计算机的类型,一个具体概念,这是产品类型。因此产品族和产品类型的对比如下表:

名称 抽象/具体 概念方向
产品族 抽象 横向
产品类型 具体 纵向

# 实现

public abstract class AppleComputer {
    public abstract void run();
}

public class AppleDesktop extends AppleComputer {
    @Override
    public void run() {
        System.out.println("AppleDesktop run!");
    }
}

public class AppleNotebook extends AppleComputer {
    @Override
    public void run() {
        System.out.println("AppleNotebook run!");
    }
}

public abstract class DellComputer {
    public abstract void run();
}

public class DellDesktop extends DellComputer {
    @Override
    public void run() {
        System.out.println("DellDeskComputer run!");
    }
}

public class DellNotebook extends DellComputer {
    @Override
    public void run() {
        System.out.println("DellNotebook run!");
    }
}

public abstract class ComputerFactory {
    public abstract AppleComputer createAppleComputer();
    public abstract DellComputer createDellComputer();
}

public class DesktopFactory extends ComputerFactory {
    @Override
    public AppleComputer createAppleComputer() {
        return new AppleDesktop();
    }

    @Override
    public DellComputer createDellComputer() {
        return new DellDesktop();
    }
}

public class NotebookFactory extends ComputerFactory {
    @Override
    public AppleComputer createAppleComputer() {
        return new AppleNotebook();
    }

    @Override
    public DellComputer createDellComputer() {
        return new DellNotebook();
    }
}

public class Test {
    public static void main(String[] args) {
        ComputerFactory desktopFactory = new DesktopFactory();
        ComputerFactory notebookFactory = new NotebookFactory();

        AppleComputer appleDesktop = desktopFactory.createAppleComputer();
        AppleComputer appleNotebook = notebookFactory.createAppleComputer();

        DellComputer dellDesktop = desktopFactory.createDellComputer();
        DellComputer dellNotebook = notebookFactory.createDellComputer();

        appleDesktop.run();
        appleNotebook.run();
        dellDesktop.run();
        dellNotebook.run();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82

运行后输出:

AppleDesktop run!
AppleNotebook run!
DellDeskComputer run!
DellNotebook run!
1
2
3
4

# 优点

封装性好,将高层模块和具体实现类解耦,高层模块不需要关心具体实现类的细节,只需要和工厂打交道,由工厂去创建对象。

# 缺点

抽象工厂模式很难对产品族进行扩展,来看看上面的例子如果要增加一个惠普品牌的计算机需要做哪些新增或修改:

  1. 新增HPDesktop类。
  2. 新增HPNotebook类。
  3. 修改ComputerFactory,在其中添加createHPComputer这个方法。
  4. 修改DesktopFactory,实现createHPComputer这个方法。
  5. 修改NotebookFactory,实现createHPComputer这个方法。

可以看到,2 个新增,3 个修改,工作量不仅很大,而且还要改动原来已经可以工作的类。也就是说,想要扩展产品族,就需要对原来的契约双方都做修改,很明显违反了开闭原则。

相反,使用抽象工厂模式对产品类型进行扩展要容易得多,上面的例子如果要增加一个服务器类型的计算机需要的新增或修改:

  1. 新增AppleServer类。
  2. 新增DellServer类。
  3. 新增ServerFactory类。

可以发现使用抽象工厂模式扩展产品类型都是新增,不需要修改原来的代码,符合开闭原则。

编辑 (opens new window)
#设计模式
上次更新: 2024-07-23, 01:00:43
设计模式(2)——工厂方法模式
设计模式(4)——模板方法模式

← 设计模式(2)——工厂方法模式 设计模式(4)——模板方法模式→

最近更新
01
2025 面试记录
05-28
02
提升沟通亲和力的实用策略
03-26
03
工作
07-15
更多文章>
Theme by Vdoing | Copyright © 2019-2025 IMOYAO | 别院牧志
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式