Skill: quochungto/bookforge-structural-pattern-selector (version 1.0.0)

--- name: structural-pattern-selector description: | Choose the right structural design pattern (Adapter, Bridge, Composite, Decorator, Facade, Flyweight, or Proxy) for a structural design problem. Use when you need to adapt interfaces between incompatible classes, decouple an abstraction from its implementation so both can vary independently, build part-whole hierarchies where individual objects and compositions are treated uniformly, add responsibilities to objects dynamically without subclassing, simplify access to a complex subsystem, share large numbers of fine-grained objects efficiently, or control and mediate access to another object. Disambiguates commonly confused patterns: Adapter vs Bridge (timing — after design vs before design), Composite vs Decorator vs Proxy (intent — structure vs embellishment vs access control, recursion pattern). Also use when someone asks "should I use Adapter or Bridge?", "what's the difference between Decorator and Proxy?", "when should I use Facade vs Adapter?", or "do I need Flyweight here?" version: 1.0.0 homepage: https://github.com/bookforge-ai/bookforge-skills/tree/main/books/design-patterns-gof/skills/structural-pattern-selector metadata: {"openclaw":{"emoji":"📚","homepage":"https://github.com/bookforge-ai/bookforge-skills"}} status: draft depends-on: - design-pattern-selector source-books: - id: design-patterns-gof title: "Design Patterns: Elements of Reusable Object-Oriented Software" authors: ["Erich Gamma", "Richard Helm", "Ralph Johnson", "John Vlissides"] chapters: [4] tags: [design-patterns, structural-patterns, adapter, bridge, composite, decorator, facade, flyweight, proxy, object-oriented, gof, disambiguation] execution: tier: 1 mode: full inputs: - type: none description: "A structural design problem description — the design challenge, existing code pain points, or a scenario requiring structural composition" tools-required: [Read, Write, TodoWrite] tools-optional: [Grep, Glob] mcps-required: [] environment: "Any agent environment. Scanning an existing codebase for context is helpful but not required." --- # Structural Pattern Selector ## When to Use You have a **structural** design problem — one about how classes or objects are composed to form larger structures. This skill applies when: - Two classes need to work together but have incompatible interfaces - An abstraction and its implementation are tightly bound and you need them to vary independently - You need to build tree-like hierarchies where individual items and groups behave the same way - You need to add capabilities to objects at runtime without subclassing - A complex subsystem needs a simpler unified entry point - You're creating large numbers of similar lightweight objects and memory is a concern - You need a stand-in, gateway, or access-control layer in front of another object - You're unsure which structural pattern fits, especially between Adapter/Bridge or Composite/Decorator/Proxy **Not this skill if:** The problem is about object creation (use a creational pattern) or communication/algorithms between objects (use a behavioral pattern). If you haven't yet classified the problem as structural, invoke `design-pattern-selector` first. ## Context & Input Gathering ### Required Context (must have before proceeding) - **Problem description:** What structural challenge exists? A rough description is fine — "I need these two incompatible classes to work together" or "I'm adding logging/auth to objects without changing them" - Check prompt for: words like "interface mismatch", "add responsibility", "part-whole", "subsystem", "access control", "share objects", "decouple abstraction" - If missing, ask: "Describe the structural design problem you're facing — what's currently rigid, mismatched, or needs composing?" - **Design timing:** Is this a new design (before classes exist) or an integration problem (classes already designed and built)? - This is the single most important disambiguator between Adapter and Bridge - Check prompt for: "existing", "third-party", "can't modify", "library" → likely post-design; "designing now", "new system", "will vary" → likely pre-design - If unclear, ask: "Are the classes you're working with already designed and built, or are you designing the structure from scratch?" ### Observable Context (gather from environment if available) - **Existing code:** If a codebase is available, scan for structural signals: - `implements`/`extends` mismatches between incompatible classes → Adapter candidate - Deep class hierarchies (subclass count growing combinatorially) → Bridge candidate - Tree-structured data with uniform operations → Composite candidate - Wrapper classes that add behavior before/after delegation → Decorator candidate - A "manager" or "controller" class that forwards to many subsystem classes → Facade candidate - Massive collections of identical-except-for-position objects (particles, characters, icons) → Flyweight candidate - Classes that gate, cache, or delay access to another class → Proxy candidate ### Default Assumptions - Object scope (composition) preferred over class scope (inheritance) unless inheritance is clearly appropriate — object patterns are more flexible at runtime - When timing is ambiguous, lean toward asking — the Adapter vs Bridge decision hinges entirely on this --- ## Process ### Step 1: Set Up Tracking and Frame the Problem **ACTION:** Use `TodoWrite` to track steps, then extract the core structural problem. **WHY:** Structural problems often present with symptoms ("this class is too hard to change") rather than causes ("these two abstractions are coupled"). Forcing a structured frame up front prevents jumping to the wrong pattern before the actual problem is clear. ``` TodoWrite: - [ ] Step 1: Frame the problem - [ ] Step 2: Classify the structural intent - [ ] Step 3: Apply the disambiguation decision tree - [ ] Step 4: Check pattern-specific applicability conditions - [ ] Step 5: Produce recommendation with rationale ``` Capture these elements from the description: | Element | Question to answer | |---------|-------------------| | **What exists** | What classes/objects are already in play? | | **What is wrong** | What is currently rigid, mismatched, or inefficient? | | **What must be possible** | What should the design enable that isn't possible now? | | **Timing** | Are these classes already designed, or is this a fresh design? | --- ### Step 2: Classify the Structural Intent **ACTION:** Identify which of the seven structural intents best matches the problem. **WHY:** Each structural pattern solves a fundamentally different structural problem. Getting the intent right eliminates 5–6 patterns immediately. The intent is the core discriminator — not the implementation mechanics. **Structural intent map:** | Intent | Core problem | Pattern | |--------|-------------|---------| | **Interface translation** | Two existing, incompatible interfaces must collaborate | Adapter | | **Abstraction/implementation decoupling** | An abstraction must vary independently of how it is implemented | Bridge | | **Part-whole uniformity** | Individual objects and compositions must be treated identically | Composite | | **Dynamic responsibility addition** | Responsibilities must be added/removed at runtime without subclassing | Decorator | | **Subsystem simplification** | A complex set of classes needs one simplified entry point | Facade | | **Instance sharing for efficiency** | Large numbers of fine-grained objects must share state to reduce memory cost | Flyweight | | **Controlled/mediated access** | Access to an object must be gated, deferred, or monitored | Proxy | **OUTPUT:** Identify the 1–2 most matching intents. If two intents match, proceed to Step 3 for disambiguation. --- ### Step 3: Apply the Disambiguation Decision Tree **ACTION:** For each commonly confused pair, apply the specific discriminator below. **WHY:** The structural patterns share implementation mechanics (all use indirection, all involve forwarding calls) but differ sharply in intent and timing. Using the wrong one produces structurally valid but semantically wrong code — Bridge code that should have been Adapter won't adapt; Proxy code that should have been Decorator won't stack. #### Adapter vs Bridge **The single question that separates them:** > "Were the classes being connected designed independently before this problem arose, or are you designing the structure now so they can vary independently later?" - **Answer: already designed, now incompatible** → **Adapter** - Adapter makes things work *after* they're designed. The coupling was unforeseen. - The goal is to make two independently developed classes collaborate without rewriting either. - The interface you're adapting *to* already exists and is owned by someone else. - **Answer: designing now, need future flexibility** → **Bridge** - Bridge makes things work *before* they're designed. The separation is intentional. - The goal is to keep an abstraction hierarchy independent from its implementation hierarchy so both can grow without a subclass explosion. - You are designing the structure up-front knowing it will need to vary in two dimensions. **Facade vs Adapter distinction:** Facade is sometimes described as an adapter for a set of objects. The difference: Facade defines a *new* interface over an existing subsystem. Adapter *reuses* an existing interface by making another class conform to it. If clients already know the target interface and you need another class to satisfy it → Adapter. If there is no target interface and you're creating a convenient entry point → Facade. #### Composite vs Decorator vs Proxy These three share a structural mechanism: they all wrap another object and forward calls. Differentiate by intent and recursion: | Question | Composite | Decorator | Proxy | |----------|-----------|-----------|-------| | **What is the purpose?** | Represent part-whole hierarchy (structure) | Add responsibilities dynamically (embellishment) | Control or mediate access (access management) | | **Does it hold multiple children?** | Yes — a Composite holds a list of Components | No — a Decorator wraps exactly one Component | No — a Proxy references exactly one Subject | | **Is recursive composition essential?** | Yes — the pattern requires it (tree structure) | Yes — decorators can be nested (stacked behaviors) | No — the proxy-subject relationship is static and one-to-one | | **Does the wrapper change behavior?** | Yes, by aggregating children | Yes, by adding before/after behavior | Sometimes (protection, logging), but the *subject* defines core behavior | | **Known at compile time?** | Determined at runtime (tree built dynamically) | Determined at runtime (decoration can be applied/removed) | Often known at compile time (proxy-subject relationship is fixed) | **Quick diagnostic:** - "I need to build a tree of objects where nodes and leaves behave the same" → **Composite** - "I need to add logging/auth/caching to objects at runtime without changing them" → **Decorator** - "I need a stand-in because the real object is remote, expensive to create, or needs access control" → **Proxy** --- ### Step 4: Check Pattern-Specific Applicability Conditions **ACTION:** For the leading candidate, verify its specific applicability conditions are met. For Flyweight, ALL five conditions must be true — it is an AND-gate, not an OR-gate. **WHY:** Each pattern has conditions that make it inappropriate even when the intent matches. Verifying these prevents applying a pattern that will cause more problems than it solves. **Adapter — use when:** - You want to use an existing class but its interface does not match the one you need - You want to create a reusable class that cooperates with unrelated classes that don't have compatible interfaces - (Object adapter only) You need to adapt multiple existing subclasses — class adapter would require subclassing each one **Bridge — use when:** - You want to avoid a permanent binding between an abstraction and its implementation (implementation must be selectable or switchable at runtime) - Both the abstractions and their implementations should be extensible by subclassing and combined independently - Changes to the implementation of an abstraction should not require recompiling clients - You have a class proliferation where subclasses exist for each combination of abstraction variant and implementation variant (the "nested generalizations" smell) **Composite — use when:** - You want to represent part-whole hierarchies of objects - You want clients to be able to ignore the difference between compositions of objects and individual objects — clients treat all objects in the composite structure uniformly **Decorator — use when:** - You need to add responsibilities to individual objects dynamically and transparently, without affecting other objects - You need responsibilities that can be withdrawn (not just added) - Extension by subclassing is impractical because it produces too many classes or classes are unavailable for subclassing **Facade — use when:** - You want to provide a simple interface to a complex subsystem (subsystem complexity has grown such that most clients need a simple default view) - There are many dependencies between clients and the implementation classes of an abstraction — introducing a Facade decouples the subsystem from clients and promotes subsystem independence - You want to layer your subsystems — use a facade as a defined entry point at each layer, simplifying inter-subsystem dependencies **Flyweight — ALL five conditions must be true (AND-gate):** 1. The application uses a large number of objects 2. Storage costs are high because of the sheer quantity of objects 3. Most object state can be made extrinsic (passed to methods rather than stored per-instance) 4. Many groups of objects may be replaced by relatively few shared objects once extrinsic state is removed 5. The application does not depend on object identity — since flyweight objects are shared, identity tests (`==`) will return true for conceptually distinct objects. **If your code needs to distinguish between individual instances that represent different logical entities, Flyweight will break that logic.** **Proxy — use when:** - A remote proxy: you need a local representative for an object in a different address space - A virtual proxy: you need to create expensive objects on demand (lazy initialization) - A protection proxy: access to the original object requires access-rights control - A smart reference: you need additional behavior triggered when an object is accessed (reference counting, loading a persistent object, locking) --- ### Step 5: Produce the Recommendation **ACTION:** Deliver a structured recommendation, explicitly naming the disambiguation rationale if the problem involved a confused pair. **WHY:** A recommendation without the disambiguation rationale leaves the developer unable to defend the choice to teammates, and unable to re-evaluate if the situation changes (e.g., if a design-time Bridge later needs to become an Adapter because existing classes were introduced). **Recommendation format:** ``` ## Structural Pattern Recommendation: [Pattern Name] **Intent match:** [One sentence connecting the pattern's intent to the specific problem] **Why not [confused alternative]:** [The specific discriminator that ruled it out — timing, recursion, identity, etc.] **Applicability check:** [Confirm the specific conditions from Step 4 are met] **What it enables:** [What the design can do after applying this pattern] **Key trade-off:** [What complexity or constraint this pattern introduces] **Patterns to combine with:** [Any structural or behavioral patterns that complement this, if applicable] ``` --- ## Examples ### Example 1: Third-Party Payment SDK with Wrong Interface **Scenario:** A team is integrating a payment provider's SDK. The SDK's `PaymentGateway` class has a `processCharge(amount, token)` method. The application's internal interface is `IPaymentProcessor` with a `charge(request: PaymentRequest)` method. The SDK cannot be modified. **Trigger:** "We need to use this payment SDK but it doesn't match our internal interface." **Process:** - Step 2: Interface translation — two existing incompatible interfaces - Step 3: Adapter vs Bridge discriminator — classes are already designed and built; the incompatibility is unforeseen. Bridge is for pre-design. This is post-design. → Adapter - Step 4: Adapter applicability — want to use an existing class whose interface doesn't match; object adapter appropriate since we don't own the SDK **Output:** ``` ## Structural Pattern Recommendation: Adapter **Intent match:** The PaymentGateway SDK already exists with a fixed interface; Adapter translates the existing IPaymentProcessor interface to the SDK's API without modifying either. **Why not Bridge:** Bridge is used before design, to keep two hierarchies from being permanently coupled. These classes are already built — the incompatibility is discovered, not anticipated. "Adapter makes things work after they're designed; Bridge makes them work before." **Applicability check:** Existing class (SDK) with non-matching interface — confirmed. Object adapter used because subclassing PaymentGateway is not appropriate. **What it enables:** The application only ever sees IPaymentProcessor. Swapping the payment provider means swapping the Adapter class, with zero changes to application code. **Key trade-off:** Each method added to IPaymentProcessor requires a corresponding translation in the Adapter. If the interfaces diverge significantly, the Adapter grows. Consider whether the internal interface can be kept stable. **Patterns to combine with:** Factory Method (to instantiate the correct Adapter based on configured payment provider) ``` --- ### Example 2: UI Component Tree with Uniform Operations **Scenario:** A document editor has two kinds of graphic objects: primitive shapes (Line, Rectangle, Text) and grouped graphics (Picture, which contains other graphics). The editor needs to move, resize, and draw both primitive and grouped objects through the same interface. Nested groups must work (a Picture can contain another Picture). **Trigger:** "We need to treat individual shapes and groups of shapes the same way, including nested groups." **Process:** - Step 2: Part-whole uniformity — individual and composed objects must behave identically - Step 3: Composite vs Decorator vs Proxy discriminator: - Need to hold multiple children? Yes (Picture holds a list of Graphic) - Recursive composition essential? Yes (nested groups required) - Purpose: structuring a hierarchy, not adding behavior or controlling access → Composite - Step 4: Composite applicability — part-whole hierarchy and uniform client treatment — both confirmed **Output:** ``` ## Structural Pattern Recommendation: Composite **Intent match:** The editor needs to treat individual shapes and grouped shapes uniformly through a Graphic interface, with arbitrarily deep nesting of groups. **Why not Decorator:** Decorator also uses recursive composition but its purpose is embellishment — adding behaviors. Composite's purpose is representation — organizing objects into a tree where nodes and leaves are interchangeable. No responsibilities are being added here; a structure is being organized. **Why not Proxy:** Proxy is a one-to-one stand-in for one Subject, not a container for multiple children. **Applicability check:** Part-whole hierarchy (Picture contains Graphics) and uniform client treatment (editor calls draw() on any Graphic) — both confirmed. **What it enables:** The editor code can call draw(), move(), or resize() on any Graphic without knowing whether it's a primitive or a group. Adding new primitive types requires no changes to the editor. **Key trade-off:** Makes the design overly general — it becomes hard to restrict what can be added to a Composite (e.g., preventing a Line from being added as a child of a TextGroup). If type-safety in the hierarchy matters, extra validation is needed. **Patterns to combine with:** Decorator (to add responsibilities to individual Graphic objects without subclassing), Iterator (to traverse the tree) ``` --- ### Example 3: Rate Limiting and Logging Added to Service Calls **Scenario:** A developer has a `ReportService` that generates reports. They need to add rate limiting (no more than 10 calls per minute), request logging, and authentication checking — all without modifying `ReportService`. The behaviors may need to be applied in different combinations to different service instances. **Trigger:** "I need to add rate limiting, logging, and auth to our service without touching the service class, and I need to be able to mix and match which ones apply." **Process:** - Step 2: Dynamic responsibility addition — behaviors added at runtime without subclassing, and must be composable - Step 3: Composite vs Decorator vs Proxy discriminator: - Adding/removing responsibilities dynamically? Yes → Decorator candidate - Controlling access to the real object? Rate limiting and auth do gate access → Proxy candidate - Key discriminator: need to stack multiple behaviors and mix-and-match → Proxy is one-to-one and static; Decorator is designed for stacking → **Decorator** - Step 4: Decorator applicability — responsibilities to add/remove dynamically, subclassing impractical for all combinations — confirmed **Output:** ``` ## Structural Pattern Recommendation: Decorator **Intent match:** Rate limiting, logging, and auth are responsibilities that need to be added dynamically and in different combinations — exactly what Decorator is designed for. Each concern becomes a decorator wrapping the service. **Why not Proxy:** Proxy controls access through a static one-to-one relationship to one Subject. It is not designed for recursive composition or for mixing and matching multiple behaviors. A ProtectionProxy could handle auth alone, but cannot stack with a RateLimitingProxy without compromising both patterns' intent. **Applicability check:** Responsibilities are to be added transparently without affecting other objects; responsibilities can be withdrawn (remove a decorator to remove the behavior); subclassing for all combinations is impractical (3 behaviors = 7 possible combinations). Confirmed. **What it enables:** RateLimitingDecorator(LoggingDecorator(AuthDecorator(reportService))) composes all three behaviors. Each can be added or removed independently at construction time. **Key trade-off:** A decorator and its component are not identical objects — code that uses object identity (==) to find a specific layer will fail. Also, many small objects can be harder to debug (stepping through the decorator chain). Keep decorator chains short and document the wrapping order. **Patterns to combine with:** Factory Method (to construct the right decorator combination based on configuration) ``` --- ## Key Principles - **Timing is the Adapter/Bridge axis** — "Adapter makes things work *after* they're designed; Bridge makes them work *before*." If the incompatibility was discovered (classes already exist), that's Adapter territory. If the separation is intentional design-time planning, that's Bridge territory. - **Intent beats mechanics** — Composite, Decorator, and Proxy all wrap objects and forward calls. The right choice is determined by what you're trying to accomplish: structure a hierarchy (Composite), add behaviors (Decorator), or control access (Proxy). Choosing by implementation similarity produces structurally valid but semantically wrong code. - **Flyweight is an AND-gate, not an OR-gate** — All five conditions must hold simultaneously. The most commonly missed is identity: if any part of the application needs to distinguish between two flyweight instances representing different logical entities, shared objects will cause silent correctness bugs. - **Facade defines new; Adapter reuses existing** — Facade creates a convenient new interface over a subsystem where none existed. Adapter makes a class conform to an existing interface someone else owns. If clients already have a target interface they code to, it's Adapter. If you're inventing the interface, it's Facade. - **Recursive composition signals Composite or Decorator, not Proxy** — Proxy's subject relationship is static and one-to-one. If the design requires stacking, nesting, or building trees of wrapped objects, the choice is between Composite (structural hierarchy) and Decorator (behavioral layering), not Proxy. --- ## References - For full applicability conditions and disambiguation detail for all seven patterns, see [structural-disambiguation.md](references/structural-disambiguation.md) - For the complete 23-pattern catalog (purpose, scope, intent), consult `design-pattern-selector/references/pattern-catalog.md` ## License This skill is licensed under [CC-BY-SA-4.0](https://creativecommons.org/licenses/by-sa/4.0/). Source: [BookForge](https://github.com/bookforge-ai/bookforge-skills) — 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-design-pattern-selector` Or install the full book set from GitHub: [bookforge-skills](https://github.com/bookforge-ai/bookforge-skills)

