SOLID 原则是面向对象设计中的五个基本原则,它们是:
- 单一职责原则(Single Responsibility Principle,SRP): 一个类应该只有一个引起变化的原因,即一个类应该只有一个责任。这意味着一个类应该只有一个导致它发生变化的原因,从而使类更加可维护和可理解。
- 开闭原则(Open/Closed Principle,OCP): 软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。这意味着当需要添加新功能时,应该通过扩展现有实体来实现,而不是修改已有代码。
- 里氏替换原则(Liskov Substitution Principle,LSP): 所有引用基类对象的地方必须能够透明地使用其子类的对象。子类应该能够替换掉父类并且仍然能够保持程序的正确性。
- 接口隔离原则(Interface Segregation Principle,ISP): 一个类不应该被强迫实现它不使用的接口。这意味着应该将接口拆分成更小的、更具体的接口,以确保类只需实现其真正需要的方法。
- 依赖倒置原则(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
接口而不是具体的形状类。