Did you ever wonder what SOLID principles are? - I’m pretty sure you have heard about them, so I’ll try to give you a brief introduction to them. SOLID principles were introduced by Uncle Bob on 2000’s, but they are becoming more and more popular nowadays.

I’m excited to launch a series dedicated to the SOLID principles, foundational concepts for crafting robust, maintainable, and scalable software. Throughout this series, I’ll dive into each principle with detailed Swift-centric examples to help you integrate these best practices into your development workflow.

What Are the SOLID Principles?

SOLID stands for five key design principles that significantly enhance software designs, making them more understandable, flexible, and maintainable. These principles, popularized by Robert C. Martin (Uncle Bob), are:

  • S: Single Responsibility Principle (SRP)
  • O: Open/Closed Principle (OCP)
  • L: Liskov Substitution Principle (LSP)
  • I: Interface Segregation Principle (ISP)
  • D: Dependency Inversion Principle (DIP)

Let’s see now these principles in some simple lines of code as a brief introduction.

Single Responsibility Principle (SRP)

  • Example: A FileHandler class solely focused on file operations.
  • Curiosity: Why does limiting a class to one activity promote better software development? We’ll explore how this principle avoids complications when your codebase evolves and how it simplifies unit testing.
class FileHandler {
    func readFile(path: String) -> String {
        // Read and return file content
    }

    func writeFile(path: String, content: String) {
        // Write content to file
    }
}

Open/Closed Principle (OCP)

  • Example: Using protocols to extend functionality of shapes without modifying existing code.
  • Curiosity: How can you add new features without altering existing code? Discover the power of Swift protocols in enabling flexible software extensions that respect existing code bases.
protocol Shape {
    func area() -> Double
}

class Rectangle: Shape {
    var width: Double
    var height: Double

    init(width: Double, height: Double) {
        self.width = width
        self.height = height
    }

    func area() -> Double {
        return width * height
    }
}

class Circle: Shape {
    var radius: Double

    init(radius: Double) {
        self.radius = radius
    }

    func area() -> Double {
        return .pi * radius * radius
    }
}

Liskov Substitution Principle (LSP)

  • Example: Substituting Bird objects with their subclass Duck and the problematic Ostrich.
  • Curiosity: What happens when a subclass breaks the expectations of the base class? Unveil the critical importance of subtype integrity to prevent breaking functionality.
class Bird {
    func fly() {
        print("Flying")
    }
}

class Duck: Bird {
    override func fly() {
        super.fly()
    }
}

class Ostrich: Bird {
    override func fly() {
        fatalError("Can't fly")
    }
}

Interface Segregation Principle (ISP)

  • Example: Dividing a monolithic interface into specialized ones that clients really use.
  • Curiosity: Why should classes not be burdened with interfaces they don’t use? Learn how appropriate abstraction fosters cleaner and more efficient Swift code.
protocol Workable {
    func work()
}

protocol Feedable {
    func eat()
}

class Human: Workable, Feedable {
    func work() {
        print("Working")
    }

    func eat() {
        print("Eating")
    }
}

Dependency Inversion Principle (DIP)

  • Example: Decoupling high-level business logic from data access specifics using protocols.
  • Curiosity: How does relying on abstractions rather than concrete implementations lead to more maintainable and flexible software architectures? Explore how Swift’s protocol-oriented programming can be a game changer.
protocol DataAccess {
    func saveData()
}

class DataManager: DataAccess {
    func saveData() {
        print("Data saved")
    }
}

class BusinessLogic {
    var dataAccess: DataAccess

    init(dataAccess: DataAccess) {
        self.dataAccess = dataAccess
    }
}

Coming Up Next

Stay tuned as we delve deeper into each principle in upcoming articles, complete with comprehensive examples and practical scenarios tailored to your Swift projects.

Help yourself and even others sharing this post to improve their skills sharing this article, #HappyCoding👨‍💻.

References