设计模式——抽象工厂模式

抽象工厂模式 (Abstract Factory Pattern)

什么是抽象工厂模式?

抽象工厂模式是一种创建型设计模式,它提供一个接口,用于创建相关或依赖对象族,而无需指定它们具体的类。

简单来说:抽象工厂模式就是创建一系列相关的对象,而不是单个对象。

生活中的例子

想象一家家具制造厂

  • 产品族:现代风格家具、古典风格家具
  • 产品等级:椅子、沙发、桌子
风格 椅子 沙发 桌子
现代风格 现代椅子 现代沙发 现代桌子
古典风格 古典椅子 古典沙发 古典桌子

抽象工厂模式可以确保:

  • 现代风格的椅子、沙发、桌子搭配在一起
  • 古典风格的椅子、沙发、桌子搭配在一起
  • 不会出现现代椅子配古典沙发的情况

为什么需要抽象工厂模式?

工厂方法模式的局限

工厂方法模式只能创建一种类型 的产品。如果需要创建多个相关产品,就需要多个工厂,这样会导致:

  1. 工厂类数量爆炸:每种产品都需要一个工厂
  2. 产品族无法保证一致性:可能创建出不匹配的产品组合

抽象工厂模式的优势

  1. 产品族一致性:确保创建的产品属于同一个产品族
  2. 代码解耦:客户端不需要知道具体创建的是哪个产品族
  3. 易于扩展:新增产品族时,只需新增对应的工厂类

抽象工厂模式的结构

复制代码
┌─────────────────────────┐
│   AbstractFactory        │  抽象工厂
├─────────────────────────┤
│ + createProductA(): A    │
│ + createProductB(): B    │
│ + createProductC(): C    │
└──────────┬──────────────┘
           │ 继承
           ├──┬──────────────────┬──────────────┐
           │                    │              │
┌──────────┴──────────┐  ┌───────┴───────────┐  ┌───┴────────┐
│ ConcreteFactory1    │  │ ConcreteFactory2 │  │ ...       │  具体工厂
└─────────────────────┘  └───────────────────┘  └────────────┘

┌─────────────────────────┐
│   AbstractProductA      │  抽象产品A
├─────────────────────────┤
│ + operation(): void     │
└──────────┬──────────────┘
           │ 继承
           ├──┬──────────────────┬──────────────┐
           │                    │              │
┌──────────┴──────────┐  ┌───────┴───────────┐  ┌───┴────────┐
│ ProductA1           │  │ ProductA2         │  │ ...       │  具体产品A
└─────────────────────┘  └───────────────────┘  └────────────┘

┌─────────────────────────┐
│   AbstractProductB      │  抽象产品B
├─────────────────────────┤
│ + operation(): void     │
└──────────┬──────────────┘
           │ 继承
           ├──┬──────────────────┬──────────────┐
           │                    │              │
┌──────────┴──────────┐  ┌───────┴───────────┐  ┌───┴────────┐
│ ProductB1           │  │ ProductB2         │  │ ...       │  具体产品B
└─────────────────────┘  └───────────────────┘  └────────────┘

代码示例

1. 定义抽象产品

java 复制代码
// 抽象产品:形状接口
public interface Shape {
    /**
     * 绘制形状
     */
    void draw();
}

// 抽象产品:颜色接口
public interface Color {
    /**
     * 填充颜色
     */
    void fill();
}

2. 定义具体产品

java 复制代码
// 具体产品:圆形
public class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("绘制圆形");
    }
}

// 具体产品:矩形
public class Rectangle implements Shape {
    @Override
    public void draw() {
        System.out.println("绘制矩形");
    }
}

// 具体产品:正方形
public class Square implements Shape {
    @Override
    public void draw() {
        System.out.println("绘制正方形");
    }
}

// 具体产品:红色
public class Red implements Color {
    @Override
    public void fill() {
        System.out.println("填充红色");
    }
}

// 具体产品:绿色
public class Green implements Color {
    @Override
    public void fill() {
        System.out.println("填充绿色");
    }
}

