迪米特法则(Demeter)

定义

  一个软件实体尽量少的与其他实体发生相互作用。

原则

  不要和“陌生人”说话、只与你的直接朋友通信。

  其中直接朋友包含以下几类:

      (1) 当前对象本身(this);

      (2) 以参数形式传入到当前对象方法中的对象;

      (3) 当前对象的成员对象;

      (4) 如果当前对象的成员对象是一个集合,那么集合中的元素也都是朋友;

      (5) 当前对象所创建的对象。

  应该尽量减少对象之间的交互,如果两个对象之间不必彼此直接通信,那么这两个对象就不应当发生任何直接的相互作用,如果其中的一个对象需要调用另一个对象的某一个方法的话,可以通过第三者转发这个调用。简言之,就是通过引入一个合理的第三者来降低现有对象之间的耦合度

例子

  在体育场上,老师命令队长把全队的女生人数数出来。

  女生类

package com.csdhsm.pattemdesign.demeter;

/**  
 * @Title:  Girl.java   
 * @Description: 女生类
 * @author: Han   
 * @date:   2016年6月22日 下午7:55:48  
 */  
public class Girl {

}

  队长类

package com.csdhsm.pattemdesign.demeter;

import java.util.List;

/**  
 * @Title:  GroupLeader.java   
 * @Description: 队长类
 * @author: Han   
 * @date:   2016年6月22日 下午7:52:42  
 */  
public class GroupLeader {
    
    //数女生个数
    public void countGirls(List<Girl> listGirls) {
        System.out.println(listGirls.size());
    }
}

  教师类package com.csdhsm.pattemdesign.demeterimport java.util.ArrayList;

import java.util.List;

/**  
 * @Title:  Teacher.java   
 * @Description: 教师类
 * @author: Han   
 * @date:   2016年6月22日 下午7:54:37  
 */  
public class Teacher {
    
    //命令队长数女生的个数
    public void commond(GroupLeader leader) {
        
     List
<Girl> listGirls = new ArrayList<>(); for(int i = 0; i < 20; i++) { listGirls.add(new Girl()); } leader.countGirls(listGirls); } }

  客户端

package com.csdhsm.pattemdesign.demeter;

public class Solution {
    
    public static void main(String[] args) {
        
        Teacher teacher = new Teacher();
        GroupLeader leader = new GroupLeader();
        
        teacher.commond(leader);
    }
}

问题

  看起来没有什么问题,但是在教师应该是给队长下命令,队长和女生耦合,List<Girl> listGirls = new ArrayList<>();,直接与不是“朋友”的Girl相互关联,使得整个系统耦合度高,不易维护和扩展。

修改之后

  女生类和客户端类不变。

  队长类

package com.csdhsm.pattemdesign.demeter;

import java.util.ArrayList;
import java.util.List;

/**  
 * @Title:  GroupLeader.java   
 * @Description: 队长类
 * @author: Han   
 * @date:   2016年6月22日 下午7:52:42  
 */  
public class GroupLeader {
    
    List<Girl> listGirls = new ArrayList<>();
    
    //数女生个数
    public void countGirls() {

        for(int i = 0; i < 20; i++) {
            listGirls.add(new Girl());
        }
        System.out.println(listGirls.size());
    }
}

  教师类

package com.csdhsm.pattemdesign.demeter;

/**  
 * @Title:  Teacher.java   
 * @Description: 教师类
 * @author: Han   
 * @date:   2016年6月22日 下午7:54:37  
 */  
public class Teacher {
    
    //命令队长数女生的个数
    public void commond(GroupLeader leader) {
        
        leader.countGirls();
    }
}

  这样耦合度就大大降低了。

总结

  迪米特法则的初衷是降低类之间的耦合,由于每个类都减少了不必要的依赖,因此的确可以降低耦合关系。但是凡事都有度,虽然可以避免与非直接的类通信,但是要通信,必然会通过一个“中介”来发生联系,例如本例中,总公司就是通过队长这个“中介”来与女生联系的。过分的使用迪米特原则,会产生大量这样的中介和传递类,导致系统复杂度变大。所以在采用迪米特法则时要反复权衡,既做到结构清晰,又要高内聚低耦合。

 posted on 2016-06-22 20:10  韩思明  阅读(208)  评论(0编辑  收藏  举报