写在最前

文档地址:gitee.com/csps/mingyu…

规划形式

推荐浏览:软件规划形式

  • 代表了代码的最佳实践,被有经历的开发人员所运用;
  • 规划形式是许多被重复运用并知晓的,主要是对代码和经历的总结;
  • 运用规划形式是为了重用代码,让代码更容易被别人了解,确保代码的可靠性;
  • 对接口编程而不是对完结变成;
  • 有限运用目标组合而不是承继联系;

规划准则

规划形式的六大规划(第七点为后增)准则通常是指的面向目标规划准则,也被称为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):

    • 高层模块不应该依赖于低层模块,而是两者都应该依赖于笼统。笼统不应该依赖于详细完结,而详细完结应该依赖于笼统;
    • 依赖倒置准则是开闭准则的基础,针对接口进行编程;
    • 能够削减类之间的耦合行,进步体系稳定性,进步代码可读性和可维护性;
    • 下降修正程序所形成的危险;
  6. 迪米特规律(Law of Demeter,LoD):

    • 一个目标应该对其他目标有最少的了解,即一个目标不应该直接调用另一个目标内部的办法,而应该经过一些中介者来进行直接调用;
    • 为了下降类与类之间的耦合联系;
    • 强调只和朋友交流,不好陌生人说话。朋友指的是成员变量或办法中输入输出的参数;
  7. 组成复用准则(Composite Reuse Principle,CRP):

    • 尽量运用目标组合,聚合的办法,而不是运用承继联系到达软件复用的意图;
    • 能够使体系愈加灵敏,下降类与类之间的耦合度,一个类的改变对其他类形成的影响相对较少;

这些规划准则共同为面向目标规划提供了指导方针,有助于创建更灵敏、可维护和可扩展的代码。在应用这些准则时,规划形式通常被用来完结这些准则的详细规划方案。

单一责任准则

1.界说人类接口

人类都具有吃饭、睡觉的行为

public interface Human {
  /**
   * 吃饭
   */
  void eat();
​
  /**
   * 睡觉
   */
  void sleep();
}

2.界说程序员笼统类

程序员都需求作业

public abstract class Programmer implements Human {
  /**
   * 程序员都需求作业
   */
  abstract void work();
}

3.Java程序员

具有Java编写能力

public class JavaProgrammer extends Programmer {
  @Override
  public void eat() {
    System.out.println("Java程序员在吃饭");
   }
​
  @Override
  public void sleep() {
    System.out.println("Java程序员在睡觉");
   }
​
  @Override
  void work() {
    System.out.println("Java程序员在作业");
   }
​
  /**
   * Java程序员其他行为
   */
  void codeJava() {
    System.out.println("Java程序员在写Java代码");
   }
}

4.测验

public class Test {
  public static void main(String[] args) {
    JavaProgrammer javaProgrammer = new JavaProgrammer();
    javaProgrammer.codeJava();
    javaProgrammer.eat();
    javaProgrammer.work();
    javaProgrammer.sleep();
   }
}

敞开/封闭准则

1.界说人类接口

人类都具有吃饭、睡觉的行为

public interface Human {
  /**
   * 吃饭
   */
  void eat();
​
  /**
   * 睡觉
   */
  void sleep();
}

2.学生完结人类接口

学生都具有学习的行为

public class Student implements Human {
  @Override
  public void eat() {
    System.out.println("学生在吃饭");
   }
​
  @Override
  public void sleep() {
    System.out.println("学生在睡觉");
   }
​
  public void study() {
    System.out.println("学生在学习");
   }
}

3.添加高中生

满意开闭准则,添加高中生,但不修正学生类。

public class HighSchoolStudent extends Student {
  @Override
  public void eat() {
    System.out.println("高中生在吃饭");
   }
​
  @Override
  public void sleep() {
    System.out.println("高中生在睡觉");
   }
​
  @Override
  public void study() {
    System.out.println("高中生在学习");
   }
​
  /**
   * 扩展高中生独有的特点或行为
   */
  public void doSomeThing() {
    System.out.println("高中生在谈恋爱");
   }
}

4.测验

public class Test {
  public static void main(String[] args) {
    Student student = new Student();
    student.eat();
    student.sleep();
    student.study();
​
    // 不修正学生类(对修正封闭),添加高中生(对扩展开发)
    HighSchoolStudent highSchoolStudent = new HighSchoolStudent();
    highSchoolStudent.eat();
    highSchoolStudent.sleep();
    highSchoolStudent.study();
    highSchoolStudent.doSomeThing();
   }
}

里氏替换准则

1.界说老鼠类

public class Mouse {
  void burrow() {
    System.out.println("老鼠会打洞。。。");
   }
}

2.界说仓鼠类承继老鼠

public class Hamster extends Mouse {
  // 子类能够不修正父类的办法,仅仅承继并运用 (老鼠天生会打洞)
}

3.界说玩具鼠类承继老鼠