// 具体产品:蓝色
public class Blue implements Color {
    @Override
    public void fill() {
        System.out.println("填充蓝色");
    }
}

3. 定义抽象工厂

java 复制代码
/**
 * 抽象工厂:形状和颜色工厂
 * 定义了创建形状和颜色的抽象方法
 */
public interface AbstractFactory {
    /**
     * 创建形状
     * @param shapeType 形状类型
     * @return 形状实例
     */
    Shape getShape(String shapeType);
    
    /**
     * 创建颜色
     * @param colorType 颜色类型
     * @return 颜色实例
     */
    Color getColor(String colorType);
}

4. 定义具体工厂

java 复制代码
/**
 * 具体工厂:形状工厂
 * 负责创建各种形状
 */
public class ShapeFactory implements AbstractFactory {
    
    @Override
    public Shape getShape(String shapeType) {
        if (shapeType == null) {
            return null;
        }
        
        if (shapeType.equalsIgnoreCase("CIRCLE")) {
            return new Circle();
        } else if (shapeType.equalsIgnoreCase("RECTANGLE")) {
            return new Rectangle();
        } else if (shapeType.equalsIgnoreCase("SQUARE")) {
            return new Square();
        }
        
        return null;
    }
    
    @Override
    public Color getColor(String colorType) {
        // 形状工厂不负责创建颜色
        return null;
    }
}

/**
 * 具体工厂:颜色工厂
 * 负责创建各种颜色
 */
public class ColorFactory implements AbstractFactory {
    
    @Override
    public Shape getShape(String shapeType) {
        // 颜色工厂不负责创建形状
        return null;
    }
    
    @Override
    public Color getColor(String colorType) {
        if (colorType == null) {
            return null;
        }
        
        if (colorType.equalsIgnoreCase("RED")) {
            return new Red();
        } else if (colorType.equalsIgnoreCase("GREEN")) {
            return new Green();
        } else if (colorType.equalsIgnoreCase("BLUE")) {
            return new Blue();
        }
        
        return null;
    }
}

5. 定义工厂生产者

java 复制代码
/**
 * 工厂生产者:工厂创建器
 * 根据传入的类型返回相应的工厂
 */
public class FactoryProducer {
    
    /**
     * 获取工厂
     * @param choice 工厂类型
     * @return 工厂实例
     */
    public static AbstractFactory getFactory(String choice) {
        if (choice.equalsIgnoreCase("SHAPE")) {
            return new ShapeFactory();
        } else if (choice.equalsIgnoreCase("COLOR")) {
            return new ColorFactory();
        }
        
        return null;
    }
}

6. 使用工厂

java 复制代码
/**
 * 抽象工厂模式演示类
 * 演示如何使用抽象工厂模式创建形状和颜色
 */
public class AbstractFactoryPatternDemo {
    
    public static void main(String[] args) {
        System.out.println("=== 抽象工厂模式演示 - 形状和颜色 ===\n");
        
        // 获取形状工厂
        AbstractFactory shapeFactory = FactoryProducer.getFactory("SHAPE");
        
        // 获取颜色工厂
        AbstractFactory colorFactory = FactoryProducer.getFactory("COLOR");
        
        // 创建形状
        System.out.println("--- 绘制形状 ---");
        Shape shape1 = shapeFactory.getShape("CIRCLE");
        shape1.draw();
        
        Shape shape2 = shapeFactory.getShape("RECTANGLE");
        shape2.draw();
        
        Shape shape3 = shapeFactory.getShape("SQUARE");
        shape3.draw();
        
        // 创建颜色
        System.out.println("\n--- 填充颜色 ---");
        Color color1 = colorFactory.getColor("RED");
        color1.fill();
        
        Color color2 = colorFactory.getColor("GREEN");
        color2.fill();
        
        Color color3 = colorFactory.getColor("BLUE");
        color3.fill();
        
        System.out.println("\n=== 抽象工厂模式的优势 ===");
        System.out.println("1. 产品族一致性:可以创建相关的对象族");
        System.out.println("2. 代码解耦:客户端不需要知道具体创建的是哪个产品");
        System.out.println("3. 易于扩展:新增产品族时,只需新增对应的工厂类");
        
        System.out.println("\n=== 实际应用场景 ===");
        System.out.println("1. UI组件库:不同风格的按钮、文本框、菜单");
        System.out.println("2. 数据库访问:不同数据库的连接、命令、参数");
        System.out.println("3. 游戏开发:不同风格的道具、角色、场景");
        System.out.println("4. 配置管理:不同环境的配置对象");
        
        System.out.println("\n=== 与工厂方法的区别 ===");
        System.out.println("工厂方法:创建单个对象");
        System.out.println("抽象工厂:创建对象族(多个相关对象)");
        
        System.out.println("\n=== 扩展性说明 ===");
        System.out.println("新增形状:只需在ShapeFactory中添加新的形状类");
        System.out.println("新增颜色:只需在ColorFactory中添加新的颜色类");
        System.out.println("新增产品族:需要修改AbstractFactory接口和所有工厂类");
    }
}

