迪米特准则,又称最少常识准则(Least Knowledge Principle, LKP),是面向目标规划和编程中的一项重要准则,其方针是下降类之间的耦合度,进步代码的可读性和可维护性。基本准则能够概括为:

准则描绘:

  • 一个目标应当对其它目标有尽或许少的了解,即一个目标不应该直接拜访非直接相关目标的办法或属性,而应经过其“朋友”或者署理进行直接交互。

  • “只和直接的朋友攀谈”,这里的“朋友”指的是:

    • 目标自身;
    • 目标所包含的目标(成员变量);
    • 目标的办法的参数;
    • 办法返回的目标。

详细实践方法:

  1. 约束对外部目标的直接引用:防止在一个类中直接拜访另一个类的内部细节,例如不要直接操作外部目标的私有属性或办法。
  2. 经过托付进行通讯:假如A目标需求调用B目标的某些功用,但A不是B的直接朋友,则能够引入一个中间者C,让C成为A的朋友并持有对B的引用,然后由C转发A对B的恳求。
  3. 接口限定交互:运用接口而非详细完成来界说交互,这样客户端只需求知道接口而不是底层的详细完成,进一步削减耦合。

详细比如:

假设我们有一个简单的场景,其间包含学生(Student)、课程(Course)以及教师(Teacher)这三个类。依照迪米特准则,学生不应该直接操作课程或教师的相关细节,而是经过某种中介机制直接交互。


// 界说笼统的接口以便解耦
interface ITeacher {
    getName(): string;
  }
  class Teacher implements ITeacher {
    private name: string;
    constructor(name: string) {
      this.name = name;
    }
    public getName() {
      return this.name;
    }
  }
  interface ICourse {
    getTeacher(): ITeacher;
    getName(): string;
  }
  class Course implements ICourse {
    private teacher: ITeacher;
    private courseName: string;
    constructor(courseName: string, teacher: ITeacher) {
      this.courseName = courseName;
      this.teacher = teacher;
    }
    public getTeacher() {
      return this.teacher;
    }
    public getName() {
      return this.courseName;
    }
  }
  class Student {
    private enrolledCourses: ICourse[];
    constructor(courses: ICourse[]) {
      this.enrolledCourses = courses;
    }
    // 遵循迪米特准则,学生不直接获取老师的信息,而是经过课程获取
    public getCourseTeacher(courseName: string): string | undefined {
      const course = this.enrolledCourses.find((course) => course.getName() === courseName);
      if (course) {
        const teacher = course.getTeacher();
        return teacher.getName(); // 直接获取教师的名字
      }
      return undefined;
    }
  }

在这个比如中:

  • 学生类(Student)只知道它所注册的课程(ICourse),并且经过课程类来获取教师的名字,而不会直接操作教师类(Teacher)。
  • 课程类(Course)供给了获取关联教师的办法,但它并不关怀详细的教师完成,只需教师符合ITeacher接口即可。
  • 教师类(Teacher)躲藏了其内部完成细节,仅经过接口暴露名字。

因而,经过这样的规划,各层之间的耦合度得以下降,完成了迪米特准则。

优点:

  • 下降耦合度:经过削减类之间的直接联系,下降了修正一个类或许带来的连锁反应,进步了体系的稳定性和可维护性。
  • 增强模块独立性:遵循迪米特准则的规划能够使各个模块愈加独立,每个模块仅需重视自己的职责和与其紧密相关的部分,更容易了解和测试。
  • 进步复用性和扩展性:由于类间的依赖削减了,所以更容易替换组件或增加新的功用,而不需求对现有很多代码进行修正。

潜在应战:

  • 过度中介化:严格遵守迪米特准则或许会导致体系中出现很多中介类,这些类仅仅为了传递调用关系而存在,这或许导致体系变得复杂且难以了解。
  • 权衡:在实际规划中需求适度平衡迪米特准则和其他规划准则,确保体系的简洁性和功能不受影响。

总归,迪米特准则是一种辅导规划思路的准则,协助开发者组织代码结构,促进杰出的封装性,并尽力削减因类间过度耦合而导致的问题。在实践中,灵活运用这一准则能够改善软件规划的整体质量。