一文搞懂迪米特原则

迪米特原则,又称最少知识原则(Least Knowledge Principle, LKP),是面向对象设计和编程中的一项重要原则,其目标是降低类之间的耦合度,提高代码的可读性和可维护性。基本原则可以概括为:

原则描述:

  • 一个对象应当对其它对象有尽可能少的了解,即一个对象不应该直接访问非直接相关对象的方法或属性,而应通过其"朋友"或者代理进行间接交互。

  • "只和直接的朋友交谈",这里的"朋友"指的是:

    • 对象本身;
    • 对象所包含的对象(成员变量);
    • 对象的方法的参数;
    • 方法返回的对象。

具体实践方式:

  1. 限制对外部对象的直接引用:避免在一个类中直接访问另一个类的内部细节,例如不要直接操作外部对象的私有属性或方法。
  2. 通过委托进行通信:如果A对象需要调用B对象的某些功能,但A不是B的直接朋友,则可以引入一个中间者C,让C成为A的朋友并持有对B的引用,然后由C转发A对B的请求。
  3. 接口限定交互:使用接口而非具体实现来定义交互,这样客户端只需要知道接口而不是底层的具体实现,进一步减少耦合。

具体例子:

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

typescript 复制代码
// 定义抽象的接口以便解耦
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)隐藏了其内部实现细节,仅通过接口暴露名字。

因此,通过这样的设计,各层之间的耦合度得以降低,实现了迪米特原则。

优点:

  • 降低耦合度:通过减少类之间的直接联系,降低了修改一个类可能带来的连锁反应,提高了系统的稳定性和可维护性。
  • 增强模块独立性:遵循迪米特原则的设计可以使各个模块更加独立,每个模块仅需关注自己的职责和与其紧密相关的部分,更容易理解和测试。
  • 提高复用性和扩展性:因为类间的依赖减少了,所以更容易替换组件或增加新的功能,而不需要对现有大量代码进行修改。

潜在挑战:

  • 过度中介化:严格遵守迪米特原则可能会导致系统中出现大量中介类,这些类仅仅为了传递调用关系而存在,这可能导致系统变得复杂且难以理解。
  • 权衡:在实际设计中需要适度平衡迪米特原则和其他设计原则,确保系统的简洁性和性能不受影响。

总之,迪米特原则是一种指导设计思路的原则,帮助开发者组织代码结构,促进良好的封装性,并努力减少因类间过度耦合而导致的问题。在实践中,灵活运用这一原则能够改善软件设计的整体质量。

相关推荐
reddingtons6 小时前
【游戏宣发】PS “生成式扩展”流,30秒无损适配全渠道KV
游戏·设计模式·新媒体运营·prompt·aigc·教育电商·游戏美术
web小白成长日记6 小时前
企业级 Vue3 + Element Plus 主题定制架构:从“能用”到“好用”的进阶之路
前端·架构
APIshop6 小时前
Python 爬虫获取 item_get_web —— 淘宝商品 SKU、详情图、券后价全流程解析
前端·爬虫·python
风送雨7 小时前
FastMCP 2.0 服务端开发教学文档(下)
服务器·前端·网络·人工智能·python·ai
XTTX1107 小时前
Vue3+Cesium教程(36)--动态设置降雨效果
前端·javascript·vue.js
LYFlied8 小时前
WebGPU与浏览器边缘智能:开启去中心化AI新纪元
前端·人工智能·大模型·去中心化·区块链
Setsuna_F_Seiei8 小时前
2025 年度总结:人生重要阶段的一年
前端·程序员·年终总结
sxlishaobin8 小时前
设计模式之桥接模式
java·设计模式·桥接模式
model20058 小时前
alibaba linux3 系统盘网站迁移数据盘
java·服务器·前端
han_9 小时前
从一道前端面试题,谈 JS 对象存储特点和运算符执行顺序
前端·javascript·面试