Token导航 LogoToken导航

Agent Skill · 效率

bookforge-abstract-factory-implementor(bookforge 抽象工厂实现者)

bookforge-abstract-factory-implementor 用于补充效率相关能力,适合在 OpenClaw 中需要让 Agent 承接效率相关任务时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

bookforge-abstract-factory-implementor 是效率类 Agent Skill,可用宿主为 OpenClaw,通过ClawHub获取,权限为调用外部服务;许可证为 MIT-0,第三方扫描已通过,按安装量在效率类的 21,003 个 Skill 里排第 13,218。

总安装 3,810周安装 162GitHub Stars 公开资料未说明下载 1,335核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
MIT-0
版本
1.0.0

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:bookforge-abstract-factory-implementor(bookforge 抽象工厂实现者)
来源仓库:https://github.com/quochungto/bookforge-abstract-factory-implementor
安装命令:
openclaw skills install bookforge-abstract-factory-implementor
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 OpenClaw 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

ClawHubOpenClaw
openclaw skills install bookforge-abstract-factory-implementor

这个 Skill 是做什么的

效率类 Skill 把重复的整理、汇总、转换工作交给助手完成,减少手工复制粘贴。

bookforge-abstract-factory-implementor 实现抽象工厂模式以解耦对象创建逻辑。适用于多系列产品线开发或需动态切换实现类的系统。输出包含接口定义与具体工厂示例代码。使用前需明确产品族划分,避免过度抽象增加复杂度。代码风格遵循项目既有规范,兼容主流编程语言。

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 OpenClaw;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 openclaw skills install bookforge-abstract-factory-implementor;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它需要调用外部服务,先在测试目录或测试账号里跑,确认没问题再放到正式项目。

常见问题

6 条

bookforge-abstract-factory-implementor 怎么安装?

在终端执行 openclaw skills install bookforge-abstract-factory-implementor。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

bookforge-abstract-factory-implementor 支持哪些 AI 工具?

公开资料标注支持 OpenClaw。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

bookforge-abstract-factory-implementor 需要什么权限?

权限级别是调用外部服务。该 Skill 可能调用第三方服务、云服务或外部模型 API,使用前需要确认账号、额度、数据发送范围和服务条款。

bookforge-abstract-factory-implementor 是免费的吗?

来源标注的许可证是 MIT-0。本站不代收任何费用,也不托管安装包;能否商用、要不要署名,以许可证原文为准。

bookforge-abstract-factory-implementor 用的人多吗?

公开数据是累计安装 3,810 次,近一周安装 162 次,下载 1,335 次。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

bookforge-abstract-factory-implementor 安全吗?

第三方扫描结果为通过,但这只覆盖已知的静态检查项,不能替代自己读一遍源码和安装命令。

值得选的地方和要先想清楚的地方

值得选的地方

  • 专注 OpenClaw 一种宿主,触发方式和使用习惯不用来回切换。
  • 许可证明确为 MIT-0,商用和分发边界好判断。
  • 第三方扫描已通过,常见的高风险行为没有命中。

先想清楚的地方

  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 OpenClaw,想直接扩展它能力的人。
  • 需要处理效率类任务、又不想每次都手写提示词的人。
  • 需要许可证清楚、并且有第三方扫描结果的团队项目。

不太适合

  • 需要厂商级技术支持和 SLA 的生产系统。

效率类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
github

GitHub 代码协作 · OpenClaw

7,632,918545需要联网MIT-0通过
nano-pdf

Nano PDF 文档 · OpenClaw

4,249,476231需要联网MIT-0通过
auto-updater

自动更新程序 · OpenClaw

2,964,063386操作浏览器MIT-0通过
video-frames

视频帧 · OpenClaw

2,621,304112需要联网MIT-0通过
gemini

Gemini 助手 · OpenClaw

2,547,39648需要联网MIT-0有提醒
bookforge-abstract-factory-implementor

bookforge 抽象工厂实现者 · 本页

3,810—调用外部服务MIT-0通过

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

