迪米特法则

引言: 

   自从我们接触编程开始,就知道了软件编程的总的原则:低耦合,高内聚。无论是面向过程编程还是面向对象编程,只有使各个模块之间的耦合尽量的低,才能提高代码的复用率。怎么样编程才能做到低耦合呢?那正是迪米特法则要去完成的。

问题由来:

    类与类之间的关系越密切,耦合度越大,当一个类发生改变时,对另一个类的影响也越大。

解决方案:

    尽量降低类与类之间的耦合。

定义:

    如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用。如果其中一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个调用。

例子:

    有一个集团公司,下属单位有分公司和直属部门,现在要求打印出所有下属单位的员工ID。

    先来看一下违反迪米特法则的设计:

//总公司员工
class Employee
{
	private String id;
	public void setId(String id)
       {
		this.id = id;
	}
	public String getId()
       {
		return id;
	}
}

//分公司员工
class SubEmployee
{
	private String id;
	public void setId(String id)
        {
		this.id = id;
	}
	public String getId()
       {
		return id;
	}
}

class SubCompanyManager
{
	public List<SubEmployee> getAllEmployee()
    {
		List<SubEmployee> list = new ArrayList<SubEmployee>();
		for(int i=0; i<100; i++)
                   {
			SubEmployee emp = new SubEmployee();
			//为分公司人员按顺序分配一个ID
			emp.setId("分公司"+i);
			list.add(emp);
		    }
		return list;
	}
}

class CompanyManager
{

	public List<Employee> getAllEmployee()
      {
		List<Employee> list = new ArrayList<Employee>();
		for(int i=0; i<30; i++)
                {
			Employee emp = new Employee();
			//为总公司人员按顺序分配一个ID
			emp.setId("总公司"+i);
			list.add(emp);
		}
		return list;
	}
	
	public void printAllEmployee(SubCompanyManager sub)
          {
		List<SubEmployee> list1 = sub.getAllEmployee();
		for(SubEmployee e:list1)
               {
			System.out.println(e.getId());
		}

		List<Employee> list2 = this.getAllEmployee();
		for(Employee e:list2)
                {
			System.out.println(e.getId());
		}
	}
}

public class Client
{
	public static void main(String[] args)
       {
		CompanyManager e = new CompanyManager();
		e.printAllEmployee(new SubCompanyManager());
	}
} 
    现在这个设计的主要问题出在CompanyManager中,根据迪米特法则,只与直接的朋友发生通信,而SubEmployee类并不是CompanyManager类的直接朋友(以局部变量出现的耦合不属于直接朋友),从逻辑上讲总公司只与他的分公司耦合就行了,与分公司的员工并没有任何联系,这样设计显然是增加了不必要的耦合。按照迪米特法则,应该避免类中出现这样非直接朋友关系的耦合。修改后的代码如下:

class SubCompanyManager
{
	public List<SubEmployee> getAllEmployee()
        {
		List<SubEmployee> list = new ArrayList<SubEmployee>();
		for(int i=0; i<100; i++)
                 {
			SubEmployee emp = new SubEmployee();
			//为分公司人员按顺序分配一个ID
			emp.setId("分公司"+i);
			list.add(emp);
		}
		return list;
	}
	public void printEmployee()
       {
		List<SubEmployee> list = this.getAllEmployee();
		for(SubEmployee e:list)
               {
			System.out.println(e.getId());
		}
	}
}

class CompanyManager
{
	public List<Employee> getAllEmployee()
        {
		List<Employee> list = new ArrayList<Employee>();
		for(int i=0; i<30; i++)
              {
			Employee emp = new Employee();
			//为总公司人员按顺序分配一个ID
			emp.setId("总公司"+i);
			list.add(emp);
		}
		return list;
	}
	
	public void printAllEmployee(SubCompanyManager sub)
        {
		sub.printEmployee();
		List<Employee> list2 = this.getAllEmployee();
		for(Employee e:list2)
               {
			System.out.println(e.getId());
		}
	}
}

               修改后,为分公司增加了打印人员ID的方法,总公司直接调用来打印,从而避免了与分公司的员工发生耦合。



评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值