path: references/structural-disambiguation.md
content: # Structural Pattern Disambiguation Reference

> Source: Design Patterns: Elements of Reusable Object-Oriented Software (Gamma, Helm, Johnson, Vlissides), Chapter 4 — Structural Patterns, pages 133–207.
> This file contains detailed applicability conditions, disambiguation criteria, and cross-pattern relationships for the seven structural GoF patterns. Load this file when the SKILL.md decision tree produces ambiguity or when you need to explain a recommendation in depth.

---

## Overview: The Seven Structural Patterns

Structural patterns are concerned with how classes and objects are composed to form larger structures.

- **Class patterns** use inheritance to compose interfaces or implementations (Adapter class variant)
- **Object patterns** use composition to realize new functionality, gaining the ability to change composition at runtime

| Pattern | Core structural problem | Mechanism |
|---------|------------------------|-----------|
| Adapter | Interface incompatibility between existing classes | Wraps one object to present another interface |
| Bridge | Abstraction and implementation tightly bound | Separates into two independent hierarchies |
| Composite | Part-whole hierarchies need uniform treatment | Recursive tree of Component objects |
| Decorator | Adding responsibilities without subclassing | Wraps a Component and adds before/after behavior |
| Facade | Complex subsystem needs a simple unified entry point | Single object that delegates to subsystem classes |
| Flyweight | Large numbers of fine-grained objects are expensive | Shared objects with extrinsic state passed in |
| Proxy | Need a stand-in, gateway, or access-control layer | One-to-one wrapper that controls access to Subject |

