"Each pattern describes a problem which occurs over and over again in our environment, and then describes the core of the solution to that problem." — Christopher Alexander
Ensure a class has only one instance, provide global access.
class Singleton:
_instance = None
_lock = threading.Lock()
def __new__(cls):
if cls._instance is None:
with cls._lock:
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
def __init__(self):
if not hasattr(self, '_initialized'):
self._initialized = True
# initialization here
#include <mutex>
#include <memory>
class Singleton {
Singleton() = default;
~Singleton() = default;
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
public:
static Singleton& getInstance() {
static std::unique_ptr<Singleton> instance;
static std::once_flag flag;
std::call_once(flag, []{ instance = std::make_unique<Singleton>(); });
return *instance;
}
};
public final class Singleton {
private static volatile Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) instance = new Singleton();
}
}
return instance;
}
}
public sealed class Singleton {
private static readonly Lazy<Singleton> _instance =
new Lazy<Singleton>(() => new Singleton());
private Singleton() {}
public static Singleton Instance => _instance.Value;
}
Define interface for creating objects, let subclasses decide which class to instantiate.
from abc import ABC, abstractmethod
class Animal(ABC):
@abstractmethod
def speak(self) -> str:
pass
class Dog(Animal):
def speak(self) -> str:
return "Woof!"
class Cat(Animal):
def speak(self) -> str:
return "Meow!"
class AnimalFactory(ABC):
@abstractmethod
def create(self) -> Animal:
pass
class DogFactory(AnimalFactory):
def create(self) -> Animal:
return Dog()
class CatFactory(AnimalFactory):
def create(self) -> Animal:
return Cat()
#include <memory>
#include <iostream>
class Animal {
public:
virtual ~Animal() = default;
virtual void speak() const = 0;
};
class Dog : public Animal {
public:
void speak() const override { std::cout << "Woof!\n"; }
};
class Cat : public Animal {
public:
void speak() const override { std::cout << "Meow!\n"; }
};
class AnimalFactory {
public:
virtual ~AnimalFactory() = default;
virtual std::unique_ptr<Animal> create() = 0;
};
class DogFactory : public AnimalFactory {
public:
std::unique_ptr<Animal> create() override { return std::make_unique<Dog>(); }
};
class CatFactory : public AnimalFactory {
public:
std::unique_ptr<Animal> create() override { return std::make_unique<Cat>(); }
};
interface Animal {
void speak();
}
final class Dog implements Animal {
@Override public void speak() { System.out.println("Woof!"); }
}
final class Cat implements Animal {
@Override public void speak() { System.out.println("Meow!"); }
}
interface AnimalFactory {
Animal create();
}
final class DogFactory implements AnimalFactory {
@Override public Animal create() { return new Dog(); }
}
final class CatFactory implements AnimalFactory {
@Override public Animal create() { return new Cat(); }
}
public interface IAnimal {
void Speak();
}
public sealed class Dog : IAnimal {
public void Speak() => Console.WriteLine("Woof!");
}
public sealed class Cat : IAnimal {
public void Speak() => Console.WriteLine("Meow!");
}
public interface IAnimalFactory {
IAnimal Create();
}
public sealed class DogFactory : IAnimalFactory {
public IAnimal Create() => new Dog();
}
public sealed class CatFactory : IAnimalFactory {
public IAnimal Create() => new Cat();
}
Provide interface for creating families of related objects.
from abc import ABC, abstractmethod
class Button(ABC):
@abstractmethod
def render(self) -> str: pass
class Checkbox(ABC):
@abstractmethod
def render(self) -> str: pass
class WinButton(Button):
def render(self) -> str: return "[Windows Button]"
class MacButton(Button):
def render(self) -> str: return "[Mac Button]"
class WinCheckbox(Checkbox):
def render(self) -> str: return "[Windows Checkbox]"
class MacCheckbox(Checkbox):
def render(self) -> str: return "[Mac Checkbox]"
class GUIFactory(ABC):
@abstractmethod
def create_button(self) -> Button: pass
@abstractmethod
def create_checkbox(self) -> Checkbox: pass
class WinFactory(GUIFactory):
def create_button(self) -> Button: return WinButton()
def create_checkbox(self) -> Checkbox: return WinCheckbox()
class MacFactory(GUIFactory):
def create_button(self) -> Button: return MacButton()
def create_checkbox(self) -> Checkbox: return MacCheckbox()
class Button { public: virtual ~Button() = default; virtual void render() = 0; };
class Checkbox { public: virtual ~Checkbox() = default; virtual void render() = 0; };
class WinButton : public Button { void render() override { std::cout << "[Windows Button]\n"; } };
class MacButton : public Button { void render() override { std::cout << "[Mac Button]\n"; } };
class WinCheckbox : public Checkbox { void render() override { std::cout << "[Windows Checkbox]\n"; } };
class MacCheckbox : public Checkbox { void render() override { std::cout << "[Mac Checkbox]\n"; } };
class GUIFactory {
public:
virtual ~GUIFactory() = default;
virtual std::unique_ptr<Button> createButton() = 0;
virtual std::unique_ptr<Checkbox> createCheckbox() = 0;
};
class WinFactory : public GUIFactory {
public:
std::unique_ptr<Button> createButton() override { return std::make_unique<WinButton>(); }
std::unique_ptr<Checkbox> createCheckbox() override { return std::make_unique<WinCheckbox>(); }
};
class MacFactory : public GUIFactory {
public:
std::unique_ptr<Button> createButton() override { return std::make_unique<MacButton>(); }
std::unique_ptr<Checkbox> createCheckbox() override { return std::make_unique<MacCheckbox>(); }
};
interface Button { void render(); }
interface Checkbox { void render(); }
final class WinButton implements Button { public void render() { System.out.println("[Windows Button]"); } }
final class MacButton implements Button { public void render() { System.out.println("[Mac Button]"); } }
final class WinCheckbox implements Checkbox { public void render() { System.out.println("[Windows Checkbox]"); } }
final class MacCheckbox implements Checkbox { public void render() { System.out.println("[Mac Checkbox]"); } }
interface GUIFactory {
Button createButton();
Checkbox createCheckbox();
}
final class WinFactory implements GUIFactory {
public Button createButton() { return new WinButton(); }
public Checkbox createCheckbox() { return new WinCheckbox(); }
}
final class MacFactory implements GUIFactory {
public Button createButton() { return new MacButton(); }
public Checkbox createCheckbox() { return new MacCheckbox(); }
}
public interface IButton { void Render(); }
public interface ICheckbox { void Render(); }
public sealed class WinButton : IButton { public void Render() => Console.WriteLine("[Windows Button]"); }
public sealed class MacButton : IButton { public void Render() => Console.WriteLine("[Mac Button]"); }
public sealed class WinCheckbox : ICheckbox { public void Render() => Console.WriteLine("[Windows Checkbox]"); }
public sealed class MacCheckbox : ICheckbox { public void Render() => Console.WriteLine("[Mac Checkbox]"); }
public interface IGUIFactory {
IButton CreateButton();
ICheckbox CreateCheckbox();
}
public sealed class WinFactory : IGUIFactory {
public IButton CreateButton() => new WinButton();
public ICheckbox CreateCheckbox() => new WinCheckbox();
}
Separate construction from representation.
class Computer:
def __init__(self, cpu: str, ram: str, storage: str, gpu: str = ""):
self.cpu = cpu
self.ram = ram
self.storage = storage
self.gpu = gpu
def __str__(self) -> str:
return f"Computer({self.cpu}, {self.ram}, {self.storage}, {self.gpu})"
class ComputerBuilder:
def __init__(self):
self._cpu = ""
self._ram = ""
self._storage = ""
self._gpu = ""
def cpu(self, val: str) -> 'ComputerBuilder':
self._cpu = val
return self
def ram(self, val: str) -> 'ComputerBuilder':
self._ram = val
return self
def storage(self, val: str) -> 'ComputerBuilder':
self._storage = val
return self
def gpu(self, val: str) -> 'ComputerBuilder':
self._gpu = val
return self
def build(self) -> 'Computer':
return Computer(self._cpu, self._ram, self._storage, self._gpu)
# Usage
pc = ComputerBuilder().cpu("Intel i9").ram("32GB").storage("1TB SSD").gpu("RTX 4090").build()
#include <string>
class Computer {
std::string cpu_, ram_, storage_, gpu_;
Computer(std::string cpu, std::string ram, std::string storage, std::string gpu)
: cpu_(cpu), ram_(ram), storage_(storage), gpu_(gpu) {}
friend class Builder;
public:
class Builder {
std::string cpu_, ram_, storage_, gpu_;
public:
Builder& cpu(std::string v) { cpu_ = std::move(v); return *this; }
Builder& ram(std::string v) { ram_ = std::move(v); return *this; }
Builder& storage(std::string v) { storage_ = std::move(v); return *this; }
Builder& gpu(std::string v) { gpu_ = std::move(v); return *this; }
Computer build() { return Computer(cpu_, ram_, storage_, gpu_); }
};
};
public final class Computer {
private final String cpu, ram, storage, gpu;
private Computer(Builder b) { this.cpu = b.cpu; this.ram = b.ram; this.storage = b.storage; this.gpu = b.gpu; }
public static class Builder {
private String cpu = "", ram = "", storage = "", gpu = "";
public Builder cpu(String v) { this.cpu = v; return this; }
public Builder ram(String v) { this.ram = v; return this; }
public Builder storage(String v) { this.storage = v; return this; }
public Builder gpu(String v) { this.gpu = v; return this; }
public Computer build() { return new Computer(this); }
}
}
public sealed class Computer {
public string Cpu { get; }
public string Ram { get; }
public string Storage { get; }
public string Gpu { get; }
private Computer(Builder b) {
Cpu = b.Cpu; Ram = b.Ram; Storage = b.Storage; Gpu = b.Gpu;
}
public sealed class Builder {
public string Cpu { get; set; } = "";
public string Ram { get; set; } = "";
public string Storage { get; set; } = "";
public string Gpu { get; set; } = "";
public Computer Build() => new Computer(this);
}
}
// Usage
var pc = new Computer.Builder()
.Cpu("Intel i9").Ram("32GB").Storage("1TB SSD").Gpu("RTX 4090")
.Build();
Convert interface of class into another interface client expects.
from abc import ABC, abstractmethod
from typing import Dict
class LegacyXMLParser:
def parse_xml(self, xml: str) -> Dict[str, str]:
return {"data": "parsed from XML"}
class JSONParser(ABC):
@abstractmethod
def parse(self, json: str) -> Dict[str, str]: pass
class XMLToJSONAdapter(JSONParser):
def __init__(self, parser: 'LegacyXMLParser'):
self.parser = parser
def parse(self, json: str) -> Dict[str, str]:
xml = self.json_to_xml(json)
return self.parser.parse_xml(xml)
def json_to_xml(self, json: str) -> str:
# conversion logic
return "<xml>converted</xml>"
#include <map>
#include <string>
#include <memory>
class LegacyXMLParser {
public:
std::map<std::string, std::string> parseXML(const std::string& xml) {
return {{"data", "parsed from XML"}};
}
};
class JSONParser {
public:
virtual std::map<std::string, std::string> parse(const std::string& json) = 0;
virtual ~JSONParser() = default;
};
class XMLToJSONAdapter : public JSONParser {
std::unique_ptr<LegacyXMLParser> parser_;
public:
explicit XMLToJSONAdapter(std::unique_ptr<LegacyXMLParser> p) : parser_(std::move(p)) {}
std::map<std::string, std::string> parse(const std::string& json) override {
std::string xml = jsonToXML(json);
return parser_->parseXML(xml);
}
std::string jsonToXML(const std::string& json) { return "<xml>converted</xml>"; }
};
import java.util.*;
class LegacyXMLParser {
public Map<String, String> parseXML(String xml) {
return Map.of("data", "parsed from XML");
}
}
interface JSONParser {
Map<String, String> parse(String json);
}
class XMLToJSONAdapter implements JSONParser {
private final LegacyXMLParser parser;
public XMLToJSONAdapter(LegacyXMLParser p) { parser = p; }
public Map<String, String> parse(String json) {
String xml = jsonToXML(json);
return parser.parseXML(xml);
}
String jsonToXML(String json) { return "<xml>converted</xml>"; }
}
using System.Collections.Generic;
public class LegacyXMLParser {
public Dictionary<string, string> ParseXML(string xml) {
return new Dictionary<string, string> { {"data", "parsed from XML"} };
}
}
public interface IJSONParser {
Dictionary<string, string> Parse(string json);
}
public class XMLToJSONAdapter : IJSONParser {
private readonly LegacyXMLParser _parser;
public XMLToJSONAdapter(LegacyXMLParser p) => _parser = p;
public Dictionary<string, string> Parse(string json) {
string xml = JsonToXml(json);
return _parser.ParseXML(xml);
}
string JsonToXml(string json) => "<xml>converted</xml>";
}
Attach additional responsibilities dynamically.
from abc import ABC, abstractmethod
class Coffee(ABC):
@abstractmethod
def cost(self) -> float: pass
@abstractmethod
def description(self) -> str: pass
class SimpleCoffee(Coffee):
def cost(self) -> float: return 2.0
def description(self) -> str: return "Simple coffee"
class CoffeeDecorator(Coffee):
def __init__(self, coffee: Coffee):
self._coffee = coffee
def cost(self) -> float:
return self._coffee.cost()
def description(self) -> str:
return self._coffee.description()
class MilkDecorator(CoffeeDecorator):
def cost(self) -> float:
return self._coffee.cost() + 0.5
def description(self) -> str:
return self._coffee.description() + ", Milk"
class SugarDecorator(CoffeeDecorator):
def cost(self) -> float:
return self._coffee.cost() + 0.2
def description(self) -> str:
return self._coffee.description() + ", Sugar"
# Usage
coffee = SimpleCoffee()
coffee = MilkDecorator(coffee)
coffee = SugarDecorator(coffee)
print(f"{coffee.description()} = ${coffee.cost()}")
#include <string>
#include <memory>
#include <iostream>
class Coffee {
public:
virtual ~Coffee() = default;
virtual double cost() const = 0;
virtual std::string description() const = 0;
};
class SimpleCoffee : public Coffee {
double cost() const override { return 2.0; }
std::string description() const override { return "Simple coffee"; }
};
class CoffeeDecorator : public Coffee {
std::unique_ptr<Coffee> coffee_;
public:
explicit CoffeeDecorator(std::unique_ptr<Coffee> c) : coffee_(std::move(c)) {}
double cost() const override { return coffee_->cost(); }
std::string description() const override { return coffee_->description(); }
};
class MilkDecorator : public CoffeeDecorator {
public:
explicit MilkDecorator(std::unique_ptr<Coffee> c) : CoffeeDecorator(std::move(c)) {}
double cost() const override { return coffee_->cost() + 0.5; }
std::string description() const override { return coffee_->description() + ", Milk"; }
};
class SugarDecorator : public CoffeeDecorator {
public:
explicit SugarDecorator(std::unique_ptr<Coffee> c) : CoffeeDecorator(std::move(c)) {}
double cost() const override { return coffee_->cost() + 0.2; }
std::string description() const override { return coffee_->description() + ", Sugar"; }
};
interface Coffee {
double cost();
String description();
}
class SimpleCoffee implements Coffee {
public double cost() { return 2.0; }
public String description() { return "Simple coffee"; }
}
abstract class CoffeeDecorator implements Coffee {
protected final Coffee coffee;
CoffeeDecorator(Coffee c) { this.coffee = c; }
public double cost() { return coffee.cost(); }
public String description() { return coffee.description(); }
}
class MilkDecorator extends CoffeeDecorator {
public MilkDecorator(Coffee c) { super(c); }
public double cost() { return coffee.cost() + 0.5; }
public String description() { return coffee.description() + ", Milk"; }
}
class SugarDecorator extends CoffeeDecorator {
public SugarDecorator(Coffee c) { super(c); }
public double cost() { return coffee.cost() + 0.2; }
public String description() { return coffee.description() + ", Sugar"; }
}
using System;
public interface ICoffee {
double Cost { get; }
string Description { get; }
}
public sealed class SimpleCoffee : ICoffee {
public double Cost { get; } = 2.0;
public string Description { get; } = "Simple coffee";
}
public abstract class CoffeeDecorator : ICoffee {
protected readonly ICoffee Coffee;
protected CoffeeDecorator(ICoffee c) => Coffee = c;
public virtual double Cost => Coffee.Cost;
public virtual string Description => Coffee.Description;
}
public sealed class MilkDecorator : CoffeeDecorator {
public MilkDecorator(ICoffee c) : base(c) {}
public override double Cost => Coffee.Cost + 0.5;
public override string Description => Coffee.Description + ", Milk";
}
public sealed class SugarDecorator : CoffeeDecorator {
public SugarDecorator(ICoffee c) : base(c) {}
public override double Cost => Coffee.Cost + 0.2;
public override string Description => Coffee.Description + ", Sugar";
}
Define dependency so when one object changes, all dependents are notified.
from typing import Callable, List, Dict
from collections import defaultdict
class EventBus:
def __init__(self):
self._listeners: Dict[str, List[Callable]] = defaultdict(list)
def subscribe(self, event: str, callback: Callable) -> None:
self._listeners[event].append(callback)
def publish(self, event: str, data: dict = None) -> None:
for callback in self._listeners[event]:
callback(data or {})
# Usage
bus = EventBus()
bus.subscribe("enemy_killed", lambda d: print(f"Enemy killed: {d.get('enemy', 'unknown')}"))
bus.publish("enemy_killed", {"enemy": "goblin", "xp": 10})
#include <functional>
#include <unordered_map>
#include <vector>
#include <any>
class EventBus {
std::unordered_map<std::string, std::vector<std::function<void(const std::any&)>>> listeners_;
public:
template<typename F>
void subscribe(const std::string& event, F&& cb) {
listeners_[event].push_back(std::forward<F>(cb));
}
void publish(const std::string& event, const std::any& data = {}) {
for (auto& cb : listeners_[event]) cb(data);
}
};
// Usage
EventBus bus;
bus.subscribe("enemy_killed", [](const std::any& data) {
auto d = std::any_cast<std::map<std::string, int>>(data);
std::cout << "Enemy killed: " << d.at("enemy") << " xp: " << d.at("xp") << "\n";
});
bus.publish("enemy_killed", std::map<std::string, int>{{"enemy", 0}, {"xp", 10}});
import java.util.*;
import java.util.function.Consumer;
public class EventBus {
private final Map<String, List<Consumer<Map<String, Object>>>> listeners = new HashMap<>();
public void subscribe(String event, Consumer<Map<String, Object>> cb) {
listeners.computeIfAbsent(event, k -> new ArrayList<>()).add(cb);
}
public void publish(String event, Map<String, Object> data) {
for (var cb : listeners.getOrDefault(event, List.of())) cb.accept(data);
}
}
// Usage
EventBus bus = new EventBus();
bus.subscribe("enemy_killed", data ->
System.out.println("Enemy killed: " + data.get("enemy") + " xp: " + data.get("xp")));
bus.publish("enemy_killed", Map.of("enemy", "goblin", "xp", 10));
using System;
using System.Collections.Generic;
public class EventBus {
private readonly Dictionary<string, List<Action<Dictionary<string, object>>>> _listeners = new();
public void Subscribe(string evt, Action<Dictionary<string, object>> cb) {
if (!_listeners.TryGetValue(evt, out var list))
_listeners[evt] = new List<Action<Dictionary<string, object>>>();
_listeners[evt].Add(cb);
}
public void Publish(string evt, Dictionary<string, object> data = null) {
if (_listeners.TryGetValue(evt, out var list))
foreach (var cb in list) cb(data ?? new());
}
}
// Usage
var bus = new EventBus();
bus.Subscribe("enemy_killed", data =>
Console.WriteLine($"Enemy killed: {data["enemy"]} xp: {data["xp"]}"));
bus.Publish("enemy_killed", new Dictionary<string, object> { ["enemy"] = "goblin", ["xp"] = 10 });
Define family of algorithms, encapsulate each, make interchangeable.
from abc import ABC, abstractmethod
class CompressionStrategy(ABC):
@abstractmethod
def compress(self, data: str) -> str:
pass
class ZipStrategy(CompressionStrategy):
def compress(self, data: str) -> str:
return f"zip:{data}"
class GzipStrategy(CompressionStrategy):
def compress(self, data: str) -> str:
return f"gzip:{data}"
class Compressor:
def __init__(self, strategy: CompressionStrategy):
self.strategy = strategy
def compress(self, data: str) -> str:
return self.strategy.compress(data)
def set_strategy(self, strategy: CompressionStrategy) -> None:
self.strategy = strategy
# Usage — swap at runtime!
c = Compressor(ZipStrategy())
print(c.compress("data")) # "zip:data"
c.set_strategy(GzipStrategy())
print(c.compress("data")) # "gzip:data"
#include <memory>
#include <string>
class CompressionStrategy {
public:
virtual std::string compress(const std::string& data) = 0;
virtual ~CompressionStrategy() = default;
};
class ZipStrategy : public CompressionStrategy {
public:
std::string compress(const std::string& data) override { return "zip:" + data; }
};
class GzipStrategy : public CompressionStrategy {
public:
std::string compress(const std::string& data) override { return "gzip:" + data; }
};
class Compressor {
std::unique_ptr<CompressionStrategy> strategy_;
public:
explicit Compressor(std::unique_ptr<CompressionStrategy> s) : strategy_(std::move(s)) {}
std::string compress(const std::string& data) { return strategy_->compress(data); }
void setStrategy(std::unique_ptr<CompressionStrategy> s) { strategy_ = std::move(s); }
};
// Usage — swap at runtime!
Compressor c(std::make_unique<ZipStrategy>());
c.compress("data"); // "zip:data"
c.setStrategy(std::make_unique<GzipStrategy>());
c.compress("data"); // "gzip:data"
interface CompressionStrategy {
String compress(String data);
}
class ZipStrategy implements CompressionStrategy {
public String compress(String data) { return "zip:" + data; }
}
class GzipStrategy implements CompressionStrategy {
public String compress(String data) { return "gzip:" + data; }
}
public final class Compressor {
private CompressionStrategy strategy;
public Compressor(CompressionStrategy s) { this.strategy = s; }
public String compress(String data) { return strategy.compress(data); }
public void setStrategy(CompressionStrategy s) { this.strategy = s; }
}
// Usage — swap at runtime!
Compressor c = new Compressor(new ZipStrategy());
c.compress("data"); // "zip:data"
c.setStrategy(new GzipStrategy());
c.compress("data"); // "gzip:data"
public interface ICompressionStrategy {
string Compress(string data);
}
public sealed class ZipStrategy : ICompressionStrategy {
public string Compress(string data) => "zip:" + data;
}
public sealed class GzipStrategy : ICompressionStrategy {
public string Compress(string data) => "gzip:" + data;
}
public sealed class Compressor {
private ICompressionStrategy _strategy;
public Compressor(ICompressionStrategy s) => _strategy = s;
public string Compress(string data) => _strategy.Compress(data);
public void SetStrategy(ICompressionStrategy s) => _strategy = s;
}
// Usage — swap at runtime!
var c = new Compressor(new ZipStrategy());
c.Compress("data"); // "zip:data"
c.SetStrategy(new GzipStrategy());
c.Compress("data"); // "gzip:data"