Files
freemo d9e5668cec fix(skills): comprehensive final audit pass for programming-patterns skill
Fixes and improvements from exhaustive audit:

Consistency fixes in SKILL.md:
- 'Pipe & Filter' → 'Pipe and Filter' (one stray '&' found and corrected)
- 'Singleton for factory instance' → clarified to 'register factory as
  singleton-scoped via DI container' (less misleading wording)
- Documentation Format section updated with note that SKILL.md itself is the
  authoritative source for related-pattern combinations

Coverage fix — Related Patterns sections:
- Added '## Related Patterns' to ALL 94 pattern files (was 0/94)
- Each section lists 3–6 related patterns with relationship descriptions
- Covers: why they're related, when to prefer one vs the other,
  and which are often confused

SOLID principles → Creational → Structural → Behavioral → Architectural →
Concurrency → Functional → Resilience → Data Access → Messaging →
Testing → Error Handling → Microservice — all 13 categories covered

Code verification:
- Python: 0 failures (all 85 testable blocks pass)
- Go: 0 failures (all 76 testable blocks pass)
- JavaScript: 0 failures (all 78 testable blocks pass)
- All 239 code blocks verified correct after edits

Final skill state:
- 108 files, 36,524 lines across 13 reference categories
- 94/94 pattern files have Related Patterns sections
- 2,815-line SKILL.md with 67 decision trees, 23 scenarios,
  0 broken references, 0 naming inconsistencies
2026-04-15 13:22:13 -04:00

8.3 KiB

Facade Pattern

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.

Problem

A home theater system has many components — Projector, SoundSystem, Lights, MediaPlayer — each with its own API. Starting a movie requires calling multiple methods in the right order across several objects. Clients shouldn't need to know every subsystem detail.

Solution

Create a HomeTheater facade that exposes simple operations like watch_movie() and end_movie(), internally orchestrating all the subsystem calls.

┌──────────┐
│  Client  │
└────┬─────┘
     │
     ▼
┌─────────────────┐
│   HomeTheater   │  ◄── Facade
│   (facade)      │
│ + watch_movie() │
│ + end_movie()   │
└──┬──┬──┬──┬─────┘
   │  │  │  │
   ▼  ▼  ▼  ▼
 Projector  SoundSystem  Lights  MediaPlayer

When to Use

  • You need a simple interface to a complex subsystem.
  • There are many dependencies between clients and the implementation classes.
  • You want to layer your subsystems and provide entry points to each layer.

When to Avoid

  • The subsystem is already simple enough that a facade adds no value.
  • Clients genuinely need fine-grained control over subsystem components.
  • The facade becomes a "god object" that does too much — split into multiple facades.

Pseudocode

class Projector:
    method on():   output "Projector on"
    method off():  output "Projector off"

class SoundSystem:
    method on():         output "Sound on"
    method set_volume(v): output "Volume set to " + v
    method off():        output "Sound off"

class Lights:
    method dim(level):   output "Lights dimmed to " + level + "%"
    method on():         output "Lights on"

class MediaPlayer:
    method play(movie):  output "Playing: " + movie
    method stop():       output "Player stopped"

class HomeTheater:
    field projector, sound, lights, player

    constructor(projector, sound, lights, player):
        assign all fields

    method watch_movie(movie):
        output "=== Preparing to watch movie ==="
        lights.dim(10)
        projector.on()
        sound.on()
        sound.set_volume(8)
        player.play(movie)

    method end_movie():
        output "=== Shutting down ==="
        player.stop()
        sound.off()
        projector.off()
        lights.on()

Python

class Projector:
    def on(self) -> None:
        print("Projector on")

    def off(self) -> None:
        print("Projector off")


class SoundSystem:
    def on(self) -> None:
        print("Sound system on")

    def set_volume(self, level: int) -> None:
        print(f"Volume set to {level}")

    def off(self) -> None:
        print("Sound system off")


class Lights:
    def dim(self, percent: int) -> None:
        print(f"Lights dimmed to {percent}%")

    def on(self) -> None:
        print("Lights on full")


class MediaPlayer:
    def play(self, movie: str) -> None:
        print(f"Playing: {movie}")

    def stop(self) -> None:
        print("Player stopped")


class HomeTheater:
    """Facade that simplifies home theater operations."""

    def __init__(
        self,
        projector: Projector,
        sound: SoundSystem,
        lights: Lights,
        player: MediaPlayer,
    ) -> None:
        self._projector = projector
        self._sound = sound
        self._lights = lights
        self._player = player

    def watch_movie(self, movie: str) -> None:
        print("=== Preparing to watch movie ===")
        self._lights.dim(10)
        self._projector.on()
        self._sound.on()
        self._sound.set_volume(8)
        self._player.play(movie)
        print()

    def end_movie(self) -> None:
        print("=== Shutting down ===")
        self._player.stop()
        self._sound.off()
        self._projector.off()
        self._lights.on()