---

## Adapter

### Intent
Convert the interface of a class into another interface clients expect. Adapter lets classes work together that couldn't otherwise because of incompatible interfaces.

Also known as: **Wrapper**

### Applicability
Use Adapter when:
- You want to use an existing class, and its interface does not match the one you need
- You want to create a reusable class that cooperates with unrelated or unforeseen classes that don't have compatible interfaces
- *(Object adapter only)* You need to use several existing subclasses, but it's impractical to adapt their interface by subclassing each one — an object adapter can adapt the interface of its parent class

### Class Adapter vs Object Adapter

| | Class Adapter | Object Adapter |
|--|--------------|---------------|
| Mechanism | Multiple inheritance | Composition (holds Adaptee reference) |
| Adapts | A single Adaptee class | Any Adaptee subclass |
| Can override Adaptee behavior | Yes | No (must subclass Adaptee) |
| Language support | C++ (multiple inheritance), not Java/C# | Universal |
| When to prefer | When you need to override specific Adaptee behavior | When you need to work with Adaptee subclasses |

### Disambiguation: Adapter vs Facade

Both Adapter and Facade wrap other objects and present a different interface. The distinction:

- **Adapter** reuses an *existing* target interface — there is already a contract (e.g., `IPaymentProcessor`) that other code depends on, and you need to make a new class satisfy it
- **Facade** defines a *new* interface — there is no pre-existing contract; you are creating a convenient entry point for a subsystem that previously had no unified access point

