设计模式:七大基本原则

292 阅读5分钟

开闭原则 (最核心)

  1. 开闭原则:(Open Close Principle)简称OCP原则。
  2. 指类或者模块或者软件应该对内扩展开放,对外修改关闭。注意:对内指的是对提供方的内部的扩展,对外指的是对使用方。
  3. 抽象去搭建框架,用实现去扩展细节,当软件功能需要发生变化时,应该使用扩展的方式去应对变化,而不是去修改原有的逻辑去应对变化。

单一只能原则

  1. 就是一个类或者一个方法只具有一项职能,不应具有多项职能。
  2. 如果具有多项职能会导致要修改起来或者变化起来的成本非常高,非常麻烦。
  3. 单一职能原则的目的主要是降低类的复杂度,即一个类或者一个方法只负责一项职能,与其无关的职能工作不要冗余地写到一个这个类或者这个方法中
  4. 提高类的可读性和可维护性,降低了变更带来的不稳定风险。
  5. 通常情况下应该在类的层面遵守单一职能原则,只有在类中的方法数量足够少逻辑足够简单的情况下才保持在方法层面遵守单一职能原则。

里氏替换原则

  1. 是面向对象编程中对继承的一种规范和要求。就是子类不要去重写父类已经实现 的方法。极端例子:如果子类全部重写了父类的方法,那么子类继承父类这个操作 就毫无意义。 (猫不能继承狗类,会重写所有的实现。)
  2. 如果一个类需要使用到另一个类的功能,在合理的情况下可以使用继承的方式去设计实现。
  3. 是要考虑耦合度是否达到要求,如果要降低耦合度可以使用组合、聚合、依赖的方式去解决,如果是使用继承那么要遵循里氏替换原则。
  4. 比如狗如果继承猫类,则会重写所有的方法,改进方式:我们可以定义顶层 animal接口,再定义狗的抽象类,再提供一个 “哈士奇” 具体的实现类狗。

依赖倒置原则

  1. 就是高层模块不应该依赖于低层模块,二者都应该依赖其抽象。
  2. 其核心就是面向接口编程。
  3. 抽象不应该依赖细节,细节应该依赖抽象。
/**
 * 电脑类 高层类
 */
class Computer {
    /**
     * 接入设备方法, 只依赖于 低层的接口,而不是具体类  --->  客户端
     */
    public void access(USB usb){
        System.out.println("电脑上:"+usb.afterAccess());
    }
}

// 外接设备 抽象接口
interface USB {
    // 接入到电脑上
    public String afterAccess();
}

/**
 */
class Mouse implements USB {
    
    public String afterAccess() {
        return "鼠标已接入";
    }
}

/**
 * 键盘类
 */
class Keyboard implements USB {
    
    public String afterAccess(){
        return "键盘已接入";
    }
    
}

接口隔离原则

  1. 就是一个类对另一个类的依赖应建立在最小接口上。
  2. 通俗来讲就是一个客户端类使用到的一个接口实现类对象,应该可能会使用到其接口的所有方法,如果没有完全使用到,那么就是这个接口不是最小接口,这样的情况就没有遵守接口隔离原则。
  3. 核心:就是将不同的功能拆分到不同的接口中,互相隔离,互不影响,客户端在使用的时候,传递不同的接口即可。
  4. 如下,项目经理只需要依赖 coderEployee接口,保安队长只需要依赖 保安接,将原本包含所有功能的员工接口,拆分成2个接口。
  5. 这里的 项目经理、保安对象 依赖接口,而不依赖具体的实现,也符合 依赖倒置原则。
/**
 * 互联网公司保安员工接口
 */
interface SafetyEmployee {

    /**
     * 能打
     */
    public void canFighting();

    /**
     * 长得凶神恶煞
     */
    public void looksFierce();

}

/**
 * 互联网公司程序员员工接口
 * @author Peter
 */
interface CoderEmployee {

    /**
     * 会编程
     */
    public void canProgramming();

    /**
     * 取得高中学历
     */
    public void canGetHighSchoolEducation();
}

/**
 * 互联网公司保安员工
 * @author Peter
 */
class SafetyKeeper implements SafetyEmployee {

    public void canFighting() {
        System.out.println("保安能打!经常叫嚣:我要打十个!");
    }

    public void looksFierce() {
        System.out.println("保安长得凶神恶煞!能够震慑宵小之徒!");
    }

}

/**
 * 互联网公司程序员员工
 * @author Peter
 */
class Coder implements CoderEmployee {

    public void canProgramming() {
        System.out.println("程序员会运用Java语言进行编程!");
    }

    public void canGetHighSchoolEducation() {
        System.out.println("程序员取得高中学历具有一定的逻辑思维");
    }
}

/**
 * 互联网公司项目经理
 */
class ProjectManager {
    /**
     * 安排编程任务  --->  客户端
     */
    public void arrangeProgrammingTask(CoderEmployee emp) {
        emp.canGetHighSchoolEducation();
        emp.canProgramming();
    }
}

/**
 * 互联网公司保安队长 --->  客户端
 */
class SafetyCaptain {
    /**
     * 确保公司安全
     */
    public void makeCompanySafety(SafetyEmployee emp) {
        emp.looksFierce();
        emp.canFighting();
    }
}

合成复用原则

  1. 尽量使用聚合的方式而不要使用继承的方式达到复用原有代码目的。
  2. 就是你需要用到另外一个类的1、2个方法时候,不应该去继承,可以使用持有该对象,调用它即可。
    • 可以作为方法形参传递,也可以作为成员变量,同时抽象为接口类传递。

最少知道原则/迪米特法则

  1. 1987年秋天由lan holland在美国东北大学一个叫做迪米特的项目设计提出的,它要求一个对象应该对其他对象有最少的了解,所以迪米特法则又叫做最少知识原则(Least Knowledge Principle, LKP)。
  2. 迪米特法则的意义在于降低类之间的耦合
  3. 出现在成员变量、方法的输入输出参数中的类就是直接的朋友。迪米特法则要求只和直接的朋友通信。