SOLID 简单理解

41 阅读2分钟

SOLID 原则是面向对象设计中的五个基本原则,它们是:

  1. 单一职责原则(Single Responsibility Principle,SRP): 一个类应该只有一个引起变化的原因,即一个类应该只有一个责任。这意味着一个类应该只有一个导致它发生变化的原因,从而使类更加可维护和可理解。
  2. 开闭原则(Open/Closed Principle,OCP): 软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。这意味着当需要添加新功能时,应该通过扩展现有实体来实现,而不是修改已有代码。
  3. 里氏替换原则(Liskov Substitution Principle,LSP): 所有引用基类对象的地方必须能够透明地使用其子类的对象。子类应该能够替换掉父类并且仍然能够保持程序的正确性。
  4. 接口隔离原则(Interface Segregation Principle,ISP): 一个类不应该被强迫实现它不使用的接口。这意味着应该将接口拆分成更小的、更具体的接口,以确保类只需实现其真正需要的方法。
  5. 依赖倒置原则(Dependency Inversion Principle,DIP): 高层模块不应该依赖于底层模块,二者都应该依赖于抽象;抽象不应该依赖于具体细节,具体细节应该依赖于抽象。

让我们通过一个 Swift 的例子来说明这些原则。假设我们有一个图形绘制的程序,其中包含不同类型的形状(Shape)。我们来设计这个程序,符合 SOLID 原则。

// 单一职责原则(Single Responsibility Principle,SRP)
protocol Shape {
    func draw()
}

// 开闭原则(Open/Closed Principle,OCP)
class Circle: Shape {
    func draw() {
        print("Draw a circle")
    }
}

class Square: Shape {
    func draw() {
        print("Draw a square")
    }
}

// 里氏替换原则(Liskov Substitution Principle,LSP)
func drawShapes(shapes: [Shape]) {
    for shape in shapes {
        shape.draw()
    }
}

// 接口隔离原则(Interface Segregation Principle,ISP)
protocol SolidShape {
    func calculateVolume() -> Double
}

class Cube: Shape, SolidShape {
    func draw() {
        print("Draw a cube")
    }

    func calculateVolume() -> Double {
        return 0.0 // Not implemented for simplicity
    }
}

// 依赖倒置原则(Dependency Inversion Principle,DIP)
class Drawing {
    var shapes: [Shape] = []

    func addShape(shape: Shape) {
        shapes.append(shape)
    }

    func draw() {
        for shape in shapes {
            shape.draw()
        }
    }
}

let circle = Circle()
let square = Square()
let cube = Cube()

let drawing = Drawing()
drawing.addShape(shape: circle)
drawing.addShape(shape: square)
drawing.addShape(shape: cube)

drawing.draw()

这个例子中,每个类和协议都有清晰的职责,遵循单一职责原则。新增形状时,我们只需要添加新的类而不是修改现有类,符合开闭原则。通过使用协议,我们保证了里氏替换原则的实现。接口隔离原则通过将不同功能的方法分离到不同的协议中得以体现。最后,依赖倒置原则通过高层的 Drawing 类依赖于抽象的 Shape 接口而不是具体的形状类。