name
abstract-factory-implementor
description
|
version
1.0.0
homepage
https://github.com/bookforge-ai/bookforge-skills/tree/main/books/design-patterns-gof/skills/abstract-factory-implementor
metadata
{"openclaw":{"emoji":"📚","homepage":"https://github.com/bookforge-ai/bookforge-skills"}}
status
draft
depends-on
source-books
title
Design Patterns: Elements of Reusable Object-Oriented Software
authors
["Erich Gamma", "Richard Helm", "Ralph Johnson", "John Vlissides"]
chapters
[3]
pages
[54-58, 88-96]
tags
[design-patterns, creational, gof, abstract-factory, product-families, portability, refactoring]
execution
tier
2
mode
full
inputs
description
Existing code with hard-coded concrete class instantiation spread across a client, or a design description of a system that must support multiple product families
tools-required
[TodoWrite, Read]
tools-optional
[Grep, Edit]
mcps-required
[]
environment
Any codebase. Language-agnostic — examples use C++ and Python but the pattern applies universally.

Abstract Factory Implementor

When to Use

You are creating families of related objects and the client must stay independent of which concrete family it uses. This skill applies under four specific conditions — all are sufficient; any one justifies the pattern:

  1. Product-creation independence — a system should not depend on how its products are created, composed, or represented. Clients should work against abstract interfaces, not constructor calls.
  2. Multiple product families — the system must be configured with one of several families of products (e.g., Motif widgets vs. Presentation Manager widgets vs. Mac widgets), and the choice of family should be a single point of configuration, not scattered throughout the codebase.
  3. Enforced co-usage — products within a family are designed to work together, and you need a structural guarantee that clients never mix products from different families (a MotifScrollBar with a PMButton, for instance, is a violation the pattern makes structurally impossible).
  4. Interface-only library — you are providing a class library and want to reveal only interfaces, not implementations. Clients code against the abstract factory and abstract product classes; the concrete implementations are deployment-time choices.

Before starting, confirm this is not a simpler case:

  • If only one product type varies, prefer Factory Method — Abstract Factory is for *families* of products that must vary together.
  • If the products are not related (no co-usage constraint), the coordination overhead of Abstract Factory is not justified.

Process

Step 1: Set Up Tracking and Map the Product Families

ACTION: Use TodoWrite to track progress, then identify all product types and all families.

WHY: The Abstract Factory interface is fixed at design time based on the product types you identify here. Missing a product type now means changing the AbstractFactory interface later, which requires updating every ConcreteFactory — the most expensive structural change possible. A complete product-family map made upfront prevents this.

TodoWrite:
- [ ] Step 1: Map product types and product families
- [ ] Step 2: Define AbstractProduct interfaces
- [ ] Step 3: Define the AbstractFactory interface
- [ ] Step 4: Implement ConcreteFactory classes
- [ ] Step 5: Wire the client to use the factory
- [ ] Step 6: Handle singleton, prototype, or extensibility concerns
- [ ] Step 7: Validate and document known trade-offs

Applicability gate — confirm at least one of these four GoF conditions holds before proceeding:

#ConditionCheck
1System should be independent of how its products are created/composed/representedDoes client code currently name concrete product classes?
2System must be configured with one of multiple product familiesAre there 2+ families that could be swapped?
3Products within a family are designed to be used together — co-usage must be enforcedWould mixing products from different families cause bugs?
4You want to reveal only product interfaces, not implementationsShould concrete classes be hidden from library consumers?

IF none hold → this is not an Abstract Factory problem. Consider Factory Method (single product) or Builder (complex construction).

Alternative to consider — Prototype-based factory: If many product families exist or families differ only slightly, a single factory initialized with prototype instances (cloning instead of subclassing) eliminates the ConcreteFactory subclass explosion. Evaluate this option in Step 6 — but be aware of it now so you don't commit to a subclass-per-family design prematurely.

Produce a product matrix before writing any code:

Product typeFamily AFamily BFamily C
ScrollBarMotifScrollBarPMScrollBarMacScrollBar
ButtonMotifButtonPMButtonMacButton
MenuMotifMenuPMMenuMacMenu

The columns are your ConcreteFactories. The rows are your AbstractProduct interfaces. Count the rows — that is the number of factory methods on your AbstractFactory interface.