public class ToyMouse extends Mouse {
  @Override
  void burrow() {
    // 它能够掩盖 burrow 办法,但不应该修正已经存在的行为
    System.out.println("我是玩具鼠,我不会打洞,我会上天");
   }
}

4.测验

public class Test {
  public static void main(String[] args) {
    Hamster hamster = new Hamster();
    // 老鼠生的会打洞
    hamster.burrow();
​
    ToyMouse toyMouse = new ToyMouse();
    // 老鼠生的不会打洞,会上天,就违反了该准则
    toyMouse.burrow();
   }
}

接口阻隔准则

1.界说人类接口

public interface Human {}

2.人类行为拆分接口,进行接口阻隔

吃饭

public interface EatAction extends Human {
  void eat();
}

睡觉

public interface SleepAction extends Human {
  void sleep();
}

3.学生具有吃饭、睡觉的行为

public class Student implements EatAction, SleepAction {
  @Override
  public void eat() {
    System.out.println("学生在吃饭");
   }
​
  @Override
  public void sleep() {
    System.out.println("学生在睡觉");
   }
}

4.测验

public class Test {
  public static void main(String[] args) {
    Student student = new Student();
​
    student.eat();
    student.sleep();
   }
}

依赖倒置准则

1.界说人类接口

人类都具有吃饭、睡觉的行为

public interface Human {
  /**
   * 吃饭
   */
  void eat();
​
  /**
   * 睡觉
   */
  void sleep();
}

2.界说程序员笼统类

public abstract class Programmer implements Human {
​
  @Override
  public void eat() {
    System.out.println("程序员在吃饭");
   }
​
  @Override
  public void sleep() {
    System.out.println("程序员在睡觉");
   }
​
  /**
   * 程序员都需求作业
   */
  abstract void work();
}

界说Java程序员、测验程序员

Java程序员

public class JavaProgrammer extends Programmer {
  @Override
  public void eat() {
    System.out.println("Java程序员在吃饭");
   }
​
  @Override
  public void sleep() {
    System.out.println("Java程序员在睡觉");
   }
​
  @Override
  void work() {
    System.out.println("Java程序员在作业");
   }
}

测验程序员

public class TestProgrammer extends Programmer {
  @Override
  public void eat() {
    System.out.println("测验程序员在吃饭");
   }
​
  @Override
  public void sleep() {
    System.out.println("测验程序员在睡觉");
   }
​
  @Override
  void work() {
    System.out.println("测验程序员在作业");
   }
}

4.测验

public class Test {
  public static void main(String[] args) {
    JavaProgrammer javaProgrammer = new JavaProgrammer();
    javaProgrammer.eat();
    javaProgrammer.work();
    javaProgrammer.sleep();
​
    TestProgrammer testProgrammer = new TestProgrammer();
    testProgrammer.work();
   }
}

迪米特规律

1.界说人类接口

public interface Human {}

2.界说管理层接口并完结

public interface Manager extends Human {}

公司老板

public class Boss implements Manager {
  public void meet(TeamLeader teamLeader) {
    System.out.println("老板开会,发布使命");
    teamLeader.assignTasks();
   }
}

团队领导

public class TeamLeader implements Manager {
​
  private Programmer programmer;
​
  public void setProgrammer(Programmer programmer) {
    this.programmer = programmer;
   }
​
  public void assignTasks() {
    System.out.println("团队领导给研制分配使命");
​
    this.programmer.work();
   }
}

3.界说程序员接口并完结

public abstract class Programmer implements Human {
  /**
   * 程序员都需求作业
   */
  abstract void work();
}

Java程序员

public class JavaProgrammer extends Programmer {
​
  @Override
  void work() {
    System.out.println("Java程序员完结Java代码开发");
   }
}

4.测验

public class Test {
  public static void main(String[] args) {
    // 老板预备发布使命
    Boss boss = new Boss();
​
    // 找到项目经理
    TeamLeader teamLeader = new TeamLeader();
​
    // 项目经理拉上手底下研制
    JavaProgrammer javaProgrammer = new JavaProgrammer();
    teamLeader.setProgrammer(javaProgrammer);
​
    // 老板发布使命
    boss.meet(teamLeader);
   }
}

组成复用准则

1.界说轿车引擎

public class Engine {
  void start() {
    System.out.println("发动机正在发动");
   }
}

2.界说轿车

public class Car {
  private Engine engine;
​
  Car(Engine engine) {
    this.engine = engine;
   }
​
  void start() {
    engine.start();
    System.out.println("轿车正在发动");
   }
}

3.测验

public class Test {
  public static void main(String[] args) {
    // 在传统的承继办法下,可能会让Car承继自Engine,但这样的规划可能导致不必要的耦合,违反了组成复用准则。
    Engine engine = new Engine();
    // 运用组成复用准则经过组合来完结复用。
    Car car = new Car(engine);
    car.start();
   }
}