java23种设计模式-抽象工厂模式

news/2025/2/26 5:11:28

抽象工厂模式(Abstract Factory Pattern)学习笔记

🌟 定义

抽象工厂模式属于创建型设计模式,提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。是工厂方法模式的升级版,支持多个产品族的创建。


🎯 适用场景

  1. 需要创建产品家族(多个关联产品)
  2. 系统要独立于产品的创建、组合和表示
  3. 需要确保产品之间的兼容性
  4. 需要切换不同产品系列
  5. 产品对象有多个创建约束条件

🔧 模式结构

📐 类图

«interface»
AbstractFactory
+createProductA() : AbstractProductA
+createProductB() : AbstractProductB
ConcreteFactory1
+createProductA() : AbstractProductA
+createProductB() : AbstractProductB
ConcreteFactory2
+createProductA() : AbstractProductA
+createProductB() : AbstractProductB
«interface»
AbstractProductA
+operationA()
ProductA1
+operationA()
ProductA2
+operationA()
«interface»
AbstractProductB
+operationB()
ProductB1
+operationB()
ProductB2
+operationB()

🛠️ 核心组成

  1. AbstractFactory(抽象工厂)

    • 声明创建产品族的方法集合
  2. ConcreteFactory(具体工厂)

    • 实现抽象工厂接口,创建特定产品族的对象
  3. AbstractProduct(抽象产品)

    • 定义产品接口,多个产品构成产品族
  4. ConcreteProduct(具体产品)

    • 实现抽象产品接口的具体类

📝 代码示例

跨平台UI组件案例

// 抽象产品:按钮
interface Button {
    void render();
}

// 具体产品:Windows按钮
class WindowsButton implements Button {
    @Override
    public void render() {
        System.out.println("渲染Windows风格按钮");
    }
}

// 具体产品:MacOS按钮
class MacOSButton implements Button {
    @Override
    public void render() {
        System.out.println("渲染MacOS风格按钮");
    }
}

// 抽象产品:文本框
interface TextField {
    void input();
}

// 具体产品:Windows文本框
class WindowsTextField implements TextField {
    @Override
    public void input() {
        System.out.println("Windows文本框输入");
    }
}

// 具体产品:MacOS文本框
class MacOSTextField implements TextField {
    @Override
    public void input() {
        System.out.println("MacOS文本框输入");
    }
}

// 抽象工厂
interface GUIFactory {
    Button createButton();
    TextField createTextField();
}

// 具体工厂:Windows组件工厂
class WindowsFactory implements GUIFactory {
    @Override
    public Button createButton() {
        return new WindowsButton();
    }

    @Override
    public TextField createTextField() {
        return new WindowsTextField();
    }
}

// 具体工厂:MacOS组件工厂
class MacOSFactory implements GUIFactory {
    @Override
    public Button createButton() {
        return new MacOSButton();
    }

    @Override
    public TextField createTextField() {
        return new MacOSTextField();
    }
}

// 客户端代码
public class Application {
    private Button button;
    private TextField textField;

    public Application(GUIFactory factory) {
        button = factory.createButton();
        textField = factory.createTextField();
    }

    public void renderUI() {
        button.render();
        textField.input();
    }

    public static void main(String[] args) {
        // 根据配置选择工厂
        GUIFactory factory = getOSFactory();
        Application app = new Application(factory);
        app.renderUI();
    }

    private static GUIFactory getOSFactory() {
        String osName = System.getProperty("os.name").toLowerCase();
        if (osName.contains("win")) {
            return new WindowsFactory();
        } else {
            return new MacOSFactory();
        }
    }
}

✅ 优点

  1. 产品族一致性:保证创建的对象相互兼容
  2. 切换产品族方便:只需更换具体工厂
  3. 解耦客户端与具体类:客户端只操作抽象接口
  4. 符合开闭原则(对扩展开放-新增产品族)
  5. 符合单一职责原则:将产品创建逻辑集中管理

⚠️ 缺点

  1. 扩展产品等级困难(对修改关闭-新增产品类型)
  2. 类数量膨胀(n个产品族×m个产品类型=n×m个类)
  3. 增加系统抽象性(需要先设计好产品结构)
  4. 需要提前预判产品变化方向

🔄 相关模式对比

模式区别
工厂方法模式单个产品等级 vs 多个产品等级
建造者模式分步构建复杂对象 vs 创建产品家族
原型模式克隆现有对象 vs 创建新对象系列

💡 实践建议

  1. 产品族设计原则

    • 同一产品族中的对象需要协同工作
    • 不同产品族的对象不应混合使用
  2. 层次结构管理

    // 使用Map维护工厂实例
    public class FactoryProducer {
        private static Map<String, GUIFactory> factories = new HashMap<>();
        
        static {
            factories.put("Windows", new WindowsFactory());
            factories.put("MacOS", new MacOSFactory());
        }
        
        public static GUIFactory getFactory(String type) {
            return factories.get(type);
        }
    }
    
  3. 扩展策略

    • 新增产品族:添加新工厂+对应产品实现
    • 新增产品类型:需要修改所有工厂接口(慎用)
  4. 组合使用技巧

    // 结合单例模式管理工厂
    class MacOSFactory {
        private static final MacOSFactory INSTANCE = new MacOSFactory();
        private MacOSFactory() {}
        public static MacOSFactory getInstance() { return INSTANCE; }
    }
    

