包括 7 个,相互依赖,相互补充,即SOLID 原则+CL

设计原则名称设计原则简介
单一职责原则 (Single Responsibility Principle, SRP)类的职责要单一,不能将太多的职责放在一个类中
开闭原则 (Open-Closed Principle, OCP)软件实体对扩展是开放的,但对修改是关闭的,即在不修改一 个软件实体的基础上去扩展其功能
里氏代换原则 (Liskov Substitution Principle, LSP)在软件系统中,一个可以接受基类对象的地方必然可以接受一 个子类对象
依赖倒转原则 (Dependency Inversion Principle, DIP)要针对抽象层编程,而不要针对具体类编程
接口隔离原则 (Interface Segregation Principle, ISP)使用多个专门的接口来取代一个统一的接口
合成复用原则 (Composite Reuse Principle, CRP)在系统中应该尽量多使用组合和聚合关联关系,尽量少使用甚 至不使用继承关系
迪米特法则 (Law of Demeter, LoD)一个软件实体对其他实体的引用越少越好,或者说如果两个类 不必彼此直接通信,那么这两个类就不应当发生直接的相互作 用,而是通过引入一个第三者发生间接交互

里氏替换

classDiagram
    class Rectangle {
        +width: number
        +height: number
        +setWidth(w: number)
        +setHeight(h: number)
    }
    class Square {
        +setWidth(w: number)
        +setHeight(h: number)
    }
    Rectangle <|-- Square : 违反LSP

依赖倒转

classDiagram
    class UserAction {
        -sender: MessageSender
        +doAction()
    }
    class MessageSender {
        <<interface>>
        +send(message: string)
    }
    class EmailSender {
        +send(message: string)
    }
    class SMSSender {
        +send(message: string)
    }

    UserAction --> MessageSender
    MessageSender <|.. EmailSender
    MessageSender <|.. SMSSender

接口隔离原则(反例)

classDiagram
    class Worker {
        <<interface>>
        +work()
        +eat()
    }
    class Human {
        +work()
        +eat()
    }
    class Robot {
        +work()
        +eat()
    }
    Worker <|.. Human
    Worker <|.. Robot

正例

classDiagram
    class Workable {
        <<interface>>
        +work()
    }
    class Eatable {
        <<interface>>
        +eat()
    }
    class Human {
        +work()
        +eat()
    }
    class Robot {
        +work()
    }
    Workable <|.. Human
    Eatable <|.. Human
    Workable <|.. Robot
interface Workable {
    work(): void;
}
 
interface Eatable {
    eat(): void;
}
 
class Human implements Workable, Eatable {
    work() { console.log("人类在工作..."); }
    eat() { console.log("人类在吃饭..."); }
}
 
class Robot implements Workable {
    work() { console.log("机器人在工作..."); }
}

合成复用原则

classDiagram
    class Color {
        <<interface>>
        +fill()
    }
    class Red {
        +fill()
    }
    class Shape {
        -color: Color
        +draw()
    }
    Color <|.. Red
    Shape o-- Color : 组合/聚合关系

迪米特法则(反例)

假设一个“学校”系统,校长想要查看学生的信息。如果校长直接访问学生的内部对象链,就产生了过度的依赖。

classDiagram
    class Principal {
        +checkStudent(classroom: Classroom)
    }
    class Classroom {
        +getStudent() Student
    }
    class Student {
        +getName()
    }
    Principal ..> Classroom
    Principal ..> Student : 暴露了陌生人Student

正例

classDiagram
    class Principal {
        +checkStudent(classroom: Classroom)
    }
    class Classroom {
        +getStudentName() string
    }
    class Student {
        -name: string
    }
    Principal --> Classroom : 只与直接朋友通信
    Classroom --> Student