抽象工厂模式的优点

  1. 产品族一致性:确保创建的产品属于同一个产品族
  2. 代码解耦:客户端与具体产品解耦
  3. 易于扩展:新增产品族时,只需新增对应的工厂类
  4. 符合开闭原则:对扩展开放,对修改关闭

抽象工厂模式的缺点

  1. 扩展困难:新增产品等级(新增产品类型)需要修改所有工厂类
  2. 类数量爆炸:每增加一个产品族,就需要增加多个产品类
  3. 系统复杂度增加:引入了多个抽象层,增加了系统的理解难度

适用场景

  1. 需要创建产品族:需要创建一系列相关的对象
  2. 产品族需要一致性:确保创建的产品属于同一个产品族
  3. 系统独立于产品的创建:客户端不依赖具体产品的创建细节
  4. 多个产品族:系统有多个产品族,且产品族可能继续增加

常见应用场景

  • 跨平台UI开发:Windows风格、Mac风格、Linux风格
  • 数据库访问:MySQL、Oracle、PostgreSQL的连接和命令
  • 游戏开发:不同风格的道具、角色、场景
  • 配置管理:不同环境(开发、测试、生产)的配置

与工厂方法的区别

特性 工厂方法 抽象工厂
创建对象 单个对象 对象族(多个相关对象)
工厂数量 多个工厂(每个产品一个) 多个工厂(每个产品族一个)
产品类型 一种产品 多种相关产品
扩展性 新增产品容易 新增产品族容易,新增产品类型困难
复杂度 较简单 较复杂

使用建议

  • 需要创建单个产品:使用工厂方法模式
  • 需要创建产品族:使用抽象工厂模式
  • 产品族固定,产品类型可能增加:考虑使用其他模式
  • 产品类型固定,产品族可能增加:使用抽象工厂模式

注意事项

⚠️ 抽象工厂模式虽然强大,但不要滥用:

  • 如果产品族很少(1-2个),可以考虑使用工厂方法模式
  • 如果产品类型很少(1-2个),可以考虑使用工厂方法模式
  • 抽象工厂模式会增加类的数量,要权衡利弊
  • 新增产品类型时,需要修改所有工厂类,违反开闭原则
相关推荐
国强_dev15 小时前
量体裁衣在技术方案中的应用
设计模式·系统架构
Engineer邓祥浩17 小时前
设计模式学习(16) 23-14 命令模式
学习·设计模式·命令模式
Maddie_Mo18 小时前
智能体设计模式 第二章:路由模式
设计模式
一条闲鱼_mytube21 小时前
智能体设计模式(五)人机协同-知识检索RAG-智能体间通信
网络·人工智能·设计模式
小码过河.21 小时前
设计模式——建造者模式
单片机·设计模式·建造者模式
小码过河.1 天前
设计模式——工厂方法模式
设计模式·工厂方法模式
把csdn当日记本的菜鸡1 天前
Java设计模式简单入门
java·开发语言·设计模式
老蒋每日coding1 天前
AI Agent 设计模式系列(十一)—— 目标设定和监控模式
人工智能·设计模式·langchain
蔺太微1 天前
外观模式(Facade Pattern)
设计模式·外观模式