> From the GoF (p.206): "You might think of a facade as an adapter to a set of other objects. But that interpretation overlooks the fact that a facade defines a *new* interface, whereas an adapter reuses an old interface. Remember that an adapter makes two *existing* interfaces work together as opposed to defining an entirely new one."

### Disambiguation: Adapter vs Bridge (THE KEY DISTINCTION)

> From the GoF (p.206): "The Adapter pattern makes things work *after* they're designed; Bridge makes them work *before*."

| Axis | Adapter | Bridge |
|------|---------|--------|
| **When applied** | Post-design — classes exist independently and must be integrated | Pre-design — structure is intentionally separated before classes are built |
| **Origin of incompatibility** | Unforeseen — coupling was not anticipated | Intentional — separation is a deliberate architectural decision |
| **Goal** | Make two independently designed classes work together without reimplementing either | Keep abstraction and implementation hierarchies separately extensible |
| **Relationship to change** | Resolves a fixed incompatibility | Accommodates ongoing independent variation |

Both patterns provide a level of indirection by forwarding requests. The difference is entirely in intent and timing.

---

## Bridge

### Intent
Decouple an abstraction from its implementation so that the two can vary independently.

### Applicability
Use Bridge when:
- You want to avoid a permanent binding between an abstraction and its implementation — for example, when the implementation must be selected or switched at runtime
- Both the abstractions and their implementations should be extensible by subclassing, and the different combinations should be composable independently
- Changes in the implementation of an abstraction should have no impact on clients — their code should not have to be recompiled
- *(C++ context)* You want to hide the implementation of an abstraction completely from clients
- You have a proliferation of classes ("nested generalizations") — a class hierarchy with subclasses for each combination of abstraction variant and implementation variant. Bridge breaks this into two independent hierarchies
- You want to share an implementation among multiple objects and this fact should be hidden from the client

