OOP, SOLID & Design Principles
Foundational software design principles: OOP pillars, SOLID rules, DRY, KISS, and TDD explained simply.
Object-Oriented Programming (OOP)
OOP is a programming paradigm based on the concept of objects, which can contain data (attributes) and code (methods).
Analogy:
- Class: The Blueprint/Instruction for building a house.
- Object: The actual built House.
Pros & Cons
Advantages:
- Structure: Better organization and readability.
- Reusability: Avoid code duplication via inheritance and polymorphism.
- Security: Encapsulation protects internal state.
- Scalability: Easier to manage large codebases.
Disadvantages:
- Complexity: Steeper learning curve.
- Boilerplate: Designing classes takes time.
- Performance: Can be less memory-efficient than procedural code.
The 3 Pillars of OOP
1. Encapsulation
Hiding the internal state and requiring all interaction to be performed through an object's methods (API).
- Benefit: Flexibility. You can change the internal logic without breaking external code.
- Analogy: Driving a car using the steering wheel (Interface) without needing to know how the engine works internally.
2. Inheritance
Creating new classes based on existing ones.
- The Child class inherits attributes and methods from the Parent class.
- Benefit: Code reuse and hierarchical organization (General -> Specific).
- Analogy: A "Sports Car" is a "Car", so it inherits wheels and an engine, but adds a turbo.
3. Polymorphism
One interface, many forms.
- Different objects can be treated as instances of the same parent class, but behave differently.
- Benefit: Flexibility.
- Analogy: A "Speak" command given to a Dog (Barks) and a Cat (Meows).
SOLID Principles
S - Single Responsibility Principle (SRP)
- Rule: A class should have one, and only one, reason to change.
- In other words: Don't create "God Classes". A "User" class shouldn't handle "PDF Exporting".
O - Open/Closed Principle (OCP)
- Rule: Entities should be Open for extension but Closed for modification.
- In other words: Add new features by creating new classes, not by changing existing, tested code.
L - Liskov Substitution Principle (LSP)
- Rule: Objects of a superclass should be replaceable with objects of its subclasses without breaking the application.
- In other words: A "Child" class shouldn't remove or break behavior expected from the "Parent". If a Parent can "Fly", the Child shouldn't throw an error when asked to "Fly".
I - Interface Segregation Principle (ISP)
- Rule: Clients should not be forced to depend on methods they do not use.
- In other words: Split large interfaces into smaller ones. A "Printer" interface shouldn't force a "Scanner" class to implement a "Fax()" method.
D - Dependency Inversion Principle (DIP)
- Rule: Depend on abstractions, not on concretions.
- In other words: Your business logic shouldn't know about "MySQLDriver". It should know about a "DatabaseInterface".
General Design Principles
DRY (Don't Repeat Yourself)
Every piece of knowledge must have a single, unambiguous representation within a system.
- Goal: Decompose complex logic into reusable functions/modules.
- Result: Easier maintenance and testing.
KISS (Keep It Short and Simple)
Avoid unnecessary complexity.
- Don't import a heavy library for one function.
- Don't over-engineer abstractions you don't need yet.
- "Simple code is better than clever code."
TDD (Test-Driven Development)
A development cycle:
- Red: Write a test for a new feature (it fails).
- Green: Write just enough code to pass the test.
- Refactor: Improve the code while keeping the test green.
- Benefit: High test coverage and confidence that the code works as expected from day one.