Step 2: Define AbstractProduct Interfaces

ACTION: For each product type (each row in the matrix), declare an abstract interface or base class.

WHY: The AbstractProduct interfaces are the contracts the client codes against. They are what make the client independent of concrete classes. Every method the client needs to call on a product must appear on the AbstractProduct interface — if a client has to downcast to access concrete behavior, the interface is incomplete and the isolation benefit disappears.

For each product type:

  1. Name it for the domain concept, not the family (e.g., ScrollBar, not MotifScrollBar)
  2. Declare only the operations all families must support
  3. Keep it minimal — only what the client actually calls

See the reference file for full code examples in C++, Python, and Smalltalk.


Step 3: Define the AbstractFactory Interface

ACTION: Declare an abstract factory class with one creation method per product type.

WHY: The AbstractFactory interface encodes the complete set of products the system knows about. Its method signatures return AbstractProduct types, never concrete types — this is what prevents concrete class names from appearing in client code. The factory interface is the "catalog" of the product family; each ConcreteFactory is one edition of that catalog.

class GUIFactory {
public:
    virtual ScrollBar* CreateScrollBar() = 0;
    virtual Button*    CreateButton()    = 0;
    virtual Menu*      CreateMenu()      = 0;
    virtual ~GUIFactory() = default;
};

Naming convention: Prefix with Create (C++/Java) or create_ (Python). This makes factory methods instantly recognizable in code review and distinguishes them from ordinary method calls.


Step 4: Implement ConcreteFactory Classes

ACTION: For each product family (each column in the matrix), create a ConcreteFactory subclass that implements every creation method.

WHY: Each ConcreteFactory encapsulates complete knowledge of one product family. A client that holds a MotifFactory reference is guaranteed to receive only Motif products — the factory enforces the co-usage constraint structurally, not through documentation or convention. This is the core value: consistency across a product family is automatic, not policed.

class MotifFactory : public GUIFactory {
public:
    ScrollBar* CreateScrollBar() override { return new MotifScrollBar; }
    Button*    CreateButton()    override { return new MotifButton; }
    Menu*      CreateMenu()      override { return new MotifMenu; }
};

class PMFactory : public GUIFactory {
public:
    ScrollBar* CreateScrollBar() override { return new PMScrollBar; }
    Button*    CreateButton()    override { return new PMButton; }
    Menu*      CreateMenu()      override { return new PMMenu; }
};

For each ConcreteFactory, implement the corresponding ConcreteProduct classes:

class MotifScrollBar : public ScrollBar {
public:
    void ScrollTo(int position) override {
        // Motif-specific scroll rendering
    }
};

class PMScrollBar : public ScrollBar {
public:
    void ScrollTo(int position) override {
        // Presentation Manager scroll rendering
    }
};

Step 5: Wire the Client to Use the Factory

ACTION: Refactor the client to receive an AbstractFactory reference and call only factory methods and AbstractProduct interfaces — no new ConcreteProduct(...) calls anywhere in client code.

WHY: The client has to commit to using the factory interface consistently. A single stray new MotifScrollBar in the client code breaks the isolation guarantee — the concrete class name is back in client code and the family-switching benefit is lost. This step is not complete until grep finds zero concrete class names imported or instantiated in client code.

Before (hard-coded, platform-specific):

// Every widget creation exposes a concrete class name
ScrollBar* sb = new MotifScrollBar;
Button* btn   = new MotifButton;
Menu* menu    = new MotifMenu;

After (factory-mediated, platform-independent):

void Application::BuildInterface(GUIFactory* factory) {
    // No concrete class names — family is entirely encapsulated in factory
    ScrollBar* sb  = factory->CreateScrollBar();
    Button*    btn = factory->CreateButton();
    Menu*      menu = factory->CreateMenu();
    // ...
}

Factory initialization — this must happen once, before the client first needs a product, at the program's configuration point:

// Compile-time known family
GUIFactory* guiFactory = new MotifFactory;

