抽象工厂模式 logo

抽象工厂模式

Organization
microwind
抽象工厂模式

为一族相关对象的创建提供一致的接口,无需指定其具体类。

Overview

Publishermicrowind
Repositoryai-skills
Skill name抽象工厂模式
Stars
93
Forks
25
Bundled files
3
LicenseMIT
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • 3 bundled files

    Scripts, templates, and references the model can read while it works. Files are read-only and never executed.

  • Open source

    Published by microwind on GitHub. Read the source before you install it.

Installation

Install the 抽象工厂模式 AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/microwind/ai-skills/tree/main/design-patterns/abstract-factory-pattern
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/microwind/ai-skills.git /tmp/ai-skills
mkdir -p .claude/skills
cp -r /tmp/ai-skills/design-patterns/abstract-factory-pattern .claude/skills/microwind-22
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable 抽象工厂模式 in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads 抽象工厂模式 on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so 抽象工厂模式 is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

抽象工厂模式 (Abstract Factory Pattern)

核心概念

Abstract Factory是一种创建型设计模式,用于创建一族相关对象的集合,而不是单个对象。它在工厂方法之上进行了抽象,提供接口定义一系列产品族的创建。

核心原则:

  • 隐藏产品族的创建复杂性
  • 保证产品族的一致性
  • 支持产品族的灵活切换
  • 将产品族的创建逻辑集中管理

关键术语:

  • 产品族 (Product Family) - 相关产品的集合(如 Windows UI族包含Button、Window、TextBox)
  • 抽象工厂 (Abstract Factory) - 定义创建产品族接口
  • 具体工厂 (Concrete Factory) - 实现具体产品族创建

何时使用 - 触发模式

始终使用:

  • 系统需要支持多个相关对象的集合(产品族)
  • 需要在多个产品族之间灵活切换
  • 希望保证一个产品族内产品的一致性
  • 产品族的创建逻辑复杂/分散在多处

触发短语:

  • "如何创建一组相关/相通的对象?"
  • "需要支持多个主题/风格/变体,且每个涉及多个对象"
  • "如何保证选定的产品都来自同一个族?"
  • "产品族涉及多个维度的变化"

典型场景:

场景产品族工厂
UI 组件系统{Windows Button, Window, Dialog} vs {Mac Button, Window, Dialog}WindowsUIFactory vs MacUIFactory
数据库方言{MySQL SQL, Optimizer, Connection} vs {PostgreSQL ...}MySQLDialectFactory vs PostgresDialectFactory
游戏渲染引擎{DirectX Texture, Shader, Buffer} vs {OpenGL ...}DirectXFactory vs OpenGLFactory
操作系统适配{Windows FileSystem, Registry, Process} vs {Linux ...}WindowsAdapterFactory vs LinuxAdapterFactory

4个实现方法详解

方法1: 简单抽象工厂 (Simple Abstract Factory)

最直接的实现方式 - 为产品族定义接口,具体工厂实现。

java
// 产品接口
public interface Button {
    void render();
    void click();
}

public interface TextField {
    void render();
    void setText(String text);
}

// 产品实现 - Windows 族
public class WindowsButton implements Button {
    @Override
    public void render() { System.out.println("🪟 Rendering Windows Button"); }
    
    @Override
    public void click() { System.out.println("Windows Button clicked"); }
}

public class WindowsTextField implements TextField {
    @Override
    public void render() { System.out.println("🪟 Rendering Windows TextField"); }
    
    @Override
    public void setText(String text) { System.out.println("Windows TextField: " + text); }
}

// 产品实现 - Mac 族
public class MacButton implements Button {
    @Override
    public void render() { System.out.println("🍎 Rendering Mac Button"); }
    
    @Override
    public void click() { System.out.println("Mac Button clicked"); }
}

public class MacTextField implements TextField {
    @Override
    public void render() { System.out.println("🍎 Rendering Mac TextField"); }
    
    @Override
    public void setText(String text) { System.out.println("Mac TextField: " + text); }
}

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

// 具体工厂 - Windows
public class WindowsUIFactory implements UIFactory {
    @Override
    public Button createButton() {
        return new WindowsButton();
    }
    
    @Override
    public TextField createTextField() {
        return new WindowsTextField();
    }
}

// 具体工厂 - Mac
public class MacUIFactory implements UIFactory {
    @Override
    public Button createButton() {
        return new MacButton();
    }
    
    @Override
    public TextField createTextField() {
        return new MacTextField();
    }
}