🚀 典型应用

  1. 跨平台UI框架

    • Java AWT/Swing的Peer机制
    • Android/iOS跨平台开发
  2. 数据库访问层

    // 抽象产品:Connection/Statement
    interface DatabaseFactory {
        Connection createConnection();
        Statement createStatement();
    }
    
    // 具体产品:MySQL/Oracle实现
    
  3. 游戏引擎

    • 不同画风的角色/场景/道具组合
    • 不同物理引擎的实现组合
  4. 企业级中间件

    • 不同消息队列的Connection/Session组合
    • 不同云服务的存储/计算组件组合

📌 实现注意事项

  1. 空对象处理

    // 空产品实现示例
    class NullButton implements Button {
        @Override
        public void render() {
            // 无操作实现
        }
    }
    
  2. 参数化工厂

    // 通过枚举类型选择产品
    enum ThemeType { MATERIAL, FLAT, RETRO }
    
    class ThemeFactory {
        public static GUIFactory getFactory(ThemeType type) {
            switch(type) {
                case MATERIAL: return new MaterialFactory();
                case FLAT: return new FlatFactory();
                default: return new RetroFactory();
            }
        }
    }
    
  3. 组合产品创建

    // 创建关联产品组
    interface VehicleFactory {
        Engine createEngine();
        Wheel createWheel();
        Light createLight();
    }
    
    class CarFactory implements VehicleFactory {
        // 实现各部件创建方法
    }
    

掌握抽象工厂模式的关键在于理解产品族产品等级的关系,合理运用可以有效管理系统中的对象创建逻辑,特别适合需要保证产品兼容性和需要动态切换产品系列的复杂系统设计。


http://www.niftyadmin.cn/n/5867999.html

相关文章

【idea问题排查技巧】

以下是针对 IDEA 中 日志打标(动态标记) 和 全链路追踪 功能的分步详解,结合具体场景和操作截图说明,帮助快速掌握实战技巧。 一、动态日志打标:不修改代码输出关键信息 1. 断点日志打印(非侵入式打标) 场景:在调试时,需要临时查看某个变量的值,但不想修改代码添加…

在Spring Boot中如何使用Freemaker模板引擎

在 Spring Boot 中使用 FreeMarker 模板引擎可以帮助你创建动态的 Web 页面。以下是详细的步骤和示例代码,介绍如何在 Spring Boot 项目里集成和使用 FreeMarker。 1. 添加依赖 如果你使用的是 Maven 项目,需要在 pom.xml 文件中添加 FreeMarker 相关依赖。Spring Boot 提供…

Elasticsearch索引设计与分片策略深度优化-手记

一、索引设计的黄金法则&#xff08;从踩坑到精通的必经之路&#xff09; 1. 字段类型显式声明原则 动态映射是新手最易踩的坑&#xff0c;某金融平台曾因金额字段被自动识别为text类型&#xff0c;导致聚合查询时触发OOM。正确做法应显式声明核心字段&#xff1a; PUT /fin…

虚拟机中如何调整宿主机的交换空间设置

1. 增加交换空间 创建交换文件&#xff1a;例如创建一个 4GB 的交换文件。 sudo fallocate -l 4G /swapfile2. 设置交换文件权限 sudo chmod 600 /swapfile3. 将文件格式化为交换空间 sudo mkswap /swapfile4. 启用交换空间 sudo swapon /swapfile5. 使交换空间永久生效 …

Docker 2025/2/24

用来快速构建、运行和管理应用的工具。帮助部署。 快速入门 代码略 解释 docker run :创建并运行一个容器&#xff0c;-d是让容器在后台运行 --name mysql :给容器起个名字&#xff0c;必须唯一 -p 3306:3306 :设置端口映射 -e KEYVALUE :是设置环境变量 mysql :指定运行的…

Java入门级小案例:网页版简易计算器

网页版简易计算器 目录 网页版简易计算器需求&#xff1a;代码实现&#xff1a;效果显示 需求&#xff1a; 用HTML、CSS、JS进行书写一个具备一定功能的简易计算器。 代码实现&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta cha…

keycloak - 开发环境的配置持久化

keycloak - 开发环境的配置持久化 前情提要&#xff1a; Keycloak - docker 运行 & 前端集成 本来是想顺便试一下 Okta 集成的&#xff0c;但是发现 Okta 没有本地的 docker 镜像&#xff0c;他们毕竟是做 Identity as a service……算了…… 更新后的 docker compose 如…

zookeeper从入门到精通

一、入门基础 1.1 什么是 ZooKeeper ZooKeeper 是一个开源的分布式协调服务&#xff0c;由雅虎创建&#xff0c;后成为 Apache 的顶级项目。它为分布式应用提供了高效、可靠的协调服务&#xff0c;例如统一命名服务、配置管理、分布式锁、集群管理等。ZooKeeper 的数据模型类…