a simple guide to software design principles from OOP to Functional Programming
Software design principles are guidelines that help us write better code. However, blindly following them can be as dangerous as ignoring them. Let’s explore these principles across different paradigms and understand when to apply them.
Core Principles
DRY vs WET vs AHA
DRY (Don’t Repeat Yourself)
Each piece of knowledge should have a single, unambiguous representation
But beware: Sometimes duplication is better than the wrong abstraction
WET (Write Everything Twice)
Wait until you need to write something three times before abstracting
Helps avoid premature abstractions
Also known as: Write Explicit Things
AHA (Avoid Hasty Abstractions)
Prefer duplication over the wrong abstraction
Wrong abstractions are more costly than duplication
When in doubt, duplicate first, abstract later
Object-Oriented Design
Gang of Four Patterns
Key patterns that remain relevant:
Creational Patterns
Factory Method: When object creation logic should be separate
Builder: For complex object construction
Singleton: When you genuinely need a single instance (rare!)
Structural Patterns
Adapter: Interface compatibility
Decorator: Dynamic behavior extension
Composite: Tree structures
Behavioral Patterns
Observer: Event handling
Strategy: Interchangeable algorithms
Command: Action encapsulation
SOLID Principles
Single Responsibility
A class should have one reason to change
But don’t make classes too granular
Open/Closed
Open for extension, closed for modification
Use interfaces and composition
Liskov Substitution
Subtypes must be substitutable for their base types
Avoid breaking inherited contracts
Interface Segregation
Many specific interfaces better than one general
Keep interfaces focused and cohesive
Dependency Inversion
Depend on abstractions, not concretions
Use dependency injection
Functional Design
Core FP Principles
Immutability
# Instead of modifying
defadd_item(list,item):list.append(item)# Mutates list
# Create new instance
defadd_item(list,item):returnlist+[item]# Returns new list