// 使用
public class Application {
    private UIFactory factory;
    
    public Application(UIFactory factory) {
        this.factory = factory;
    }
    
    public void renderUI() {
        Button button = factory.createButton();
        TextField textField = factory.createTextField();
        
        button.render();
        textField.render();
    }
    
    public static void main(String[] args) {
        // 根据配置选择工厂
        String os = System.getProperty("os.name");
        UIFactory factory = os.contains("Windows") 
            ? new WindowsUIFactory()
            : new MacUIFactory();
        
        Application app = new Application(factory);
        app.renderUI();
    }
}

优点: 结构清晰,易于理解和维护 缺点: 添加新产品族需要创建多个新类


方法2: 配置驱动型工厂 (Configuration-Driven Factory)

使用配置或反射动态决定使用哪个产品族,减少硬编码。

java
public class ConfigurableUIFactory implements UIFactory {
    private String platform;
    private Map<String, Class<?>> productRegistry;
    
    public ConfigurableUIFactory(String platform) {
        this.platform = platform;
        this.productRegistry = new HashMap<>();
        loadConfiguration(platform);
    }
    
    private void loadConfiguration(String platform) {
        // 从配置文件加载
        if ("WINDOWS".equalsIgnoreCase(platform)) {
            productRegistry.put("Button", WindowsButton.class);
            productRegistry.put("TextField", WindowsTextField.class);
        } else if ("MAC".equalsIgnoreCase(platform)) {
            productRegistry.put("Button", MacButton.class);
            productRegistry.put("TextField", MacTextField.class);
        }
    }
    
    @Override
    public Button createButton() {
        try {
            Class<?> clazz = productRegistry.get("Button");
            return (Button) clazz.getDeclaredConstructor().newInstance();
        } catch (Exception e) {
            throw new RuntimeException("Failed to create Button", e);
        }
    }
    
    @Override
    public TextField createTextField() {
        try {
            Class<?> clazz = productRegistry.get("TextField");
            return (TextField) clazz.getDeclaredConstructor().newInstance();
        } catch (Exception e) {
            throw new RuntimeException("Failed to create TextField", e);
        }
    }
}

优点: 通过配置切换产品族,无需重新编译 缺点: 运行时反射开销,异常处理复杂


方法3: 单例结合的工厂 (Singleton-Combined Factory)

确保每个产品族的工厂只有一个实例(资源共享)。

java
public class SingletonUIFactory {
    private static final Map<String, UIFactory> instances = new HashMap<>();
    
    static {
        instances.put("WINDOWS", new WindowsUIFactory());
        instances.put("MAC", new MacUIFactory());
    }
    
    private SingletonUIFactory() {}
    
    public static UIFactory getInstance(String platform) {
        UIFactory factory = instances.get(platform);
        if (factory == null) {
            throw new IllegalArgumentException("Unknown platform: " + platform);
        }
        return factory;
    }
    
    // 获取当前系统的工厂
    public static UIFactory getCurrentFactory() {
        String os = System.getProperty("os.name");
        return getInstance(os.contains("Windows") ? "WINDOWS" : "MAC");
    }
}

// 使用
UIFactory factory = SingletonUIFactory.getCurrentFactory();

优点: 资源共享,单一全局访问点 缺点: 全局性可能导致测试困难


方法4: 动态注册工厂 (Dynamic Registry Factory)

允许在运行时注册和注销产品族,支持插件化架构。

java
public class PluggableUIFactory implements UIFactory {
    private static final Map<String, UIFactory> registry = new ConcurrentHashMap<>();
    private String platformId;
    
    // 动态注册工厂
    public static void register(String platformId, UIFactory factory) {
        registry.put(platformId, factory);
        System.out.println("Registered factory for: " + platformId);
    }
    
    // 动态注销工厂
    public static void unregister(String platformId) {
        registry.remove(platformId);
        System.out.println("Unregistered factory for: " + platformId);
    }
    
    public PluggableUIFactory(String platformId) {
        if (!registry.containsKey(platformId)) {
            throw new IllegalArgumentException("No factory registered for: " + platformId);
        }
        this.platformId = platformId;
    }
    
    @Override
    public Button createButton() {
        return registry.get(platformId).createButton();
    }
    
    @Override
    public TextField createTextField() {
        return registry.get(platformId).createTextField();
    }
}

