~/app/articles/NORMAL

cat article/33.md

抽象工厂模式 (Abstract Factory) 全面讲解

学习笔记
设计模式
抽象工厂模式
Java
面向对象
软件设计
编程模式

本文全面讲解了抽象工厂模式,包括其定义、核心思想、与工厂方法模式的区别、应用场景、结构以及具体实现。

date: 2025-06-22T19:31:00 tags:

  • 复习
  • Java
  • 面向对象

抽象工厂模式 (Abstract Factory) 全面讲解


1. 什么是抽象工厂模式?

抽象工厂模式是创建型设计模式,用于生产一系列相关或依赖的对象,而无需指定它们的具体类。

  • 核心思想:提供一个接口,用于创建多个产品族(如不同风格的UI组件:Windows/Mac按钮、文本框等)。
  • 类比:家具工厂生产整套家具(椅子+桌子+沙发),而不是单一产品。

🔹 和工厂方法模式的区别

模式工厂方法 (Factory Method)抽象工厂 (Abstract Factory)
目标创建单一产品(如Car)创建多个相关产品(如Car + Engine + Wheel)
层级一个方法对应一个产品一个工厂对应一个产品族

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

问题场景

假设需要开发一个跨平台UI库,支持Windows和Mac两种风格的按钮和文本框:

// 直接硬编码的问题:
Button winButton = new WinButton();
TextBox macTextBox = new MacTextBox();
// 问题:代码耦合,切换平台需要大量修改!

解决方案

用抽象工厂封装同一风格的所有组件创建,客户端只需切换工厂即可换整套风格。


3. 抽象工厂模式的结构

角色说明

  1. AbstractFactory(抽象工厂)
    • 声明创建一组产品的接口(如createButton(), createTextBox())。
  2. ConcreteFactory(具体工厂)
    • 实现抽象工厂,生产同一产品族的对象(如WinFactory生产Windows风格组件)。
  3. AbstractProduct(抽象产品)
    • 定义产品的接口(如Button、TextBox)。
  4. ConcreteProduct(具体产品)
    • 实现抽象产品(如WinButton、MacTextBox)。

4. 示例代码(跨平台UI组件)

步骤1:定义抽象产品

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

// 抽象产品:文本框
public interface TextBox {
    void show();
}

步骤2:定义具体产品

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

public class WinTextBox implements TextBox {
    @Override
    public void show() {
        System.out.println("Windows文本框");
    }
}

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

public class MacTextBox implements TextBox {
    @Override
    public void show() {
        System.out.println("Mac文本框");
    }
}

步骤3:定义抽象工厂

public interface GUIFactory {
    Button createButton();
    TextBox createTextBox();
}

步骤4:定义具体工厂

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

    @Override
    public TextBox createTextBox() {
        return new WinTextBox();
    }
}

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

    @Override
    public TextBox createTextBox() {
        return new MacTextBox();
    }
}

步骤5:客户端调用

public class Client {
    public static void main(String[] args) {
        // 只需切换工厂即可换整套UI风格
        GUIFactory factory = new MacFactory();  // 改为WinFactory即切换为Windows风格
        
        Button button = factory.createButton();
        TextBox textBox = factory.createTextBox();
        
        button.render();  // 输出:Mac按钮
        textBox.show();   // 输出:Mac文本框
    }
}

5. 关键点总结

  1. 适用场景:
    • 系统需要独立于产品的创建、组合和表示(如跨平台UI、游戏不同主题的地图/NPC)。
    • 强调一系列相关产品的一致性(如不能混用Windows按钮和Mac文本框)。
  2. 优点:
    • 客户端代码与具体类解耦。
    • 易于扩展新产品族(新增一个工厂即可)。
  3. 缺点:
    • 新增产品类型(如新增Checkbox)需要修改所有工厂接口。

6. 互动实践

问题1:以下代码是抽象工厂吗?为什么?

public class SimpleFactory {
    public Button createButton(String type) {
        if ("Win".equals(type)) return new WinButton();
        else if ("Mac".equals(type)) return new MacButton();
        return null;
    }
}

答案:不是!这是简单工厂,抽象工厂需要生产多个相关产品(如按钮+文本框)。

问题2:如何扩展支持Linux风格的UI?

任务:

  1. 新增LinuxButton和LinuxTextBox类。
  2. 新增LinuxFactory实现GUIFactory接口。

7. 考试练习题

题目1(概念题)

抽象工厂模式的主要作用是?
A. 创建单个对象
B. 创建一组相关对象
C. 替代继承
D. 优化算法性能

答案:B


题目2(代码填空)

补全抽象工厂模式的代码:

public interface FurnitureFactory {
    Chair createChair();
    Table ____();  // 填空1
}

public class ModernChair implements Chair { /*...*/ }
public class ModernTable implements Table { /*...*/ }

public class ModernFactory implements FurnitureFactory {
    @Override
    public Chair createChair() {
        return ____;  // 填空2
    }
    @Override
    public Table ____() {  // 填空3
        return new ModernTable();
    }
}

答案:

  1. createTable
  2. new ModernChair()
  3. createTable

题目3(设计题)

用抽象工厂模式设计一个游戏角色系统,包含:

  • 产品族:Warrior(战士)、Mage(法师)
  • 风格:Fantasy(奇幻风格)、SciFi(科幻风格)
    要求:画出类图并写出关键代码。

答案:

  • 抽象产品:Warrior、Mage接口。
  • 具体产品:FantasyWarrior、SciFiMage等。
  • 抽象工厂:CharacterFactory(含createWarrior()和createMage())。
  • 具体工厂:FantasyFactory、SciFiFactory。
$ comments --list (0)

// not signed in


// no comments yet