【设计模式】【3】抽象工厂

抽象工厂(Abstract Factory)

抽象工厂是一种创建型设计模式, 它能创建一系列相关的对象,而  无需指定其具体类。

案例说明

跨平台应用中的相同 UI 元素功能类似,但是在不同操作系统下的外观有一定差异。此外,你需要确保 UI 元素与当前操
作系统风格一致。你一定不希望在 Windows 系统下运行的应用程序中显示 macOS 的控件。抽象工厂接口声明一系列构建方法,
客户端代码可调用它们生成不同风格的 UI 元素。每个具体工厂对应特定操作系统,并负责生成符合该操作系统风格的 UI 元素。

UML图

在这里插入图片描述

  1. 抽象产品(Abstract Product)为构成系列产品的一组不同但 相关的产品声明接口。
  2. 具体产品(Concrete Product)是抽象产品的多种不同类型实 现。所有变体(维多利亚/现代)都必须实现相应的抽象产品 (椅子/沙发)。
  3. 抽象工厂(Abstract Factory)接口声明了一组创建各种抽象 产品的方法。
  4. 具体工厂(Concrete Factory)实现抽象工厂的构建方法。每 个具体工厂都对应特定产品变体,且仅创建此种产品变体。
  5. 尽管具体工厂会对具体产品进行初始化,其构建方法签名必 须返回相应的抽象产品。这样,使用工厂类的客户端代码就 不会与工厂创建的特定产品变体耦合。客户端(Client)只 需通过抽象接口调用工厂和产品对象,就能与任何具体工厂/ 产品变体交互。

核心代码

factory/Factory
/**
 * @author: ccyy
 * @create: 2021-10-12
 * @description: 抽象工厂接口声明了一组能返回不同抽象产品
 * 的方法。这些产品属于同一个系列且在高层主题或概念上具
 * 有相关性。 同系列的产品通常能相互搭配使用。
 * 系列产品可有多个变体,但不同变体的产品不能搭配使用。
 **/
public interface GUIFactory {
    Button createButton();
    Checkbox createCheckbox();
}

factory/MacFactory
/**
 * @author: ccyy
 * @create: 2021-10-12
 * @description:
 **/
public class MacFactory implements GUIFactory{
    @Override
    public Button createButton() {
        return new MacButton();
    }

    @Override
    public Checkbox createCheckbox() {
        return new MacCheckbox();
    }
}

factory/WinFactory
/**
 * @author: ccyy
 * @create: 2021-10-12
 * @description: 具体工厂可生成属于同一变体的系列产品。
 * 工厂会确保其创建的产品能相互搭配使用。
 * 具体工厂方法签名会返回一个抽象产品,
 * 但在方法内部则会对具体产品进行实例化。
 **/
public class WinFactory implements GUIFactory{
    @Override
    public Button createButton() {
        return new WinButton();
    }

    @Override
    public Checkbox createCheckbox() {
        return new WinCheckbox();
    }
}
project/Button
/**
 * @author: ccyy
 * @create: 2021-10-12
 * @description: 系列产品中的特定产品必须有一个基础接口。
 * 所有产品变体都必须实现这个接口。
 **/
public interface Button {
    void paint();
}

project/Checkbox
/**
 * @author: ccyy
 * @create: 2021-10-12
 * @description: 这是另一个产品的基础接口。
 * 所有产品都可以互动,
 * 但是只有相同具体变体的产品之间才能够正确地进行交互。
 **/
public interface Checkbox {
    void paint();
}

project/mac/MacButton
/**
 * @author: ccyy
 * @create: 2021-10-12
 * @description: mac按钮样式
 **/
public class MacButton implements Button {
    @Override
    public void paint() {
        System.out.println("---创建mac按钮");
    }
}

project/mac/MacCheckbox
/**
 * @author: ccyy
 * @create: 2021-10-12
 * @description: mac选择框样式
 **/
public class MacCheckbox implements Checkbox {
    @Override
    public void paint() {
        System.out.println("---创建mac选择框");
    }
}
project/win/WinButton
/**
 * @author: ccyy
 * @create: 2021-10-12
 * @description: window按钮样式
 **/
public class WinButton implements Button {

    /**
     * 根据 Windows 样式渲染按钮。
     */
    @Override
    public void paint() {
        System.out.println("---创建windows按钮");
    }
}

project/mac/WinCheckbox
/**
 * @author: ccyy
 * @create: 2021-10-12
 * @description: windows选择框样式
 **/
public class WinCheckbox implements Checkbox {
    @Override
    public void paint() {
        System.out.println("---创建windows选择框");
    }
}
Application
/**
 * @author: ccyy
 * @create: 2021-10-12
 * @description: 客户端代码仅通过抽象类型
 * (GUIFactory、Button 和 Checkbox)使用工厂和产品。
 * 这让你无需修改任何工厂或产品子类就能将其传递给客户端代码。
 **/
public class Application {
    private GUIFactory factory;

    public Application(GUIFactory factory) {
        this.factory = factory;
    }

    public void paint(){
        Button button = factory.createButton();
        Checkbox checkbox = factory.createCheckbox();
        button.paint();
        checkbox.paint();
    }
}
Main
/**
 * @author: ccyy
 * @create: 2021-10-12
 * @description: 测试
 **/
public class Main {
    public static void main(String[] args) {
//        创建windows组件
        System.out.println("-----创建windows");
        Application win = new Application(new WinFactory());
        win.paint();
//        创建mac组件
        System.out.println("-----创建mac");
        Application mac = new Application(new MacFactory());
        mac.paint();
    }
}

适用场景

如果代码需要与多个不同系列的相关产品交互,但是由于无 法提前获取相关信息,或者出于对未来扩展性的考虑,你不 希望代码基于产品的具体类进行构建,在这种情况下,你可 以使用抽象工厂。

如果你有一个基于一组抽象方法的类,且其主要功能因此变 得不明确,那么在这种情况下可以考虑使用抽象工厂模式。

优缺点

优点:

  • 你可以确保同一工厂生成的产品相互匹配。
  • 你可以避免客户端和具体产品代码的耦合。 单一职责原则。
  • 你可以将产品生成代码抽取到同一位置,使 得代码易于维护。
  • 开闭原则。向应用程序中引入新产品变体时,你无需修改客 户端代码。

缺点

​ 由于采用该模式需要向应用中引入众多接口和类,代码可能 会比之前更加复杂。

与其他模式的关系

  • 在许多设计工作的初期都会使用工厂方法(较为简单,而且 可以更方便地通过子类进行定制),随后演化为使用抽象工 厂、原型或生成器(更灵活但更加复杂)。
  • 生成器重点关注如何分步生成复杂对象。抽象工厂专门用于 生产一系列相关对象。抽象工厂会马上返回产品,生成器则 允许你在获取产品前执行一些额外构造步骤。
  • 抽象工厂模式通常基于一组工厂方法,但你也可以使用原型 模式来生成这些类的方法
  • 当只需对客户端代码隐藏子系统创建对象的方式时,你可以 使用抽象工厂来代替外观。
  • 你可以将抽象工厂和桥接搭配使用。如果由桥接定义的抽象 只能与特定实现合作,这一模式搭配就非常有用。在这种情 况下,抽象工厂可以对这些关系进行封装,并且对客户端代 码隐藏其复杂性。
  • 抽象工厂、生成器和原型都可以用单例来实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值