首页
技术小册
AIGC
面试刷题
技术文章
MAGENTO
云计算
视频课程
源码下载
PDF书籍
「涨薪秘籍」
登录
注册
设计模式概述
工厂方法
抽象工厂
生成器
原型
单例
适配器
桥接
组合
装饰器
外观
享元
代理
责任链
命令
迭代器
中介者
备忘录
观察者
状态
策略
模板方法
访问者
当前位置:
首页>>
技术小册>>
经典设计模式Java版
小册名称:经典设计模式Java版
**抽象工厂模式** 是一种创建型设计模式,它能创建一系列相关的对象,而无需指定其具体类。 ***** 假设你正在开发一款家具商店模拟器。你的代码中包括一些 类,用于表示: 1. 一系列相关产品, 例如 椅子 Chair 、 沙发 Sofa 和 咖啡桌 CoffeeTable 。 2. 系列产品的不同变体。 例如, 你可以使用 现代 Modern 、 维多利亚 Victorian 、 装饰风艺术 ArtDeco 等风格生成 椅子 、 沙发 和 咖啡桌 。 ![](images/1_1636253661011.png) 你需要设法单独生成每件家具对象,这样才能确保其风格一 致。如果顾客收到的家具风格不一样,他们可不会开心。 ![](images/1_1636253693191.png) 此外, 你也不希望在添加新产品或新风格时修改已有代码。 家具供应商对于产品目录的更新非常频繁,你不会想在每次 更新时都去修改核心代码的。 ***** **解决方案** 首先,抽象工厂模式建议为系列中的每件产品明确声明接口 (例如椅子、沙发或咖啡桌)。然后,确保所有产品变体都继 承这些接口。例如,所有风格的椅子都实现 椅子 接口;所 有风格的咖啡桌都实现 咖啡桌 接口,以此类推。 ![](images/1_1636253746562.png) 接下来,我们需要声明抽象工厂——包含系列中所有产品构 造方法的接口。例如 createChair 创建椅子 、 createSofa 创建沙发 和 createCoffeeTable 创建咖啡桌 。 这些方法必 须返回抽象产品类型,即我们之前抽取的那些接口: 椅子 , 沙发 和 咖啡桌 等等。 ![](images/1_1636253776412.png) 那 么 该 如 何 处 理 产 品 变 体 呢? 对 于 系 列 产 品 的 每 个 变 体, 我 们 都 将 基 于 抽象工厂 接 口 创 建 不 同 的 工 厂 类。 每 个 工 厂 类 都 只 能 返 回 特 定 类 别 的 产 品, 例 如, 现代家具工厂 ModernFurnitureFactory 只 能 创 建 现代椅子 ModernChair 、 现代沙发 ModernSofa 和 现代咖啡桌 ModernCoffeeTable 对象。 客户端代码可以通过相应的抽象接口调用工厂和产品类。你 无需修改实际客户端代码,就能更改传递给客户端的工厂类, 也能更改客户端代码接收的产品变体。 ![](images/1_1636253819936.png) 假设客户端想要工厂创建一把椅子。客户端无需了解工厂类, 也不用管工厂类创建出的椅子类型。无论是现代风格,还是 维多利亚风格的椅子,对于客户端来说没有分别,它只需调 用抽象 椅子 接口就可以了。这样一来,客户端只需知道椅 子以某种方式实现了 sitOn 坐下 方法就足够了。此外,无 论工厂返回的是何种椅子变体,它都会和由同一工厂对象创 建的沙发或咖啡桌风格一致。 最后一点说明:如果客户端仅接触抽象接口,那么谁来创建 实际的工厂对象呢?一般情况下,应用程序会在初始化阶段 创建具体工厂对象。而在此之前,应用程序必须根据配置文 件或环境设定选择工厂类别。 ***** ![](images/1_1636253881502.png) 1. 抽象产品(Abstract Product)为构成系列产品的一组不同但 相关的产品声明接口。 2. 具体产品(Concrete Product)是抽象产品的多种不同类型实 现。所有变体(维多利亚/现代)都必须实现相应的抽象产品 (椅子/沙发)。 3. 抽象工厂(Abstract Factory)接口声明了一组创建各种抽象 产品的方法。 4. 具体工厂(Concrete Factory)实现抽象工厂的构建方法。每 个具体工厂都对应特定产品变体,且仅创建此种产品变体。 5. 尽管具体工厂会对具体产品进行初始化,其构建方法签名必 须返回相应的抽象产品。这样,使用工厂类的客户端代码就 不会与工厂创建的特定产品变体耦合。客户端(Client)只 需通过抽象接口调用工厂和产品对象,就能与任何具体工厂/ 产品变体交互。 ***** ### **代码示例** JAVA版: ## 跨平台 GUI 组件系列及其创建方式 在本例中,按钮和复选框将被作为产品。它们有两个变体:macOS 版和 Windows 版。 抽象工厂定义了用于创建按钮和复选框的接口。而两个具体工厂都会返回同一变体的两个产品。 客户端代码使用抽象接口与工厂和产品进行交互。同样的代码能与依赖于不同工厂对象类型的多种产品变体进行交互。 **buttons:第一个产品层次结构** buttons/Button.java ``` package design_pattern.abstract_factory.example.buttons; /** * Abstract Factory assumes that you have several families of products, * structured into separate class hierarchies (Button/Checkbox). All products of * the same family have the common interface. * * This is the common interface for buttons family. */ public interface Button { void paint(); } ``` buttons/MacOSButton.java ``` package design_pattern.abstract_factory.example.buttons; /** * All products families have the same varieties (MacOS/Windows). * * This is a MacOS variant of a button. */ public class MacOSButton implements Button { @Override public void paint() { System.out.println("You have created MacOSButton."); } } ``` buttons/WindowsButton.java ``` package design_pattern.abstract_factory.example.buttons; /** * All products families have the same varieties (MacOS/Windows). * * This is another variant of a button. */ public class WindowsButton implements Button { @Override public void paint() { System.out.println("You have created WindowsButton."); } } ``` **buttons:第二个产品层次结构** checkboxes/Checkbox.java ``` package design_pattern.abstract_factory.example.checkboxes; /** * Checkboxes is the second product family. It has the same variants as buttons. */ public interface Checkbox { void paint(); } ``` checkboxes/MacOSCheckbox.java ``` package design_pattern.abstract_factory.example.checkboxes; /** * All products families have the same varieties (MacOS/Windows). * * This is a variant of a checkbox. */ public class MacOSCheckbox implements Checkbox { @Override public void paint() { System.out.println("You have created MacOSCheckbox."); } } ``` checkboxes/WindowsCheckbox.java ``` package design_pattern.abstract_factory.example.checkboxes; /** * All products families have the same varieties (MacOS/Windows). * * This is another variant of a checkbox. */ public class WindowsCheckbox implements Checkbox { @Override public void paint() { System.out.println("You have created WindowsCheckbox."); } } ``` **factories** factories/GUIFactory.java: 抽象工厂 ``` package design_pattern.abstract_factory.example.factories; import design_pattern.abstract_factory.example.buttons.Button; import design_pattern.abstract_factory.example.checkboxes.Checkbox; /** * Abstract factory knows about all (abstract) product types. */ public interface GUIFactory { Button createButton(); Checkbox createCheckbox(); } ``` factories/MacOSFactory.java: 具体工厂 ( macOS) ``` package design_pattern.abstract_factory.example.factories; import design_pattern.abstract_factory.example.buttons.Button; import design_pattern.abstract_factory.example.buttons.MacOSButton; import design_pattern.abstract_factory.example.checkboxes.Checkbox; import design_pattern.abstract_factory.example.checkboxes.MacOSCheckbox; /** * Each concrete factory extends basic factory and responsible for creating * products of a single variety. */ public class MacOSFactory implements GUIFactory { @Override public Button createButton() { return new MacOSButton(); } @Override public Checkbox createCheckbox() { return new MacOSCheckbox(); } } ``` factories/WindowsFactory.java: 具体工厂 (Windows) ``` package design_pattern.abstract_factory.example.factories; import design_pattern.abstract_factory.example.buttons.Button; import design_pattern.abstract_factory.example.buttons.WindowsButton; import design_pattern.abstract_factory.example.checkboxes.Checkbox; import design_pattern.abstract_factory.example.checkboxes.WindowsCheckbox; /** * Each concrete factory extends basic factory and responsible for creating * products of a single variety. */ public class WindowsFactory implements GUIFactory { @Override public Button createButton() { return new WindowsButton(); } @Override public Checkbox createCheckbox() { return new WindowsCheckbox(); } } ``` **app** ``` app/Application.java: 客户端代码 package design_pattern.abstract_factory.example.app; import design_pattern.abstract_factory.example.buttons.Button; import design_pattern.abstract_factory.example.checkboxes.Checkbox; import design_pattern.abstract_factory.example.factories.GUIFactory; /** * Factory users don't care which concrete factory they use since they work with * factories and products through abstract interfaces. */ public class Application { private Button button; private Checkbox checkbox; public Application(GUIFactory factory) { button = factory.createButton(); checkbox = factory.createCheckbox(); } public void paint() { button.paint(); checkbox.paint(); } } ``` Demo.java: 程序配置 ``` package design_pattern.abstract_factory.example; import design_pattern.abstract_factory.example.app.Application; import design_pattern.abstract_factory.example.factories.GUIFactory; import design_pattern.abstract_factory.example.factories.MacOSFactory; import design_pattern.abstract_factory.example.factories.WindowsFactory; /** * Demo class. Everything comes together here. */ public class Demo { /** * Application picks the factory type and creates it in run time (usually at * initialization stage), depending on the configuration or environment * variables. */ private static Application configureApplication() { Application app; GUIFactory factory; String osName = System.getProperty("os.name").toLowerCase(); if (osName.contains("mac")) { factory = new MacOSFactory(); app = new Application(factory); } else { factory = new WindowsFactory(); app = new Application(factory); } return app; } public static void main(String[] args) { Application app = configureApplication(); app.paint(); } } ``` **OutputDemo.txt:执行结果** ~~~ You create WindowsButton. You created WindowsCheckbox. ~~~ *****
上一篇:
工厂方法
下一篇:
生成器
该分类下的相关小册推荐:
Java高并发秒杀入门与实战
Java性能调优实战
Java并发编程
Java语言基础4-数组详解
Java语言基础11-Java中的泛型
Java语言基础16-JDK8 新特性
深入拆解 Java 虚拟机
Mybatis合辑5-注解、扩展、SQL构建
Mybatis合辑4-Mybatis缓存机制
Java必知必会-JDBC
JAVA 函数式编程入门与实践
Java语言基础3-流程控制