### The "Nested Generalization" Smell That Bridge Solves

If you see a class hierarchy like:
```
Shape
├── RedCircle
├── BlueCircle
├── RedSquare
└── BlueSquare
```

And it is growing as both shapes and colors are added, Bridge is likely the solution. Separate the two dimensions:
```
Shape (abstraction)          Color (implementation)
├── Circle                   ├── Red
└── Square                   └── Blue
```

Circle and Square hold a reference to a Color implementation. 2 shapes + 2 colors = 4 classes, not 4 subclasses (and it scales linearly, not combinatorially).

### Participants

- **Abstraction** — defines the abstraction's interface; maintains a reference to an Implementor
- **RefinedAbstraction** — extends the Abstraction interface
- **Implementor** — defines the interface for implementation classes (does not need to match Abstraction's interface; typically provides primitive operations that Abstraction uses to define higher-level operations)
- **ConcreteImplementor** — implements the Implementor interface

---

## Composite

### Intent
Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly.

### Applicability
Use Composite when:
- You want to represent part-whole hierarchies of objects
- You want clients to be able to ignore the difference between compositions of objects and individual objects — clients will treat all objects in the composite structure uniformly

### Participants

- **Component** — declares the interface for objects in the composition; implements default behavior for the interface common to all classes
- **Leaf** — represents leaf objects in the composition; a Leaf has no children
- **Composite** — defines behavior for components having children; stores child components; implements child-related operations
- **Client** — manipulates objects in the composition through the Component interface

### Key Consequence: The Uniformity Principle

The power of Composite is that clients never need to ask "is this a leaf or a composite?" — they call the same interface either way. The Composite propagates operations through its children automatically (`for g in children: g.Operation()`).

### Disambiguation: Composite vs Decorator vs Proxy

See dedicated section below.

---

## Decorator

### Intent
Attach additional responsibilities to an object dynamically. Decorator provides a flexible alternative to subclassing for extending functionality.

Also known as: **Wrapper**

### Applicability
Use Decorator:
- To add responsibilities to individual objects dynamically and transparently, without affecting other objects
- For responsibilities that can be withdrawn
- When extension by subclassing is impractical — sometimes a large number of independent extensions are possible, producing an explosion of subclasses to support every combination; or a class definition may be hidden or otherwise unavailable for subclassing

### Why Decorator Instead of Subclassing

Subclassing adds behavior statically — all instances of the subclass have the additional behavior, and it cannot be removed. Decorator adds behavior at object level, dynamically. Three separate responsibilities (logging, rate limiting, auth) would require 7 subclasses to cover all combinations ($2^3 - 1$). With Decorator, you wrap the object with whichever decorators you need.

### The Recursive Composition Structure

A Decorator conforms to the interface of the Component it decorates. This means decorators can be nested:

```
AuthDecorator(LoggingDecorator(RateLimitDecorator(realService)))
```

Each layer adds its behavior before/after calling the next layer's method. The real object is at the center. The nesting depth is open-ended — this is the essential feature that distinguishes Decorator from Proxy.

### Important Consequence: Identity Breaks

A Decorator and its Component are not the same object. Code that uses object identity (`decorator == component`) will behave unexpectedly. This is a documented trade-off: Decorator sacrifices identity in exchange for compositional flexibility.

---

## Facade

### Intent
Provide a unified interface to a set of interfaces in a subsystem. Facade defines a higher-level interface that makes the subsystem easier to use.

### Applicability
Use Facade when:
- You want to provide a simple interface to a complex subsystem. Subsystems often get more complex as they evolve. Most patterns, when applied, result in more and smaller classes. This makes the subsystem more reusable and easier to customize, but also harder to use for clients that don't need to customize it. A facade can provide a simple default view of the subsystem that is good enough for most clients.
- There are many dependencies between clients and the implementation classes of an abstraction. Introduce a facade to decouple the subsystem from clients and other subsystems, thereby promoting subsystem independence and portability.
- You want to layer your subsystems. Use a facade to define an entry point to each subsystem level. If subsystems are dependent, you can simplify the dependencies between them by making them communicate with each other solely through their facades.

### Facade Does Not Encapsulate the Subsystem

Unlike other structural patterns that fully hide the wrapped object, Facade does not prevent clients from using subsystem classes directly if they need to. Facade only provides a convenient default — clients needing advanced customization can bypass the Facade and work with subsystem classes directly.

### Disambiguation: Facade vs Adapter (Summary)

| | Facade | Adapter |
|--|--------|---------|
| Interface it provides | A new, simpler interface that didn't exist before | An existing interface that another class should satisfy |
| What it wraps | A subsystem (multiple classes) | A single class (or class hierarchy) |
| Goal | Simplify usage | Resolve incompatibility |
| Pre-existing target interface? | No — Facade creates the interface | Yes — Adapter maps to an existing interface |

---

## Flyweight

### Intent
Use sharing to support large numbers of fine-grained objects efficiently.

### The AND-Gate: All Five Conditions Must Hold

The Flyweight pattern's effectiveness depends heavily on how and where it's used. Apply Flyweight only when **all** of the following are true:

1. **Large number of objects** — the application creates and manages thousands or more instances
2. **High storage cost** — memory consumption from this quantity of objects is measurably significant
3. **Most state is extrinsic** — the majority of each object's state can be computed or passed in from outside, rather than stored per-instance
4. **Many objects can be replaced by few shared objects** — once extrinsic state is separated out, many "different" objects turn out to be identical in their intrinsic state
5. **No object identity dependency** — the application does not use identity tests (`==`, reference equality) to distinguish objects that represent conceptually different entities

**Condition 5 is the most commonly missed.** Flyweight objects are shared — multiple logical "instances" map to the same physical object. If any code does:

```python
character_a1 = flyweight_factory.get('a')
character_a2 = flyweight_factory.get('a')
assert character_a1 is not character_a2  # FAILS — they're the same object
```

or relies on object identity for tracking, ordering, or comparison, Flyweight will produce silent correctness bugs that are difficult to diagnose.

### Intrinsic vs Extrinsic State

| | Intrinsic state | Extrinsic state |
|--|----------------|----------------|
| Stored in | The flyweight object itself | Passed to flyweight methods by the client |
| Shared? | Yes — all clients sharing this flyweight use the same intrinsic state | No — different for each context |
| Example (character glyph) | Character code ('a', 'b', etc.) | Position, font, color in the document |

Separating intrinsic from extrinsic state is the central design task when implementing Flyweight.

---

## Proxy

### Intent
Provide a surrogate or placeholder for another object to control access to it.

### Four Types of Proxy

1. **Remote proxy** — provides a local representative for an object in a different address space. The proxy handles network communication transparently; clients see a local interface.

2. **Virtual proxy** — creates expensive objects on demand. The proxy stands in until the real object is actually needed, then creates and delegates to it (lazy initialization). Example: ImageProxy that shows a placeholder until the image is loaded.

3. **Protection proxy** — controls access to the original object based on access rights. Useful when objects should have different access rights.

4. **Smart reference** — replacement for a bare pointer that performs additional actions when an object is accessed: reference counting, locking, logging, caching.

### Disambiguation: Proxy vs Decorator

This is the most subtle distinction among structural patterns.

> From the GoF (p.207): "Like Decorator, the Proxy pattern composes an object and provides an identical interface to clients. Unlike Decorator, the Proxy pattern is not concerned with attaching or detaching properties dynamically, and it's not designed for recursive composition."

| Axis | Proxy | Decorator |
|------|-------|-----------|
| **Purpose** | Control or mediate access to the Subject | Add responsibilities to the Component |
| **Who defines core behavior** | The Subject — Proxy only provides/refuses access to it | Both Component and Decorators — Decorator adds to what Component provides |
| **Recursive composition** | Not designed for it — relationship is static one-to-one | Essential to the pattern — decorators stack |
| **Known at compile time** | Often — the proxy-subject relationship is frequently fixed | Typically no — decoration applied at runtime |
| **Can be stacked** | Not the intent — multiple proxies can exist but each is independent | Yes — stacking is the primary value proposition |

**Decision rule:** If you need one wrapper that gates, defers, or monitors access to one object → Proxy. If you need to stack multiple wrappers that each add a piece of behavior → Decorator.

### Proxy vs Adapter

Both Proxy and Adapter wrap an object. The difference:
- **Proxy** implements the *same interface* as its Subject — it is a transparent stand-in
- **Adapter** implements a *different interface* than its Adaptee — it is an interface translator

---

## Cross-Pattern Relationships Summary

| Pattern pair | Relationship | When both are used together |
|-------------|-------------|----------------------------|
| Composite + Decorator | Complementary | Build a tree of objects (Composite), then add behaviors to individual nodes (Decorator) without modifying the tree structure |
| Composite + Iterator | Complementary | Define a Composite tree structure, use Iterator to traverse it |
| Decorator + Strategy | Alternatives for behavioral extension | Decorator changes an object's *skin* (wraps it); Strategy changes an object's *guts* (replaces its algorithm). Use Decorator when the behavior wraps/extends the component's own behavior; use Strategy when the component's behavior needs to be replaced entirely |
| Facade + Singleton | Often combined | A Facade is often implemented as a Singleton — one unified entry point per subsystem |
| Proxy + Decorator | Can be combined (carefully) | A proxy-decorator adds functionality to a proxy, or a decorator-proxy embellishes a remote object. The GoF notes this is possible but recommends treating them separately unless needed |
| Adapter + Factory Method | Common combination | Use Factory Method to instantiate the right Adapter based on runtime configuration |
| Bridge + Abstract Factory | Common combination | Use Abstract Factory to create the ConcreteImplementor for a Bridge |

---

## Quick Disambiguation Card

```
STRUCTURAL PROBLEM
       │
       ├─ Incompatible interface?
       │         ├─ Classes already designed, incompatibility unforeseen? → ADAPTER
       │         └─ Designing now, need long-term independent variation? → BRIDGE
       │
       ├─ Need part-whole tree (nodes and leaves behave the same)? → COMPOSITE
       │
       ├─ Need to add/remove behaviors dynamically without subclassing?
       │         ├─ Need to STACK multiple behaviors? → DECORATOR
       │         └─ Need ONE gateway (access control, lazy init, remote)? → PROXY
       │
       ├─ Complex subsystem needs a simple unified entry point? → FACADE
       │         └─ (Note: Facade creates NEW interface; Adapter reuses EXISTING interface)
       │
       └─ Thousands of fine-grained objects, memory is the problem,
          ALL 5 conditions hold (including no identity dependency)? → FLYWEIGHT
```


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: clean (LOW)