// Runtime-selected family (environment or config)
const char* styleName = getenv("LOOK_AND_FEEL");
if (strcmp(styleName, "Motif") == 0) {
    guiFactory = new MotifFactory;
} else if (strcmp(styleName, "Presentation_Manager") == 0) {
    guiFactory = new PMFactory;
} else {
    guiFactory = new DefaultGUIFactory;
}
// Pass guiFactory to all subsystems — they never see a concrete class name

Step 6: Handle Singleton, Prototype, or Extensibility Concerns

ACTION: Apply one or more of the three standard implementation refinements based on the system's constraints.

WHY: The basic four-step structure above covers the standard case. The three refinements address recurring complications. Choosing the wrong refinement (or skipping one when it is needed) leads to: unnecessary multi-instantiation of factories (singleton concern), an explosion of ConcreteFactory subclasses when families multiply (prototype concern), or a brittle interface that breaks when new product types are added (extensibility concern).

Refinement A — Factories as Singletons

An application typically needs exactly one instance of each ConcreteFactory per product family. Multiple instances would allow different parts of the application to use different families simultaneously, which is precisely the co-usage violation the pattern prevents.

Apply the Singleton pattern to each ConcreteFactory class. The factory's construction is then controlled and the single instance is shared across all clients.

Refinement B — Prototype-based Factories (when families are many and similar)

The factory-method approach requires a new ConcreteFactory subclass for each product family. When many product families exist (or families differ only slightly), this produces a combinatorial number of factory subclasses.

The alternative: a single concrete factory initialized with prototype instances. The factory's Make method clones the appropriate prototype rather than calling a subclass-specific factory method:

"Smalltalk prototype-based factory"
make: partName
    ^ (partCatalog at: partName) copy

addPart: partTemplate named: partName
    partCatalog at: partName put: partTemplate

Creating an EnchantedMazeFactory requires no new class — only a different factory initialization:

createMazeFactory
    ^ (MazeFactory new
        addPart: Wall named: #wall;
        addPart: EnchantedRoom named: #room;
        addPart: DoorNeedingSpell named: #door;
        yourself)

Prefer the prototype approach when: (a) many product families exist, (b) families differ only in which concrete products they use, or (c) you need to create new families at runtime by composing existing prototypes.

Refinement C — Extensible Factory Interface

The standard AbstractFactory interface is closed: adding a new product type requires changing the interface and all ConcreteFactories. A more flexible (but less type-safe) alternative is a single parameterized Make method:

// Type-safe but closed
virtual ScrollBar* CreateScrollBar() = 0;
virtual Button*    CreateButton() = 0;

// Flexible but loses static type safety
virtual AbstractProduct* Make(const string& productKind) = 0;

The parameterized version needs only one method change when new product types are added, but products are returned as a common abstract type — clients must cast (or use dynamic typing). This trade-off is the classic extensibility vs. type safety tension.

Use the extensible form when: the product type set is known to grow, you are in a dynamically typed language (where the casting cost disappears), or the flexibility benefit outweighs the safety cost. Stick with the standard form when: the product set is stable, static type checking matters, and you want the compiler to catch misuse.


Step 7: Validate and Document Known Trade-offs

ACTION: Verify the implementation satisfies all invariants, then explicitly document the extensibility liability.

WHY: Two of the four consequences of Abstract Factory are benefits (isolation, easy exchange), one is a benefit-with-a-condition (consistency, which only holds if you never mix factories), and one is a genuine liability (supporting new product kinds is hard). Documenting the liability upfront prevents the team from discovering it painfully later when someone tries to add a new product type.

Validation checklist:

  • [ ] No concrete product class names appear in client code (verify with grep)
  • [ ] Every product type in the matrix has an AbstractProduct interface
  • [ ] Every ConcreteFactory implements every AbstractProduct creation method
  • [ ] Factory is initialized once, at application startup or configuration boundary
  • [ ] If Singleton refinement was applied — factory construction is controlled
  • [ ] If Prototype refinement was applied — prototype registry is populated before first use
  • [ ] If Extensibility refinement was applied — all clients handle the downcast safely

Document the trade-off:

ConsequenceEffect
Isolates concrete classesClient code contains zero concrete class names; all coupling runs through abstract interfaces
Easy family exchangeChanging the entire product family requires changing exactly one factory instantiation site
Enforces product consistencyUsing objects from different families simultaneously is structurally impossible — the factory guarantees the constraint
Hard to add new product typesAdding a new product type requires changing AbstractFactory and every ConcreteFactory — this cascades across the entire hierarchy

Inputs

  • Existing code with scattered new ConcreteProduct(...) calls that need to be family-switched, OR
  • A design description identifying: (a) product types, (b) product families, (c) the client that consumes products

Outputs

  • abstract_factory.py (or .h/.cpp, .java, etc.) — AbstractFactory + AbstractProduct interfaces
  • concrete_factories.py — one ConcreteFactory per family, with ConcreteProduct implementations
  • Updated client code — factory-mediated, with all concrete class names removed

Key Principles

  • The interface is the commitment — every product type your AbstractFactory declares is a permanent entry in the contract. Adding product types later is costly. Invest in completeness at design time rather than patching the interface repeatedly.
  • One factory initialization point — the concrete factory should be chosen exactly once, at the application's configuration boundary. Allowing factory selection to spread through the codebase recreates the family-mixing problem the pattern solves.
  • Consistency is structural, not conventional — the value of Abstract Factory over a naming convention ("always use Motif widgets together") is that the structure makes family mixing impossible. If clients can bypass the factory, the guarantee evaporates.
  • Prototype over subclass when families multiply — factory-method-based AbstractFactory creates one ConcreteFactory subclass per product family. When families are many or differ only slightly, the prototype approach eliminates the subclass explosion without sacrificing the interface guarantee.
  • The extensibility liability is real — Abstract Factory trades extensibility for consistency. The pattern is appropriate when the product type set is stable. If new product types are expected frequently, the parameterized Make interface or a different pattern (Prototype, Builder) may be more appropriate.

Examples

Example 1: Lexi GUIFactory — Look-and-Feel Portability

Scenario: Lexi, a document editor, must run on Motif, Presentation Manager, and Mac. Every widget creation call currently names a concrete class, making it impossible to switch look-and-feel at runtime or port to a new platform without auditing the entire codebase.

Trigger: "We need to support a new look-and-feel standard, but widgets are instantiated directly throughout the application."

Product matrix:

Product typeMotifFactoryPMFactoryMacFactory
ScrollBarMotifScrollBarPMScrollBarMacScrollBar
ButtonMotifButtonPMButtonMacButton
MenuMotifMenuPMMenuMacMenu

AbstractFactory interface:

class GUIFactory {
public:
    virtual ScrollBar* CreateScrollBar() = 0;
    virtual Button*    CreateButton()    = 0;
    virtual Menu*      CreateMenu()      = 0;
};

Runtime family selection at startup:

GUIFactory* guiFactory;
const char* styleName = getenv("LOOK_AND_FEEL");

if (strcmp(styleName, "Motif") == 0)
    guiFactory = new MotifFactory;
else if (strcmp(styleName, "Presentation_Manager") == 0)
    guiFactory = new PMFactory;
else
    guiFactory = new DefaultGUIFactory;

// guiFactory passed to all Application subsystems
// No subsystem ever imports or names MotifScrollBar, PMButton, etc.

Output: Adding Mac support requires a MacFactory + three MacProduct classes. Zero changes to application logic, layout code, or event handling. A MotifMenu can never appear beside a PMButton — the factory makes this impossible.


Example 2: MazeFactory — Swappable Maze Components

Scenario: A maze game hard-codes Room, Wall, and Door in its CreateMaze function. Adding enchanted mazes or bombed mazes requires forking CreateMaze for each variant — a maintenance problem.

Trigger: "Every new maze type requires duplicating the maze-building logic with different class names."

AbstractFactory (also acts as ConcreteFactory for the default case):

class MazeFactory {
public:
    virtual Maze* MakeMaze()  const { return new Maze; }
    virtual Wall* MakeWall()  const { return new Wall; }
    virtual Room* MakeRoom(int n) const { return new Room(n); }
    virtual Door* MakeDoor(Room* r1, Room* r2) const { return new Door(r1, r2); }
};

Client uses only factory calls — no concrete class names:

Maze* MazeGame::CreateMaze(MazeFactory& factory) {
    Maze* aMaze = factory.MakeMaze();
    Room* r1 = factory.MakeRoom(1);
    Room* r2 = factory.MakeRoom(2);
    Door* aDoor = factory.MakeDoor(r1, r2);

    aMaze->AddRoom(r1);
    aMaze->AddRoom(r2);
    r1->SetSide(North, factory.MakeWall());
    r1->SetSide(East, aDoor);
    r1->SetSide(South, factory.MakeWall());
    r1->SetSide(West, factory.MakeWall());
    // ...
    return aMaze;
}

ConcreteFactories override only the methods that differ:

class EnchantedMazeFactory : public MazeFactory {
public:
    Room* MakeRoom(int n) const override {
        return new EnchantedRoom(n, CastSpell());
    }
    Door* MakeDoor(Room* r1, Room* r2) const override {
        return new DoorNeedingSpell(r1, r2);
    }
protected:
    Spell* CastSpell() const;
};

class BombedMazeFactory : public MazeFactory {
public:
    Wall* MakeWall() const override { return new BombedWall; }
    Room* MakeRoom(int n) const override { return new RoomWithABomb(n); }
};

Usage — single factory swap changes the entire maze variant:

MazeGame game;
BombedMazeFactory factory;
game.CreateMaze(factory);  // builds a maze with bombs — zero changes to CreateMaze

Output: CreateMaze is written once. Supporting three maze variants requires three factory classes — none of which touch the maze-building algorithm. The Smalltalk prototype-based version creates EnchantedMazeFactory without a new class, by initializing a MazeFactory with different prototype instances for #room and #door.


Example 3: Database Abstraction Layer

Scenario: A backend application runs tests against SQLite and production against PostgreSQL. Connection, query builder, and transaction objects all vary by database. Currently the database type is conditionally checked in dozens of places.

Trigger: "We have if db == 'postgres' scattered everywhere — adding a MySQL test environment would require touching every one."

Product matrix:

Product typePostgresFactorySQLiteFactory
ConnectionPostgresConnectionSQLiteConnection
QueryBuilderPostgresQueryBuilderSQLiteQueryBuilder
TransactionPostgresTransactionSQLiteTransaction

AbstractFactory + client:

class DatabaseFactory(ABC):
    @abstractmethod
    def create_connection(self) -> Connection: ...

    @abstractmethod
    def create_query_builder(self) -> QueryBuilder: ...

    @abstractmethod
    def create_transaction(self) -> Transaction: ...

# Client receives factory — never imports Postgres or SQLite classes
class Repository:
    def __init__(self, factory: DatabaseFactory):
        self._conn = factory.create_connection()
        self._qb   = factory.create_query_builder()

    def find_by_id(self, id: int):
        query = self._qb.select("users").where("id", id).build()
        return self._conn.execute(query)

Test environment wiring:

# tests/conftest.py
factory = SQLiteFactory(":memory:")

# production
factory = PostgresFactory(os.environ["DATABASE_URL"])

repo = Repository(factory)

Output: Adding MySQL support is a MySQLFactory class and three concrete products. Zero changes to Repository, zero changes to test setup beyond adding a new factory option.


Reference Files

FileContents
references/abstract-factory-implementation-guide.mdFull participants catalog, consequences analysis, prototype-based factory deep dive, extensible factory trade-off analysis, known uses (InterViews, ET++)

License

This skill is licensed under CC-BY-SA-4.0. Source: BookForge — Design Patterns: Elements of Reusable Object-Oriented Software by Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides.

Related BookForge Skills

Install related skills from ClawhHub:

  • clawhub install bookforge-creational-pattern-selector

Or install the full book set from GitHub: bookforge-skills

平台分布

OpenClaw

92.42%
按下载量换算1,234

安全审计

VirusTotal

通过

ClawScan

通过

Static analysis

通过

权限和风险

调用外部服务

该 Skill 可能调用第三方服务、云服务或外部模型 API,使用前需要确认账号、额度、数据发送范围和服务条款。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。目前只有一个公开来源,建议同时核对源仓库。

继续浏览同类 Skills