// 使用
public class Main {
    public static void main(String[] args) {
        // 在运行时注册工厂
        PluggableUIFactory.register("WINDOWS", new WindowsUIFactory());
        PluggableUIFactory.register("MAC", new MacUIFactory());
        
        // 使用注册的工厂
        UIFactory factory = new PluggableUIFactory("WINDOWS");
        Button button = factory.createButton();
        button.render();
        
        // 动态添加新的产品族
        PluggableUIFactory.register("LINUX", new LinuxUIFactory());
    }
}

优点: 高度灵活,支持运行时插件 缺点: 复杂度高,需要仔细管理注册表


常见问题与解决方案

❌ 问题1: 产品族的管理和扩展

症状: 添加新的产品族时,需要修改多个地方;添加新的产品类型时,需要修改所有工厂类。

根本原因: 产品族边界不清晰,扩展点不明确。

解决方案:

java
// ✅ 改进:使用Builder模式来管理产品族的复杂构建
public class UIFactoryBuilder {
    private Map<String, Class<?>> buttonImpls = new HashMap<>();
    private Map<String, Class<?>> textFieldImpls = new HashMap<>();
    
    public UIFactoryBuilder registerButton(String platform, Class<?> impl) {
        buttonImpls.put(platform, impl);
        return this;
    }
    
    public UIFactoryBuilder registerTextField(String platform, Class<?> impl) {
        textFieldImpls.put(platform, impl);
        return this;
    }
    
    public UIFactory build(String platform) {
        return new ConfigurableUIFactory(platform, buttonImpls, textFieldImpls);
    }
}

// 使用
UIFactory factory = new UIFactoryBuilder()
    .registerButton("WINDOWS", WindowsButton.class)
    .registerTextField("WINDOWS", WindowsTextField.class)
    .build("WINDOWS");

❌ 问题2: 产品族一致性保证

症状: 某个工厂返回的产品来自不同的族(混杂),导致风格不一致。

根本原因: 工厂实现不规范,产品隔离不足。

解决方案:

java
// ✅ 使用版本控制和验证确保一致性
public abstract class BaseUIFactory implements UIFactory {
    protected String version;
    
    public BaseUIFactory(String version) {
        this.version = version;
    }
    
    // 验证产品一致性
    protected final void validateConsistency(Button button, TextField textField) {
        if (!button.getVersion().equals(textField.getVersion())) {
            throw new IllegalStateException(
                "Inconsistent product family: " + 
                button.getVersion() + " vs " + textField.getVersion()
            );
        }
    }
}

public class ConsistentWindowsUIFactory extends BaseUIFactory {
    public ConsistentWindowsUIFactory() {
        super("1.0");
    }
    
    @Override
    public Button createButton() {
        return new VersionedWindowsButton("1.0");
    }
    
    @Override
    public TextField createTextField() {
        return new VersionedWindowsTextField("1.0");
    }
}

❌ 问题3: 产品族扩展成本

症状: 添加新的产品类型时,需要修改所有工厂类;代码改动范围大,容易引入Bug。

根本原因: 产品族的接口设计不够灵活。

解决方案:

java
// ✅ 使用组合和装饰器扩展产品族
public interface UIProduct {
    String getType();
    void render();
}

public class ProductFactory {
    private UIFactory delegate;
    private List<ProductDecorator> decorators;
    
    public ProductFactory(UIFactory delegate) {
        this.delegate = delegate;
        this.decorators = new ArrayList<>();
    }
    
    public ProductFactory addDecorator(ProductDecorator decorator) {
        decorators.add(decorator);
        return this;
    }
    
    public Button createButton() {
        Button button = delegate.createButton();
        for (ProductDecorator decorator : decorators) {
            button = decorator.decorate(button);
        }
        return button;
    }
}

// 新增产品类型无需修改工厂
public interface ProductDecorator {
    Button decorate(Button button);
}

public class TooltipDecorator implements ProductDecorator {
    @Override
    public Button decorate(Button button) {
        return new TooltipButton(button);
    }
}

❌ 问题4: 产品序列化和反序列化

症状: 需要保存和恢复产品状态,但工厂创建的对象难以序列化。

根本原因: 序列化信息不完整或工厂引用无法恢复。

解决方案:

java
// ✅ 实现序列化工厂
public class SerializableUIFactory implements UIFactory, Serializable {
    private String platformId;
    
    public SerializableUIFactory(String platformId) {
        this.platformId = platformId;
    }
    
    @Override
    public Button createButton() {
        Button button = getPlatformFactory().createButton();
        return new SerializableButton(button, platformId);
    }
    
