抽象工厂模式

点击阅读:设计模式系列文章


1. 抽象工厂模式的定义

抽象工厂模式(Abstract Factory Pattern) 是一种创建型设计模式,它的核心思想是: 提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

  1. 解决工厂方法模式只能创建单一产品的局限性。
  2. 支持创建产品家族,确保产品之间的兼容性。
  3. 客户端与具体产品类解耦,只依赖抽象接口。

核心概念:

  1. 产品族(Product Family):一组相关或相互依赖的产品对象
  2. 产品等级结构(Product Hierarchy):同一类产品的不同实现

2. 抽象工厂模式的结构

抽象工厂模式主要包含以下角色:

  • AbstractFactory(抽象工厂):定义创建一系列相关产品的接口。
  • ConcreteFactory(具体工厂):实现抽象工厂接口,创建特定产品族的所有产品。
  • AbstractProduct(抽象产品):定义产品对象的接口。
  • ConcreteProduct(具体产品):实现抽象产品接口,属于特定产品族。
txt 复制代码
Client
   |
AbstractFactory (抽象)
   |
ConcreteFactoryA --> ProductA1, ProductA2, ProductA3
ConcreteFactoryB --> ProductB1, ProductB2, ProductB3

特点

  • 每个具体工厂负责创建一个完整的产品族。
  • 产品族内的产品相互配合,保证兼容性。
  • 客户端只依赖抽象接口,不关心具体实现。

2.1 AbstractFactory 抽象工厂

java 复制代码
public interface GUIFactory {
    Button createButton();
    Checkbox createCheckbox();
    Menu createMenu();
}

2.2 ConcreteFactory 具体工厂

java 复制代码
public class WinFactory implements GUIFactory {
    @Override
    public Button createButton() {
        return new WinButton();
    }
    
    @Override
    public Checkbox createCheckbox() {
        return new WinCheckbox();
    }
    
    @Override
    public Menu createMenu() {
        return new WinMenu();
    }
}

public class MacFactory implements GUIFactory {
    @Override
    public Button createButton() {
        return new MacButton();
    }
    
    @Override
    public Checkbox createCheckbox() {
        return new MacCheckbox();
    }
    
    @Override
    public Menu createMenu() {
        return new MacMenu();
    }
}

2.3 AbstractProduct 抽象产品

java 复制代码
public interface Button {
    void render();
    void onClick();
}

public interface Checkbox {
    void render();
    void toggle();
}

public interface Menu {
    void render();
    void show();
}

2.4 ConcreteProduct 具体产品

java 复制代码
public class WinButton implements Button {
    @Override
    public void render() {
        System.out.println("渲染Windows风格按钮");
    }
    
    @Override
    public void onClick() {
        System.out.println("Windows按钮点击事件处理");
    }
}

public class MacButton implements Button {
    @Override
    public void render() {
        System.out.println("渲染Mac风格按钮");
    }
    
    @Override
    public void onClick() {
        System.out.println("Mac按钮点击事件处理");
    }
}

2.5 Client 客户端

java 复制代码
public class Application {
    private Button button;
    private Checkbox checkbox;
    private Menu menu;
    
    public Application(GUIFactory factory) {
        this.button = factory.createButton();
        this.checkbox = factory.createCheckbox();
        this.menu = factory.createMenu();
    }
    
    public void renderUI() {
        button.render();
        checkbox.render();
        menu.render();
    }
    
    public static void main(String[] args) {
        GUIFactory factory;
        String osName = System.getProperty("os.name").toLowerCase();
        
        if (osName.contains("win")) {
            factory = new WinFactory();
        } else if (osName.contains("mac")) {
            factory = new MacFactory();
        } else {
            throw new UnsupportedOperationException("不支持的操作系统");
        }
        
        Application app = new Application(factory);
        app.renderUI();
    }
}

3. 抽象工厂模式的优缺点

