microwind/ai-skills/abstract-factory-pattern

Claude Code and agent skill by microwind/ai-skills

Trust tier 3
  • community
Source check pending

Checking that the SKILL.md file is still in the repository.

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

Install

npx vskill@latest install microwind/ai-skills/abstract-factory-pattern

SKILL.md

抽象工厂模式 (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();
}
}

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 95 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
51
Repository forks
13
7-day trend score
20

Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/microwind/ai-skills/abstract-factory-pattern/badge)](https://verified-skill.com/skills/microwind/ai-skills/abstract-factory-pattern)

Something wrong with this skill or its page? Tell us.