1、开闭原则(Open Close Principle)

定义:对扩展开放,对修改关闭。

理解:使用接口和抽象类。

2、里氏代换原则(Liskov Substitution Principle)

定义:如果我们决定使用接口和抽象类,那么任何基类可以出现的地方,子类必须一定可以出现。

理解:LSP 是继承复用的基石,只有当派生类可以替换掉基类,且软件单位的功能不受到影响时,基类才能真正被复用,而派生类也能够在基类的基础上增加新的行为。

3、依赖倒转原则(Dependence Inversion Principle)

定义:针对接口编程,依赖于抽象而不依赖于具体。

4、接口隔离原则(Interface Segregation Principle)

定义:使用多个隔离的接口,比使用单个接口要好。它还有另外一个意思是:降低类之间的耦合度。

5、迪米特法则,又称最少知道原则(Demeter Principle)

定义:一个实体应当尽量少地与其他实体之间发生相互作用,使得系统功能模块相对独立。

理解:
  1. 使用类 不关心 被使用类 的内部,它只是使用 被使用类 提供的public方法而已。
  2. 类只和它的朋友类交流。
  3. 朋友间也是有距离的,不要让一个类过多地和另一个类交互。
  4. 是自己的就是自己的:一个方法,放在类A中可以,放在类B中也可以,尝试坚持这样一个原则:如果一个方法放在本类中,既不增加类间关系,也对本类不产生负面影响,那就放置在本类中。

    解释:
  5. 假设现在 一个老师 叫 体育委员 统计 班级人数:

    1. class Teacher {
    2. void command(GroupLeader groupLeader) {
    3. List<Student> students = new ArrayList<>();
    4. for (int i = 0; i < 20; i++) { //召集学生
    5. students.add(new Student());
    6. }
    7. groupLeader.countStudentSum(students); //叫组长数人数
    8. }
    9. }
    1. class GroupLeader {
    2. void countStudentSum(List<Student> students) {
    3. System.out.println(students.size()); //点人
    4. }
    5. }
    1. class Student {}
    • 总体的关系图:

image.pngimage.png

  1. - 现在,模拟一次老师叫组长数人数:
  1. public class Main {
  2. public static void main(String[] s) {
  3. Teacher teacher = new Teacher();
  4. teacher.command(new GroupLeader());
  5. }
  6. }
  1. - 分析以上操作:
  2. - `Teacher``GroupLeader`是朋友类,因为`GroupLeader`出现在了`Teacher`的方法参数中。
  3. - `Teacher``Student`不是朋友类,因为`Student`的实例出现在方法体中。`Teacher`在和陌生的类进行交流!
  4. - 这违反了LSP原则。
  1. 对上面类之间的关系进行改进:

    1. class Teacher { //删除了和陌生的Student交流
    2. void command(GroupLeader groupLeader) {
    3. groupLeader.countStudentSum(); //叫组长数人数
    4. }
    5. }
    1. class GroupLeader { //GroupLeader和Student的关系更加紧密了一点
    2. private List<Student> students;
    3. public GroupLeader(List<Student> students){
    4. this.students=students;
    5. }
    6. void countStudentSum() {
    7. System.out.println(this.students.size()); //点人
    8. }
    9. }
    1. class Student {
    2. }
    • 现在,再进行一次模拟的老师叫组长数人数:

      1. public class Main {
      2. public static void main(String[] s) {
      3. List<Student> students = new ArrayList<>(); //规定自己收多少学生
      4. for (int i = 0; i < 20; i++) { //招收学生
      5. students.add(new Student());
      6. }
      7. Teacher teacher = new Teacher();
      8. teacher.command(new GroupLeader(students));
      9. }
      10. }
    • 总体的关系:

image.pngimage.png

  1. - 分析以上操作:
  2. - `Teacher``GroupLeader`是朋友类,`Teacher`不再认识`Student`们。
  3. - `GroupLeader``Student`是朋友类。
  4. - `Teacher`不再负责召集`Student`,而是外界(`Main`)召集`Student`,老师现在完全只负责叫组长。老师**完全不需要考虑**“学生”。

6、合成(组合)复用原则(Composite Reuse Principle)

定义:尽量使用合成(组合)/聚合的方式,而不是使用继承。

7、其他和名称解释:

1.朋友类(满足以下任一要求):
  • 出现在成员变量处(即类内部属性)。
  • 出现在方法的输入输出参数中。

2.本文借鉴:https://blog.csdn.net/weixin_34204722/article/details/90089329