    @Override
    public TextField createTextField() {
        TextField field = getPlatformFactory().createTextField();
        return new SerializableTextField(field, platformId);
    }
    
    private UIFactory getPlatformFactory() {
        if ("WINDOWS".equals(platformId)) {
            return new WindowsUIFactory();
        }
        return new MacUIFactory();
    }
}

public class SerializableButton implements Button, Serializable {
    private Button delegate;
    private String platformId;
    
    // 序列化后可通过工厂恢复
    private void readObject(java.io.ObjectInputStream in) 
            throws IOException, ClassNotFoundException {
        in.defaultReadObject();
        this.delegate = SerializableUIFactory.getInstance(platformId).createButton();
    }
}

与其他模式的关系

模式关系使用场景差异
工厂方法Abstract Factory 通常使用工厂方法创建产品工厂方法:单个产品;Abstract Factory:产品族
单例常结合使用,确保工厂唯一性需要全局一致性时组合使用
生成器可用于复杂产品族的创建产品族构建复杂时结合使用
适配器用于兼容旧系统的产品族需要与既有系统集成时使用
装饰器可用于扩展产品族功能需要动态添加产品功能时组合使用

最佳实践

✅ 清晰的产品族定义 - 明确界定哪些产品属于一个族
✅ 版本管理 - 为产品族版本化,避免混杂
✅ 配置化 - 优先使用配置而非硬编码决定工厂选择
✅ 一致性保证 - 在工厂中验证产品一致性
✅ 扩展点清晰 - 明确新产品类型的添加流程
✅ 避免过度设计 - 产品族较少时不必使用


何时避免使用

❌ 系统只有单个产品(使用工厂方法)
❌ 产品家族变化频繁且无规律(可能设计不当)
❌ 产品间没有明显关联(可能不算一个族)
❌ 过度预测未来需求(导致过度设计)


真实使用场景

场景1: 数据库方言工厂

java
public interface SQLDialect {
    String getDateFormatFunction();
    String getPageClause(long offset, long limit);
    String getCountQuery(String sql);
}

public class MySQLDialect implements SQLDialect {
    @Override
    public String getDateFormatFunction() { return "DATE_FORMAT"; }
    
    @Override
    public String getPageClause(long offset, long limit) {
        return "LIMIT " + offset + ", " + limit;
    }
    
    @Override
    public String getCountQuery(String sql) {
        return "SELECT COUNT(*) FROM (" + sql + ")";
    }
}

public class PostgresDialect implements SQLDialect {
    @Override
    public String getDateFormatFunction() { return "TO_CHAR"; }
    
    @Override
    public String getPageClause(long offset, long limit) {
        return "OFFSET " + offset + " LIMIT " + limit;
    }
    
    @Override
    public String getCountQuery(String sql) {
        return "SELECT COUNT(*) FROM (" + sql + ") AS t";
    }
}

// 应用:ORM框架根据数据库类型选择方言
public class QueryBuilder {
    private SQLDialect dialect;
    
    public QueryBuilder(String dbType) {
        this.dialect = DialectFactory.getDialect(dbType);
    }
    
    public String buildQuery(String sql, long offset, long limit) {
        return sql + " " + dialect.getPageClause(offset, limit);
    }
}

场景2: 游戏渲染引擎工厂

跨平台游戏引擎通常需要支持不同的渲染API(DirectX、OpenGL、Metal)。抽象工厂确保图片、着色器、缓冲区成套来自同一个渲染后端。

场景3: 云服务商适配工厂

多云架构中使用抽象工厂为不同云服务商(AWS、Azure、GCP)提供统一接口。每个工厂创建该云商的全套服务(存储、计算、网络)。

Bundled files

The model reads these on demand while the skill is loaded. They are exposed as readable files and are never executed.

Frequently asked questions

What does the 抽象工厂模式 AI skill do?

为一族相关对象的创建提供一致的接口,无需指定其具体类。

Why use 抽象工厂模式 on TypingMind?

Because you install it once and use it with any model. 抽象工厂模式 is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install 抽象工厂模式 in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/microwind/ai-skills/tree/main/design-patterns/abstract-factory-pattern. TypingMind reads its SKILL.md and bundles its files and installs it as a skill you can enable per chat.

Which AI models can use 抽象工厂模式?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with 抽象工厂模式?

As many as you like. As long as a model supports skills, you can use 抽象工厂模式 with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the 抽象工厂模式 AI skill free?

Yes. It is published on GitHub by microwind under the MIT license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