Java设计模式之抽象工厂模式详解

1.模式概述

抽象工厂模式(Abstract Factory Pattern)是创建型设计模式的集大成者,它通过提供接口创建相关或依赖对象的家族,而无需指定具体实现类。这种模式是工厂方法模式的升级版,核心区别在于它能创建多个产品族(一组相关产品),而非单一产品。

模式特点:

  • 创建产品家族而非单个产品
  • 高层抽象隔离具体实现
  • 符合开闭原则(扩展新产品族无需修改已有代码)
  • 符合单一职责原则(每个工厂只负责一个产品族)

2.适用场景

1. 跨平台UI开发:为不同操作系统(Windows/Mac/Linux)创建整套UI组件
2. 数据库访问层:支持多种数据库(MySQL/Oracle/PostgreSQL)的DAO工厂
3. 游戏开发:为不同阵营(人类/兽族)创建配套角色、建筑、武器
4. 主题切换:实现白天/夜间主题的颜色、字体、图标配套更换

客户端
抽象工厂
具体工厂1
具体工厂2
产品A1
产品B1
产品A2
产品B2

3.模式结构

UML类图

AbstractFactory
+createProductA() : AbstractProductA
+createProductB() : AbstractProductB
ConcreteFactory1
+createProductA() : ProductA1
+createProductB() : ProductB1
ConcreteFactory2
+createProductA() : ProductA2
+createProductB() : ProductB2
AbstractProductA
ProductA1
ProductA2
AbstractProductB
ProductB1
ProductB2
Client

4.代码实现

4.1 产品接口

// 按钮产品接口
interface Button {
    void render();
}

// 输入框产品接口
interface TextField {
    void input();
}

4.2 具体产品实现

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

class WinTextField implements TextField {
    @Override
    public void input() {
        System.out.println("Windows输入框获取内容");
    }
}

// Mac风格产品
class MacButton implements Button {
    @Override
    public void render() {
        System.out.println("渲染Mac风格按钮");
    }
}

class MacTextField implements TextField {
    @Override
    public void input() {
        System.out.println("Mac输入框获取内容");
    }
}

4.3 抽象工厂接口

interface GUIFactory {
    Button createButton();
    TextField createTextField();
}

4.4 具体工厂实现

// Windows工厂
class WinFactory implements GUIFactory {
    @Override
    public Button createButton() {
        return new WinButton();
    }

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

// Mac工厂
class MacFactory implements GUIFactory {
    @Override
    public Button createButton() {
        return new MacButton();
    }

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

4.5 客户端调用

public class Client {
    public static void main(String[] args) {
        // 根据配置选择工厂
        GUIFactory factory = createFactory("mac");
        
        // 创建成套UI组件
        Button button = factory.createButton();
        TextField textField = factory.createTextField();
        
        button.render();     // 输出: 渲染Mac风格按钮
        textField.input();    // 输出: Mac输入框获取内容
    }
    
    // 工厂选择器(可替换为配置文件读取)
    static GUIFactory createFactory(String osType) {
        switch (osType.toLowerCase()) {
            case "win": return new WinFactory();
            case "mac": return new MacFactory();
            default: throw new IllegalArgumentException("不支持的OS类型");
        }
    }
}

5.模式对比

模式关注点创建产品数量扩展方向
简单工厂单个具体产品1种产品修改工厂类
工厂方法单个抽象产品1种产品新增工厂子类
抽象工厂产品家族多种产品新增产品族

6.优缺点分析

✅ 优点:

  1. 保证产品族一致性(所有Mac组件风格统一)
  2. 客户端与具体产品解耦
  3. 新增产品族符合开闭原则
  4. 便于切换整个产品家族(只需更换工厂)

⛔ 缺点:

  1. 增加新产品种类困难(需修改所有工厂接口)
  2. 类结构复杂(需创建多个层次)
  3. 过度设计风险(简单场景不适用)

7.实际应用案例

7.1 Spring框架中的抽象工厂

// 定义数据访问抽象工厂
public interface DaoFactory {
    UserDao getUserDao();
    OrderDao getOrderDao();
}

// MySQL实现
public class MySQLDaoFactory implements DaoFactory {
    public UserDao getUserDao() {
        return new MySQLUserDao();
    }
    public OrderDao getOrderDao() {
        return new MySQLOrderDao();
    }
}

// MongoDB实现
public class MongoDbDaoFactory implements DaoFactory {
    public UserDao getUserDao() {
        return new MongoDBUserDao();
    }
    public OrderDao getOrderDao() {
        return new MongoDBOrderDao();
    }
}

// 通过@Bean配置工厂切换
@Configuration
public class AppConfig {
    @Bean
    public DaoFactory daoFactory() {
        return new MySQLDaoFactory(); // 只需修改此处切换数据库
    }
}

8.扩展技巧

1. 使用枚举简化工厂选择

public enum FactoryType {
    WINDOWS(WinFactory::new),
    MAC(MacFactory::new);
    
    private final Supplier<GUIFactory> constructor;
    
    FactoryType(Supplier<GUIFactory> constructor) {
        this.constructor = constructor;
    }
    
    public GUIFactory getFactory() {
        return constructor.get();
    }
}

// 使用方式
GUIFactory factory = FactoryType.MAC.getFactory();

2.结合单例模式管理工厂

public class MacFactory implements GUIFactory {
    private static final MacFactory INSTANCE = new MacFactory();
    
    private MacFactory() {} // 私有构造
    
    public static MacFactory getInstance() {
        return INSTANCE;
    }
    
    // ...其他方法
}

9.总结

抽象工厂模式是解决成套对象创建问题的终极方案,特别适合:

  • 需要确保产品兼容性的场景
  • 跨平台或多主题实现
  • 需要灵活切换整套组件的系统

💡 设计建议:当系统中产品种类稳定但产品族频繁变化时,抽象工厂是最佳选择。若产品种类常变,考虑使用其他创建型模式(如建造者模式)组合实现。

通过合理应用抽象工厂模式,可以显著提升系统的可扩展性和可维护性,实现"开箱即用"的产品族切换能力。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老鼠只爱大米

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值