if __name__ == "__main__":
    theater = HomeTheater(
        projector=Projector(),
        sound=SoundSystem(),
        lights=Lights(),
        player=MediaPlayer(),
    )

    theater.watch_movie("The Matrix")
    theater.end_movie()

Output:

=== Preparing to watch movie ===
Lights dimmed to 10%
Projector on
Sound system on
Volume set to 8
Playing: The Matrix

=== Shutting down ===
Player stopped
Sound system off
Projector off
Lights on full

Go

package main

import "fmt"

// --- Subsystem components ---

type Projector struct{}

func (p *Projector) On()  { fmt.Println("Projector on") }
func (p *Projector) Off() { fmt.Println("Projector off") }

type SoundSystem struct{}

func (s *SoundSystem) On()              { fmt.Println("Sound system on") }
func (s *SoundSystem) SetVolume(v int)  { fmt.Printf("Volume set to %d\n", v) }
func (s *SoundSystem) Off()             { fmt.Println("Sound system off") }

type Lights struct{}

func (l *Lights) Dim(percent int) { fmt.Printf("Lights dimmed to %d%%\n", percent) }
func (l *Lights) On()             { fmt.Println("Lights on full") }

type MediaPlayer struct{}

func (m *MediaPlayer) Play(movie string) { fmt.Printf("Playing: %s\n", movie) }
func (m *MediaPlayer) Stop()             { fmt.Println("Player stopped") }

// --- Facade ---

type HomeTheater struct {
	projector *Projector
	sound     *SoundSystem
	lights    *Lights
	player    *MediaPlayer
}

func NewHomeTheater() *HomeTheater {
	return &HomeTheater{
		projector: &Projector{},
		sound:     &SoundSystem{},
		lights:    &Lights{},
		player:    &MediaPlayer{},
	}
}

func (h *HomeTheater) WatchMovie(movie string) {
	fmt.Println("=== Preparing to watch movie ===")
	h.lights.Dim(10)
	h.projector.On()
	h.sound.On()
	h.sound.SetVolume(8)
	h.player.Play(movie)
	fmt.Println()
}

func (h *HomeTheater) EndMovie() {
	fmt.Println("=== Shutting down ===")
	h.player.Stop()
	h.sound.Off()
	h.projector.Off()
	h.lights.On()
}

func main() {
	theater := NewHomeTheater()
	theater.WatchMovie("The Matrix")
	theater.EndMovie()
}

Output:

=== Preparing to watch movie ===
Lights dimmed to 10%
Projector on
Sound system on
Volume set to 8
Playing: The Matrix

=== Shutting down ===
Player stopped
Sound system off
Projector off
Lights on full

JavaScript

// --- Subsystem components ---

class Projector {
  on() {
    console.log("Projector on");
  }
  off() {
    console.log("Projector off");
  }
}

class SoundSystem {
  on() {
    console.log("Sound system on");
  }
  setVolume(level) {
    console.log(`Volume set to ${level}`);
  }
  off() {
    console.log("Sound system off");
  }
}

class Lights {
  dim(percent) {
    console.log(`Lights dimmed to ${percent}%`);
  }
  on() {
    console.log("Lights on full");
  }
}

class MediaPlayer {
  play(movie) {
    console.log(`Playing: ${movie}`);
  }
  stop() {
    console.log("Player stopped");
  }
}

// --- Facade ---

class HomeTheater {
  constructor() {
    this._projector = new Projector();
    this._sound = new SoundSystem();
    this._lights = new Lights();
    this._player = new MediaPlayer();
  }

  watchMovie(movie) {
    console.log("=== Preparing to watch movie ===");
    this._lights.dim(10);
    this._projector.on();
    this._sound.on();
    this._sound.setVolume(8);
    this._player.play(movie);
    console.log();
  }

  endMovie() {
    console.log("=== Shutting down ===");
    this._player.stop();
    this._sound.off();
    this._projector.off();
    this._lights.on();
  }
}

// --- Main ---
const theater = new HomeTheater();
theater.watchMovie("The Matrix");
theater.endMovie();

Output:

=== Preparing to watch movie ===
Lights dimmed to 10%
Projector on
Sound system on
Volume set to 8
Playing: The Matrix

=== Shutting down ===
Player stopped
Sound system off
Projector off
Lights on full
  • Adapter — Both wrap complex things. Adapter makes incompatible interfaces compatible; Facade simplifies a complex subsystem without changing the interface.
  • Mediator — Both simplify interactions. Facade is one-way (client to subsystem); Mediator is multi-directional (coordinates between subsystem components).
  • Service Layer — Service Layer is an application-level Facade over the domain and data access layers.
  • Module — Module is a code-organization Facade: it groups related functionality and exposes a clean public API.