定义

迪米特法则又称最少知识原则(Least Knowledge Principle, LKP)
只与你的直接朋友交谈,不跟“陌生人”说话

Talk only to your immediate friends and not to strangers

其含义是:如果两个软件实体无须直接通信,那么就不应当发生直接的相互调用,可以通过第三方转发该调用。其目的是降低类之间的耦合度,提高模块的相对独立性。

迪米特法则中的“朋友”是指:当前对象本身、当前对象的成员对象、当前对象所创建的对象、当前对象的方法参数等,这些对象同当前对象存在关联、聚合或组合关系,可以直接访问这些对象的方法。

迪米特法则的优点

迪米特法则要求限制软件实体之间通信的宽度和深度,正确使用迪米特法则将有以下两个优点。

  • 降低了类之间的耦合度,提高了模块的相对独立性。
  • 由于亲合度降低,从而提高了类的可复用率和系统的扩展性。

使用迪米特法则的平衡

过度使用迪米特法则会使系统产生大量的中介类,从而增加系统的复杂性,使模块之间的通信效率降低。所以,在釆用迪米特法则时需要反复权衡,确保高内聚和低耦合的同时,保证系统的结构清晰。

迪米特法则的实现方法

从迪米特法则的定义和特点可知,它强调以下两点:

  • 从依赖者的角度来说,只依赖应该依赖的对象。
  • 从被依赖者的角度说,只暴露应该暴露的方法。

案例:手机读书

需求:平常在零碎的时间里,喜欢看一些书籍,一般都是电子书,现在我们看书的操作是这样的:唤醒手机,打开阅读软件,选择书籍,然后阅读。总共 3 个步骤,涉及了 3 样东西:手机、软件、书籍。
可能会产生如下代码:

  1. // 测试类
  2. public class Test {
  3. public static void main(String[] args) {
  4. Phone phone = new Phone();
  5. phone.readBook();
  6. }
  7. }
  8. // 手机类
  9. class Phone {
  10. App app = new App();
  11. Book book = new Book("设计模式");
  12. public void readBook() {
  13. app.read(book);
  14. }
  15. }
  16. // app类
  17. class App {
  18. public void read(Book book) {
  19. System.out.println(book.getTitle());
  20. }
  21. }
  22. // 书类
  23. class Book {
  24. private String title;
  25. public Book(String title) {
  26. this.title = title;
  27. }
  28. public String getTitle() {
  29. return title;
  30. }
  31. public void setTitle(String title) {
  32. this.title = title;
  33. }
  34. }

代码是完成了读书这个过程,看样子是功能实现了,细看会发现代码的逻辑不对。哪里不对呢?书籍和应用对象都在手机上,现实是我们唤醒手机,这时手机是没有书籍的,只有当我们打开阅读软件,才有书籍可以看,没有阅读软件,书籍是看不了的。因此,手机和书籍没有一毛钱关系,书籍不应该在手机里面。正常的设计是:手机里面有阅读软件,阅读软件里面有书籍,这才符合迪米特法则,按定义来说:手机和阅读软件是朋友,阅读软件和书籍是朋友,可是朋友的朋友不是朋友,也就是手机和书籍不是朋友,所以它们不应该有交集,应该离得远远的。
正确示例:

  1. public class Test {
  2. public static void main(String[] args) {
  3. Phone phone = new Phone();
  4. phone.readBook();
  5. }
  6. }
  7. class Phone {
  8. private App app = new App();
  9. public void readBook() {
  10. app.read();
  11. }
  12. }
  13. class App {
  14. private Book book = new Book("设计模式");
  15. public void read() {
  16. System.out.println(book.getTitle());
  17. }
  18. }
  19. class Book {
  20. private String title;
  21. public Book(String title) {
  22. this.title = title;
  23. }
  24. public String getTitle() {
  25. return title;
  26. }
  27. public void setTitle(String title) {
  28. this.title = title;
  29. }
  30. }

现在这段代码就符合迪米特法则,手机中有阅读软件,阅读软件中有书籍,手机没有书籍任何影子。

参考链接

http://c.biancheng.net/view/1331.html
https://segmentfault.com/a/1190000017779269