优点:

  1. 产品族一致性:确保创建的对象属于同一产品族,保证兼容性。
  2. 开闭原则:新增产品族无需修改已有代码,只需添加新的具体工厂。
  3. 客户端解耦:客户端只依赖抽象接口,不关心具体实现。
  4. 切换便捷:可以轻松切换整个产品家族。

缺点:

  1. 扩展产品等级困难:新增产品类型需要修改所有工厂接口和实现。
  2. 类数量膨胀:产品族数量×产品等级数量=类的总数量。
  3. 复杂性高:多重抽象增加理解和维护难度。
  4. 违反开闭原则:新增产品等级时需要修改抽象工厂接口。

4. 抽象工厂模式的设计思想

  • 产品族一致性:确保同一产品族内的产品相互兼容。

  • 接口隔离:客户端只依赖抽象工厂和抽象产品接口。

  • 开闭原则:对扩展开放(新增产品族),对修改关闭(已有代码)。

  • 依赖倒置:高层模块不依赖低层模块,都依赖抽象。

  • 单一职责:每个具体工厂只负责创建一个产品族。

5. 一些问题

Q1: 抽象工厂模式与工厂方法模式的区别是什么?

A1:

  • 工厂方法模式:一个工厂只创建一种产品,关注单个产品的创建
  • 抽象工厂模式:一个工厂创建一族相关产品,关注产品家族的创建
  • 核心区别:工厂方法强调"单一产品的多态创建",抽象工厂强调"产品族的一致性创建"
java 复制代码
// 工厂方法:每个工厂只创建一种产品
ButtonFactory -> Button
CheckboxFactory -> Checkbox

// 抽象工厂:每个工厂创建一族产品
WinFactory -> WinButton, WinCheckbox, WinMenu
MacFactory -> MacButton, MacCheckbox, MacMenu

Q2: 抽象工厂模式在什么场景下不适用?

  1. 单一产品创建

    • 解释:如果只需要创建单个产品,使用抽象工厂会增加不必要的复杂性。
    • 例子:只需要创建按钮组件,不需要整套UI组件时,用简单工厂或工厂方法更合适。
  2. 产品族不稳定

    • 解释:如果产品类型经常变化,抽象工厂的接口需要频繁修改。
    • 例子:UI组件库经常新增或删除组件类型,会导致所有工厂接口都需要修改。
  3. 性能敏感场景

    • 解释:多层抽象和工厂创建会带来额外的性能开销。
    • 例子:游戏引擎中的高频对象创建,直接new对象可能比工厂创建更高效。
  4. 产品间无关联性

    • 解释:如果产品之间没有关联性或兼容性要求,不需要产品族概念。
    • 例子:创建独立的工具类对象,它们之间没有配合关系。
相关推荐
chen_mangoo17 分钟前
HDMI简介
android·linux·驱动开发·单片机·嵌入式硬件
阿里-于怀20 分钟前
AgentScope AutoContextMemory:告别 Agent 上下文焦虑
android·java·数据库·agentscope
sxlishaobin33 分钟前
设计模式之模板方法模式
设计模式·模板方法模式
le16161641 分钟前
设计模式之单例模式
单例模式·设计模式
Larry_Yanan1 小时前
Qt安卓开发(三)双摄像头内嵌布局
android·开发语言·c++·qt·ui
粲然忧生1 小时前
腾讯云终端性能监控SDK正式上线,为鸿蒙开发适配保驾护航
android·腾讯云·harmonyos
我命由我123451 小时前
Kotlin 开发 - Kotlin Lambda 表达式返回值
android·java·开发语言·java-ee·kotlin·android studio·android-studio
Knight_AL1 小时前
从单例模式说起:Java 常见设计模式的理解与实践
java·单例模式·设计模式
a努力。1 小时前
中国电网Java面试被问:Dubbo的服务目录和路由链实现
java·开发语言·jvm·后端·面试·职场和发展·dubbo
Engineer邓祥浩1 小时前
设计模式学习(10) 23-8 装饰者模式
python·学习·设计模式