基本介绍

1) 一个对象应该对其他对象保持最少的了
2) 类与类关系越密切,耦合度越大
3) 迪米特法则(Demeter Principle)又叫最少知道原则,即一个类对自己依赖的类知道的
越少越好。也就是说,对于被依赖的类不管多么复杂,都尽量将逻辑封装在类的内
。对外除了提供的public 方法,不对外泄露任何信息
4) 迪米特法则还有个更简单的定义:只与直接的朋友通信
5) **直接的朋友:每个对象都会与其他对象有耦合关系,只要两个对象之间有耦合关系
我们就说这两个对象之间是朋友关系。
耦合的方式很多,依赖,关联,组合,聚合
。其中,我们称出现成员变量,方法参数,方法返回值中的类为直接的朋友
出现在局部变量中的类不是直接的朋友。也就是说,陌生的类最好不要以局部变量
的形式出现在类的内部。**

1.错误示范

对于SchoolManager学校管理类
分析:
直接朋友:Employee ,CollegeManager
陌生朋友:CollegeEmployee,不是直接朋友,局部变量的方式出SchoolManager,是陌生类,违反迪米特法则

  1. package com.kris.designmode.principle.demeter;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. public class Demeter1 {
  5. public static void main(String[] args) {
  6. //创建一个SchoolManager对象
  7. SchoolManager schoolManager = new SchoolManager();
  8. schoolManager.printAllEmployee(new CollegeManager());
  9. }
  10. }
  11. /**
  12. * 总部员工
  13. */
  14. class Employee{
  15. private String id;
  16. public String getId() {
  17. return id;
  18. }
  19. public void setId(String id) {
  20. this.id = id;
  21. }
  22. }
  23. class CollegeEmployee{
  24. private String id;
  25. public String getId() {
  26. return id;
  27. }
  28. public void setId(String id) {
  29. this.id = id;
  30. }
  31. }
  32. /**
  33. * 学院管理类
  34. */
  35. class CollegeManager{
  36. //返回学院所有员工
  37. public List<CollegeEmployee> getAllEmployee(){
  38. List<CollegeEmployee> list = new ArrayList<CollegeEmployee>();
  39. for (int i=0;i<10;i++){
  40. CollegeEmployee employee = new CollegeEmployee();
  41. employee.setId("学院员工id="+i);
  42. list.add(employee);
  43. }
  44. return list;
  45. }
  46. }
  47. /**
  48. * SchoolManager学校管理类
  49. * 分析:
  50. * 直接朋友:Employee ,CollegeManager
  51. * 陌生朋友:CollegeEmployee,不是直接朋友,局部变量的方式出SchoolManager,是陌生类,违反迪米特法则
  52. */
  53. class SchoolManager{
  54. /**
  55. * 返回学校总部所有员工
  56. * @return
  57. */
  58. public List<Employee> getAllEmployee(){
  59. List<Employee> list = new ArrayList<Employee>();
  60. for (int i=0;i<10;i++){
  61. Employee employee = new Employee();
  62. employee.setId("学校总部员工id="+i);
  63. list.add(employee);
  64. }
  65. return list;
  66. }
  67. /**
  68. * 打印学院和学校所有的员工id
  69. * @param collegeManager
  70. */
  71. void printAllEmployee(CollegeManager collegeManager){
  72. List<CollegeEmployee> allCollegeEmployee = collegeManager.getAllEmployee();
  73. System.out.println("---------学院员工-----------");
  74. for (CollegeEmployee employee : allCollegeEmployee) {
  75. System.out.println(employee.getId());
  76. }
  77. System.out.println("---------学校员工-----------");
  78. List<Employee> allSchoolEmployee = this.getAllEmployee();
  79. for (Employee employee : allSchoolEmployee) {
  80. System.out.println(employee.getId());
  81. }
  82. }
  83. }

2.正确示范

应用实例改进
1) 前面设计的问题在于SchoolManager中,CollegeEmployee类并不是
SchoolManager类的直接朋友 (分析)
2) 按照迪米特法则,应该避免类中出现这样非直接朋友关系的耦合
3) 对代码按照迪米特法则 进行改进,将本来的打印学院员工的部分,放到CollegeManager类中实现

  1. package com.kris.designmode.principle.demeter.improve;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. public class Demeter1 {
  5. public static void main(String[] args) {
  6. //创建一个SchoolManager对象
  7. SchoolManager schoolManager = new SchoolManager();
  8. schoolManager.printAllEmployee(new CollegeManager());
  9. }
  10. }
  11. /**
  12. * 总部员工
  13. */
  14. class Employee{
  15. private String id;
  16. public String getId() {
  17. return id;
  18. }
  19. public void setId(String id) {
  20. this.id = id;
  21. }
  22. }
  23. class CollegeEmployee{
  24. private String id;
  25. public String getId() {
  26. return id;
  27. }
  28. public void setId(String id) {
  29. this.id = id;
  30. }
  31. }
  32. /**
  33. * 学院管理类
  34. */
  35. class CollegeManager{
  36. //返回学院所有员工
  37. public List<CollegeEmployee> getAllEmployee(){
  38. List<CollegeEmployee> list = new ArrayList<CollegeEmployee>();
  39. for (int i=0;i<10;i++){
  40. CollegeEmployee employee = new CollegeEmployee();
  41. employee.setId("学院员工id="+i);
  42. list.add(employee);
  43. }
  44. return list;
  45. }
  46. /**
  47. * 打印学院的员工id
  48. */
  49. void printAllEmployee(){
  50. List<CollegeEmployee> allCollegeEmployee = getAllEmployee();
  51. System.out.println("---------学院员工-----------");
  52. for (CollegeEmployee employee : allCollegeEmployee) {
  53. System.out.println(employee.getId());
  54. }
  55. }
  56. }
  57. /**
  58. * 学校管理类
  59. * 分析:
  60. * 直接朋友:Employee ,CollegeManager
  61. * 陌生朋友:CollegeEmployee,不是直接朋友,局部变量的方式出SchoolManager,是陌生类,违反迪米特法则
  62. */
  63. class SchoolManager{
  64. /**
  65. * 返回学校总部所有员工
  66. * @return
  67. */
  68. public List<Employee> getAllEmployee(){
  69. List<Employee> list = new ArrayList<Employee>();
  70. for (int i=0;i<10;i++){
  71. Employee employee = new Employee();
  72. employee.setId("学校总部员工id="+i);
  73. list.add(employee);
  74. }
  75. return list;
  76. }
  77. /**
  78. * 学校所有的员工id
  79. * @param collegeManager
  80. */
  81. void printAllEmployee(CollegeManager collegeManager){
  82. //将本来的打印学院员工的部分,放到CollegeManager类中实现
  83. collegeManager.printAllEmployee();
  84. System.out.println("---------学校员工-----------");
  85. List<Employee> allSchoolEmployee = this.getAllEmployee();
  86. for (Employee employee : allSchoolEmployee) {
  87. System.out.println(employee.getId());
  88. }
  89. }
  90. }

3.迪米特法则注意事项和细节

1) 迪米特法则的核心是降低类之间的耦合
2) 但是注意:由于每个类都减少了不必要的依赖,因此迪米特法则只是要求降低
类间(对象间)耦合关系, 并不是要求完全没有依赖关系