# Structural Patterns

> Every principle in this category is listed as a record.

Page: Ontology · Principles
Canonical: https://banes-lab.com/ontology#arch-category-structural-patterns

Every principle in this category is listed as a record. Each record carries its kind, its severity, the scopes it applies at and the layer it lives in, then the edge relations that join it to other records, the records that point back at it, the contracts that answer to it and the tensions it takes part in. The descriptors say how it is violated, detected, measured, repaired and enforced. Where the record carries one, an exemplar shows the shape before and after the principle is applied.

Relations diagram

The relations inside this category.

```mermaid
flowchart LR
n_adapter_pattern["Adapter Pattern"]
n_facade_pattern["Facade Pattern"]
n_proxy_pattern["Proxy Pattern"]
n_bridge_pattern["Bridge Pattern"]
n_decorator_pattern["Decorator Pattern"]
n_composite_pattern["Composite Pattern"]
n_flyweight_pattern["Flyweight Pattern"]
```

### Adapter Pattern

- Kind: [pattern](https://banes-lab.com/records/kind/pattern.md)
- Severity: mandatory
- Scope: integration, boundary
- Layer: [Design Patterns Core](https://banes-lab.com/records/layer/design-patterns-core.md)

Details

Requires
[Incompatible Interfaces](https://banes-lab.com/records/lex/incompatible-interfaces.md)

Reinforces
[Anti-Corruption Layer](https://banes-lab.com/records/arch/anti-corruption-layer.md), [Replaceability](https://banes-lab.com/records/arch/replaceability.md)

Enables
[Interoperability](https://banes-lab.com/records/arch/interoperability.md)

In tension with
[Mapping Overhead](https://banes-lab.com/records/lex/mapping-overhead.md)

Conflicts with
[Direct External Coupling](https://banes-lab.com/records/lex/direct-external-coupling.md)

Referenced by
[Interface-Based Design](https://banes-lab.com/records/arch/interface-based-design.md)

Tensions
[Adapter Pattern Mapping Overhead](https://banes-lab.com/records/tension/adapter-pattern-mapping-overhead.md)

Violated by
foreign model leaking into core

Detected by
external SDK types in domain/application

Measured by
external leakage count

Refactored by
Add Adapter, Add Translator

Enforced by
boundary import rules

Before

```typescript
function saveFoo(foo: Foo) {
return legacyClient.put(foo.id, foo.name, foo.count);
}
```

After

```typescript
class LegacyFooAdapter implements FooStore {
constructor(private readonly client: LegacyClient) {}
save(foo: Foo) { return this.client.put(foo.id, foo.name, foo.count); }
}
```

### Facade Pattern

- Kind: [pattern](https://banes-lab.com/records/kind/pattern.md)
- Severity: recommended
- Scope: module, subsystem, API
- Layer: [Design Patterns Core](https://banes-lab.com/records/layer/design-patterns-core.md)

Details

Requires
[Subsystem Complexity](https://banes-lab.com/records/lex/subsystem-complexity.md)

Reinforces
[Encapsulation](https://banes-lab.com/records/arch/encapsulation.md), [Information Hiding](https://banes-lab.com/records/arch/information-hiding.md)

Enables
[Simplified Access](https://banes-lab.com/records/lex/simplified-access.md)

In tension with
[Over-Centralization](https://banes-lab.com/records/lex/over-centralization.md)

Conflicts with
[Leaky Subsystem API](https://banes-lab.com/records/lex/leaky-subsystem-api.md)

Tensions
[Facade Pattern Over-Centralization](https://banes-lab.com/records/tension/facade-pattern-over-centralization.md)

Violated by
consumers depending on many subsystem internals

Detected by
broad dependency surface to subsystem

Measured by
consumer dependency count

Refactored by
Introduce Facade

Enforced by
API boundary rules

Before

```typescript
const foo = fooValidator.validate(fooParser.parse(raw));
await fooStore.save(foo);
await fooEvents.publish(foo);
```

After

```typescript
class FooFacade {
async create(raw: string) {
const foo = fooValidator.validate(fooParser.parse(raw));
await fooStore.save(foo);
await fooEvents.publish(foo);
}
}
```

### Proxy Pattern

- Kind: [pattern](https://banes-lab.com/records/kind/pattern.md)
- Severity: contextual
- Scope: access control, remote access, lazy loading
- Layer: [Design Patterns Core](https://banes-lab.com/records/layer/design-patterns-core.md)

Details

Requires
[Controlled Access](https://banes-lab.com/records/lex/controlled-access.md)

Reinforces
[Encapsulation](https://banes-lab.com/records/arch/encapsulation.md), [Security](https://banes-lab.com/records/lex/security.md)

Enables
[Lazy Load](https://banes-lab.com/records/lex/lazy-load.md), [Authorization](https://banes-lab.com/records/arch/authorization.md), [Remote Stub](https://banes-lab.com/records/lex/remote-stub.md)

In tension with
[Transparency / Debugging](https://banes-lab.com/records/lex/transparency-debugging.md)

Conflicts with
[Direct Access](https://banes-lab.com/records/lex/direct-access.md)

Tensions
[Proxy Pattern Transparency / Debugging](https://banes-lab.com/records/tension/proxy-pattern-transparency-debugging.md)

Violated by
uncontrolled direct resource access

Detected by
bypassed access wrapper

Measured by
proxy bypass count

Refactored by
Introduce Proxy

Enforced by
access rules

Before

```typescript
function loadFoo(id: FooId) { return remoteFooStore.find(id); }
```

After

```typescript
class CachingFooStoreProxy implements FooStore {
constructor(private readonly target: FooStore) {}
async find(id: FooId) {
const cached = fooCache.get(id);
if (cached) return cached;
const foo = await this.target.find(id);
fooCache.set(id, foo);
return foo;
}
}
```

### Bridge Pattern

- Kind: [pattern](https://banes-lab.com/records/kind/pattern.md)
- Severity: contextual
- Scope: abstraction, implementation variation
- Layer: [Design Patterns Core](https://banes-lab.com/records/layer/design-patterns-core.md)

Details

Requires
[Independent Variation Axes](https://banes-lab.com/records/lex/independent-variation-axes.md)

Reinforces
[Composition Over Inheritance](https://banes-lab.com/records/arch/composition-over-inheritance.md)

Enables
[Implementation Swap](https://banes-lab.com/records/lex/implementation-swap.md)

In tension with
[Indirection](https://banes-lab.com/records/lex/indirection.md)

Conflicts with
[Cartesian Inheritance Explosion](https://banes-lab.com/records/lex/cartesian-inheritance-explosion.md)

Tensions
[Bridge Pattern Indirection](https://banes-lab.com/records/tension/bridge-pattern-indirection.md)

Violated by
subclass explosion for combinations

Detected by
parallel hierarchies / deep variant classes

Measured by
variant class count

Refactored by
Introduce Bridge

Enforced by
[design review](https://banes-lab.com/records/arch/design-review.md)

Before

```typescript
class SqlJsonFooExporter {}
class SqlCsvFooExporter {}
class MemoryJsonFooExporter {}
class MemoryCsvFooExporter {}
```

After

```typescript
interface FooSource { read(): Promise<readonly Foo[]>; }
interface FooFormat { encode(foos: readonly Foo[]): string; }
class FooExporter {
constructor(private readonly source: FooSource, private readonly format: FooFormat) {}
async export() { return this.format.encode(await this.source.read()); }
}
```

### Decorator Pattern

- Kind: [pattern](https://banes-lab.com/records/kind/pattern.md)
- Severity: contextual
- Scope: behavior composition
- Layer: [Design Patterns Core](https://banes-lab.com/records/layer/design-patterns-core.md)

Details

Requires
[Common Interface](https://banes-lab.com/records/lex/common-interface.md)

Reinforces
[Open/Closed Principle (OCP)](https://banes-lab.com/records/arch/open-closed.md), [Composability](https://banes-lab.com/records/arch/composability.md)

Enables
[Runtime Behavior Extension](https://banes-lab.com/records/lex/runtime-behavior-extension.md)

In tension with
[Stack Debugging](https://banes-lab.com/records/lex/stack-debugging.md)

Conflicts with
[Subclass Explosion](https://banes-lab.com/records/lex/subclass-explosion.md)

Referenced by
[Composition Over Inheritance](https://banes-lab.com/records/arch/composition-over-inheritance.md)

Tensions
[Decorator Pattern Stack Debugging](https://banes-lab.com/records/tension/decorator-pattern-stack-debugging.md)

Violated by
many subclasses for optional features

Detected by
repeated wrapper-like subclasses

Measured by
variant explosion count

Refactored by
Introduce Decorator

Enforced by
interface conformance tests

Before

```typescript
class LoggedSqlFooStore extends SqlFooStore {
override save(foo: Foo) { logger.info("foo.saved", { fooId: foo.id }); return super.save(foo); }
}
```

After

```typescript
class LoggedFooStore implements FooStore {
constructor(private readonly inner: FooStore, private readonly log: Log) {}
save(foo: Foo) { this.log.write(foo.id); return this.inner.save(foo); }
}
```

### Composite Pattern

- Kind: [pattern](https://banes-lab.com/records/kind/pattern.md)
- Severity: recommended
- Scope: structure, tree, hierarchy
- Layer: [Design Patterns Core](https://banes-lab.com/records/layer/design-patterns-core.md)

Details

Requires
[Uniform Component Interface](https://banes-lab.com/records/lex/uniform-component-interface.md)

Reinforces
[Uniform Interface](https://banes-lab.com/records/arch/uniform-interface.md), [Open/Closed Principle (OCP)](https://banes-lab.com/records/arch/open-closed.md)

Enables
[Recursive Composition](https://banes-lab.com/records/lex/recursive-composition.md), [Leaf/Composite Transparency](https://banes-lab.com/records/lex/leaf-composite-transparency.md)

In tension with
[Type Safety](https://banes-lab.com/records/arch/type-safety.md)

Conflicts with
[Leaf-vs-Container Special-Casing](https://banes-lab.com/records/lex/leaf-vs-container-special-casing.md)

Tensions
[Composite Pattern Type Safety](https://banes-lab.com/records/tension/composite-pattern-type-safety.md)

Violated by
callers branching on leaf-vs-container at every node

Detected by
isContainer/isLeaf conditionals during traversal

Measured by
node-kind conditional count

Refactored by
Unify Leaf and Composite behind one interface

Enforced by
[design review](https://banes-lab.com/records/arch/design-review.md)

Before

```typescript
function totalFoo(item: Foo | FooGroup): number {
if ("children" in item) return item.children.reduce((sum, child) => sum + totalFoo(child), 0);
return item.value;
}
```

After

```typescript
interface FooComponent { total(): number; }
class FooLeaf implements FooComponent {
constructor(private readonly value: number) {}
total() { return this.value; }
}
class FooGroup implements FooComponent {
constructor(private readonly children: readonly FooComponent[]) {}
total() { return this.children.reduce((sum, child) => sum + child.total(), 0); }
}
```

### Flyweight Pattern

- Kind: [pattern](https://banes-lab.com/records/kind/pattern.md)
- Severity: contextual
- Scope: structure, memory, sharing
- Layer: [Design Patterns Core](https://banes-lab.com/records/layer/design-patterns-core.md)

Details

Requires
[Separable Intrinsic State](https://banes-lab.com/records/lex/separable-intrinsic-state.md)

Reinforces
[Memory Efficiency](https://banes-lab.com/records/arch/memory-efficiency.md)

Enables
[Shared Immutable State](https://banes-lab.com/records/lex/shared-immutable-state.md), [High-Cardinality Object Reuse](https://banes-lab.com/records/lex/high-cardinality-object-reuse.md)

In tension with
[Complexity](https://banes-lab.com/records/lex/complexity.md)

Conflicts with
[Per-Instance Duplicate State](https://banes-lab.com/records/lex/per-instance-duplicate-state.md)

Tensions
[Flyweight Pattern Complexity](https://banes-lab.com/records/tension/complexity-flyweight-pattern.md)

Violated by
identical heavy state duplicated across many instances

Detected by
repeated equal intrinsic state across objects

Measured by
duplicate-state memory footprint

Refactored by
Extract Flyweight, Share Intrinsic State

Enforced by
profiling review

Before

```typescript
const icons = foos.map(foo => new FooIcon(foo.position, loadSprite(foo.kind)));
```

After

```typescript
const spriteCache = new Map<string, Sprite>();
function fooSprite(kind: string) {
const cached = spriteCache.get(kind);
if (cached) return cached;
const sprite = loadSprite(kind);
spriteCache.set(kind, sprite);
return sprite;
}
const icons = foos.map(foo => ({ position: foo.position, sprite: fooSprite(foo.kind) }));
```

## Links to

- [pattern](https://banes-lab.com/records/kind/pattern.md)
- [Design Patterns Core](https://banes-lab.com/records/layer/design-patterns-core.md)
- [Incompatible Interfaces](https://banes-lab.com/records/lex/incompatible-interfaces.md)
- [Anti-Corruption Layer](https://banes-lab.com/records/arch/anti-corruption-layer.md)
- [Replaceability](https://banes-lab.com/records/arch/replaceability.md)
- [Interoperability](https://banes-lab.com/records/arch/interoperability.md)
- [Mapping Overhead](https://banes-lab.com/records/lex/mapping-overhead.md)
- [Direct External Coupling](https://banes-lab.com/records/lex/direct-external-coupling.md)
- [Interface-Based Design](https://banes-lab.com/records/arch/interface-based-design.md)
- [Adapter Pattern / Mapping Overhead](https://banes-lab.com/records/tension/adapter-pattern-mapping-overhead.md)
- [Subsystem Complexity](https://banes-lab.com/records/lex/subsystem-complexity.md)
- [Encapsulation](https://banes-lab.com/records/arch/encapsulation.md)
- [Information Hiding](https://banes-lab.com/records/arch/information-hiding.md)
- [Simplified Access](https://banes-lab.com/records/lex/simplified-access.md)
- [Over-Centralization](https://banes-lab.com/records/lex/over-centralization.md)
- [Leaky Subsystem API](https://banes-lab.com/records/lex/leaky-subsystem-api.md)
- [Facade Pattern / Over-Centralization](https://banes-lab.com/records/tension/facade-pattern-over-centralization.md)
- [Controlled Access](https://banes-lab.com/records/lex/controlled-access.md)
- [Security](https://banes-lab.com/records/lex/security.md)
- [Lazy Load](https://banes-lab.com/records/lex/lazy-load.md)
- [Authorization](https://banes-lab.com/records/arch/authorization.md)
- [Remote Stub](https://banes-lab.com/records/lex/remote-stub.md)
- [Transparency / Debugging](https://banes-lab.com/records/lex/transparency-debugging.md)
- [Direct Access](https://banes-lab.com/records/lex/direct-access.md)
- [Proxy Pattern / Transparency / Debugging](https://banes-lab.com/records/tension/proxy-pattern-transparency-debugging.md)
- [Independent Variation Axes](https://banes-lab.com/records/lex/independent-variation-axes.md)
- [Composition Over Inheritance](https://banes-lab.com/records/arch/composition-over-inheritance.md)
- [Implementation Swap](https://banes-lab.com/records/lex/implementation-swap.md)
- [Indirection](https://banes-lab.com/records/lex/indirection.md)
- [Cartesian Inheritance Explosion](https://banes-lab.com/records/lex/cartesian-inheritance-explosion.md)
- [Bridge Pattern / Indirection](https://banes-lab.com/records/tension/bridge-pattern-indirection.md)
- [Design Review](https://banes-lab.com/records/arch/design-review.md)
- [Common Interface](https://banes-lab.com/records/lex/common-interface.md)
- [Open/Closed Principle (OCP)](https://banes-lab.com/records/arch/open-closed.md)
- [Composability](https://banes-lab.com/records/arch/composability.md)
- [Runtime Behavior Extension](https://banes-lab.com/records/lex/runtime-behavior-extension.md)
- [Stack Debugging](https://banes-lab.com/records/lex/stack-debugging.md)
- [Subclass Explosion](https://banes-lab.com/records/lex/subclass-explosion.md)
- [Decorator Pattern / Stack Debugging](https://banes-lab.com/records/tension/decorator-pattern-stack-debugging.md)
- [Uniform Component Interface](https://banes-lab.com/records/lex/uniform-component-interface.md)
- [Uniform Interface](https://banes-lab.com/records/arch/uniform-interface.md)
- [Recursive Composition](https://banes-lab.com/records/lex/recursive-composition.md)
- [Leaf/Composite Transparency](https://banes-lab.com/records/lex/leaf-composite-transparency.md)
- [Type Safety](https://banes-lab.com/records/arch/type-safety.md)
- [Leaf-vs-Container Special-Casing](https://banes-lab.com/records/lex/leaf-vs-container-special-casing.md)
- [Composite Pattern / Type Safety](https://banes-lab.com/records/tension/composite-pattern-type-safety.md)
- [Separable Intrinsic State](https://banes-lab.com/records/lex/separable-intrinsic-state.md)
- [Memory Efficiency](https://banes-lab.com/records/arch/memory-efficiency.md)
- [Shared Immutable State](https://banes-lab.com/records/lex/shared-immutable-state.md)
- [High-Cardinality Object Reuse](https://banes-lab.com/records/lex/high-cardinality-object-reuse.md)
- [Complexity](https://banes-lab.com/records/lex/complexity.md)
- [Per-Instance Duplicate State](https://banes-lab.com/records/lex/per-instance-duplicate-state.md)
- [Flyweight Pattern / Complexity](https://banes-lab.com/records/tension/complexity-flyweight-pattern.md)

## Linked from

- [The layer topology](https://banes-lab.com/ontology/schema/the-layer-topology.md)
- [The membership](https://banes-lab.com/ontology/schema/the-membership.md)
