6.9 KiB
Design Patterns Cheatsheet
This repo implements seven patterns in C#, cross-referenced with Design Patterns: Elements of Reusable Object-Oriented Software (Gamma / Helm / Johnson / Vlissides — the "Gang of Four", GoF) and Dive Into Design Patterns (Alexander Shvets, 2019).
Every code sample comes from the actual project files. Each Output block reflects a real build and run of that project — none of the output is hand-traced.
The patterns
Structural — how to assemble objects and classes into larger structures.
| Pattern | One-line idea | Repo project |
|---|---|---|
| Bridge | Splits one exploding hierarchy into two, joined by composition. | patterns/bridge/Bridge Example/ |
| Decorator | Stacks wrappers, each adding one behavior, all sharing an interface. | patterns/decorator/ShapeDecorations/ |
| Facade | Hides a pile of fiddly subsystem classes behind one friendly class. | patterns/facade/CarEngineFacade/ (+ CarEngineFacadeRecording/) |
Behavioral — how objects communicate and divide responsibility.
| Pattern | One-line idea | Repo project |
|---|---|---|
| Mediator | Stops objects from calling each other directly; routes every call through one go-between. | patterns/mediator/AirTrafficControl/ |
| Memento | Lets an object snapshot itself, opaquely, for undo. | patterns/memento/MementoPattern/ |
| Observer | Publishes changes to a dynamic list of subscribed listeners. | patterns/observer/ObserverPattern/ (+ UpdatedOne/) |
| State | Replaces a giant switch on a state field with one class per state. |
patterns/state/BadCarState/ + CarState/ (+ WithStatePattern/, WithoutStatePattern/) |
Also in here
- Cross-pattern comparisons — the distinctions most likely to be tested and most likely to cause confusion in review, such as Bridge vs. State vs. Strategy, Decorator vs. Proxy vs. Adapter, and Facade vs. Mediator vs. Observer.
- Principles these examples keep demonstrating — encapsulate what varies, program to an interface, favor composition, the Single Responsibility Principle, and the Open/Closed Principle.
Quick reference: GoF intents (verbatim)
| Pattern | GoF Intent | Key structural move |
|---|---|---|
| Bridge | "Decouple an abstraction from its implementation so that the two can vary independently." | Abstraction has-a Implementor |
| Decorator | "Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality." | Wrapper is-a AND has-a Component |
| Facade | "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." | Facade has-many subsystem parts |
| Mediator | "Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently." | N×N links → N links to a hub |
| Memento | "Without violating encapsulation, capture and externalize an object's internal state so that the object can be restored to this state later." | Nested private snapshot class |
| Observer | "Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically." | Subject holds List<IObserver> |
| State | "Allow an object to alter its behavior when its internal state changes. The object will appear to change its class." | Context delegates to a swappable State |
Before / after pair
One pattern ships with a deliberately bad version alongside the patterned version. Diffing that pair teaches more than either version alone, so both are reproduced in full:
- State —
BadCarState(aswitchinside aswitch, four times over) vs.CarState(one class per state). The two produce byte-identical output, confirming the refactor changed structure and nothing else.
Run these projects
All projects target net10.0 and are wired into the root DesignPatterns.slnx.
Build and run any project directly with the .NET 10 SDK:
dotnet run --project "patterns/bridge/Bridge Example/Bridge Example.csproj"
CarState, BadCarState, WithStatePattern, WithoutStatePattern, and
MementoPattern read from stdin. Pipe input to them:
printf 'gas\nturn-clockwise\ngas\nbrake\nturn-counter\nexit\n' | dotnet run --project patterns/state/CarState/CarState.csproj
Each patterns/<pattern>/ folder also holds any in-class recording or
before/after variant alongside the canonical example — for example,
patterns/facade/CarEngineFacadeRecording/. The exercises/ folder holds
material that doesn't map to a specific GoF pattern, such as ClassIntroExam, a
pass-by-value-vs-reference demo.