Skip to content

Instantly share code, notes, and snippets.

@psahni
Last active August 16, 2024 13:08
Show Gist options
  • Save psahni/18ab78c5f747c353967e3e3a6cba1417 to your computer and use it in GitHub Desktop.
Save psahni/18ab78c5f747c353967e3e3a6cba1417 to your computer and use it in GitHub Desktop.
Design Patterns

Factory Pattern

// Factory Pattern
pf: = ProductFactory{}
pf.createProduct("jeans")


// Product is interface 

createProduct(type string) Product {
	if type == "jeans" {
		return Jeans{}
	}
}

Adaptor Pattern

# Existing class with incompatible interface
class OldPrinter:
    def print_old(self, text):
        print(f"[Old Printer] {text}")

# Target interface
class Printer:
    def print(self, text):
        pass

# Adapter
class PrinterAdapter(Printer):
    def __init__(self, old_printer):
        self.old_printer = old_printer

    def print(self, text):
        self.old_printer.print_old(text)

# Client code
def client_code(printer):
    printer.print("Hello, World!")

# Usage
old_printer = OldPrinter()
adapter = PrinterAdapter(old_printer)
client_code(adapter)

Decorator Pattern

from abc import ABC, abstractmethod

# Component interface
class Coffee(ABC):
    @abstractmethod
    def cost(self):
        pass

    @abstractmethod
    def description(self):
        pass

# Concrete component
class SimpleCoffee(Coffee):
    def cost(self):
        return 5

    def description(self):
        return "Simple coffee"

# Decorator base class
class CoffeeDecorator(Coffee):
    def __init__(self, coffee):
        self._coffee = coffee

    def cost(self):
        return self._coffee.cost()

    def description(self):
        return self._coffee.description()

# Concrete decorators
class Milk(CoffeeDecorator):
    def cost(self):
        return self._coffee.cost() + 2

    def description(self):
        return f"{self._coffee.description()}, milk"

class Sugar(CoffeeDecorator):
    def cost(self):
        return self._coffee.cost() + 1

    def description(self):
        return f"{self._coffee.description()}, sugar"

# Usage
simple_coffee = SimpleCoffee()
print(f"{simple_coffee.description()}: ${simple_coffee.cost()}")

milk_coffee = Milk(simple_coffee)
print(f"{milk_coffee.description()}: ${milk_coffee.cost()}")

sweet_milk_coffee = Sugar(Milk(simple_coffee))
print(f"{sweet_milk_coffee.description()}: ${sweet_milk_coffee.cost()}")

Facade Pattern

# Complex subsystem classes
class CPU:
    def freeze(self): print("CPU: Freezing...")
    def jump(self, position): print(f"CPU: Jumping to {position}")
    def execute(self): print("CPU: Executing...")

class Memory:
    def load(self, position, data): print(f"Memory: Loading {data} to {position}")

class HardDrive:
    def read(self, sector, size): return f"Data from sector {sector} with size {size}"

# Facade
class ComputerFacade:
    def __init__(self):
        self.cpu = CPU()
        self.memory = Memory()
        self.hard_drive = HardDrive()

    def start(self):
        self.cpu.freeze()
        self.memory.load("BOOT_ADDRESS", self.hard_drive.read("BOOT_SECTOR", "BOOT_SIZE"))
        self.cpu.jump("BOOT_ADDRESS")
        self.cpu.execute()

# Client code
computer = ComputerFacade()
computer.start()
@psahni
Copy link
Author

psahni commented Aug 16, 2024

Strategy Pattern

interface PaymentStrategy {
    processPayment(amount: number): void;
}
class CreditCardPayment implements PaymentStrategy {
    processPayment(amount: number): void {
        console.log(`Processing credit card payment of ${amount}`);
    }
}
class PayPalPayment implements PaymentStrategy {
    processPayment(amount: number): void {
        console.log(`Processing PayPal payment of ${amount}`);
    }
}

class CryptoPayment implements PaymentStrategy {
    processPayment(amount: number): void {
        console.log(`Processing cryptocurrency payment of ${amount}`);
    }
}
class PaymentContext {
    private strategy: PaymentStrategy;

    constructor(strategy: PaymentStrategy) {
        this.strategy = strategy;
    }

    public setStrategy(strategy: PaymentStrategy) {
        this.strategy = strategy;
    }

    public executeStrategy(amount: number): void {
        this.strategy.processPayment(amount);
    }
}
// Choose a payment method at runtime
const paymentContext = new PaymentContext(new CreditCardPayment());
paymentContext.executeStrategy(100); // Processing credit card payment of 100

paymentContext.setStrategy(new PayPalPayment());
paymentContext.executeStrategy(200); // Processing PayPal payment of 200

paymentContext.setStrategy(new CryptoPayment());
paymentContext.executeStrategy(300); // Processing cryptocurrency payment of 300

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment