面向对象设计原则

发布时间:2023-05-21

一、SRP:单一职责原则

SRP即Single Responsibility Principle,指的是每个类都应该只有一个单一的职责。类的职责应该尽量简单明了,如果一个类承担的职责过多会影响代码的封装性、可读性和可维护性。 例如,一个员工类需要完成打印工资条和计算员工绩效这两个职责,可以将这两个职责拆分为两个类:打印工资条类和员工绩效类。这样可以降低类的复杂度,增加类的可复用性和灵活性。

class PrintSalary {
   public void print() {
       // 打印工资条
   }
}
class EmployeePerformance {
    public double calculatePerformance() {
        // 计算员工绩效
    }
}

二、OCP:开闭原则

OCP即Open-Closed Principle,指的是系统中的类、模块、函数等应该对扩展开放,对修改关闭。其实就是要求我们尽量使用继承、接口等方式,尽量不去修改原有的代码。 例如,现在有一个手机类,支持发短信、打电话、拍照等功能。那么为了实现新增功能,可以通过继承来实现,不用修改原手机类中的代码。

class MobilePhone {
   public void call() {
       // 打电话
   }
   public void sendSMS() {
       // 发短信
   }
   public void takePhoto() {
      // 拍照
   }
}
class NewMobilePhone extends MobilePhone {
   public void playGame() {
       // 手机新增玩游戏功能
   }
}

三、LSP:里氏替换原则

LSP即Liskov Substitution Principle,指的是子类可以替换其父类在任何场景下,程序的行为都应该保持不变。也就是说,在程序中使用基类对象的地方,如果用子类对象代替,程序的行为不应该受到影响。 例如,现在有一个鸟类的基类,其中有一个叫声的方法。那么替换成子类乌鸦时,在运行时也应该输出“哇哇”这个叫声。

class Bird {
   public void cry() {
       // 鸟的叫声
       System.out.println("叽叽喳喳");
   }
}
class Crow extends Bird {
   public void cry() {
       // 乌鸦的叫声
       System.out.println("哇哇");
   }
}

四、ISP:接口隔离原则

ISP即Interface Segregation Principle,指的是客户端不应该依赖它不需要的接口。一个类对另一个类的依赖应该建立在最小的接口上。 例如,现在有一个动物类,但是其中有一些不是所有动物都有的方法,如羊有毛而鱼没有,但是Animal中却有毛的方法。所以需要在类中设计接口,减少无用的接口。

interface Animal {
   void eat();
}
interface Swim {
   void swim();
}
interface Wool {
   void wool();
}
class Sheep implements Animal, Wool {
   public void eat() {
       System.out.println("羊吃草");
   }
   public void wool() {
       System.out.println("羊有毛");
   }
}
class Fish implements Animal, Swim {
   public void eat() {
       System.out.println("鱼吃水草");
   }
   public void swim() {
       System.out.println("鱼会游泳");
   }
}

五、DIP:依赖倒置原则

DIP即Dependency Inversion Principle,指的是高层模块不应该依赖低层模块,而是应该通过抽象来进行依赖。 例如,现在有一个学生类和成绩类,如果对学生进行操作,就需要依赖成绩类。那么我们就可以通过接口或抽象类等方式进行依赖。

interface IScore {
   public void setScore(Student stu);
}
class Student {
   private String name;
   public Student(String name) {
       this.name = name;
   }
   public String getName() {
       return name;
   }
}
class Score implements IScore {
   public void setScore(Student stu) {
       System.out.println(stu.getName() + "的成绩是90分");
   }
}
class StudentManager {
   private IScore score;
   public StudentManager(IScore score) {
       this.score = score;
   }
   public void setScore(Student stu) {
       score.setScore(stu);
   }
}