理念:
迪米特法则又称为最少知识原则,定义是一个软件实体应当尽可能少地与其他实体发生相互作用;
迪米特法则可降低系统的耦合度,使类与类之间保持松散的耦合关系;
迪米特法则还有一种定义:不要和“陌生人”说话,只与你的直接朋友通信;
其中对象的直接朋友定义如下:
- 当前对象本身,即this;
- 以参数形式传入到当前对象方法中的对象;
- 当前对象的成员对象;
- 如果当前对象的成员对象是一个集合,那么集合中的元素也都是朋友;
- 当前对象所创建的对象;
案例:
小明在工作中接到一个需求,要求查询出内部公司员工和公司的外包公司员工,并进行展示,于是他是这样设计的代码:
首先他先定义了内部员工类InnerEmployee
和外派员工类OuterEmployee
,如下:
/**
* 内部员工
*/
public class InnerEmployee implements Serializable {
private static final long serialVersionUID = 7851782470225501429L;
private String id;
private String name;
public InnerEmployee() {
}
public InnerEmployee(String id, String name) {
this.id = id;
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "InnerEmployee{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
'}';
}
}
/**
* 外派员工
*/
public class OuterEmployee implements Serializable {
private static final long serialVersionUID = -9026013823532683124L;
private String id;
private String name;
public OuterEmployee() {
}
public OuterEmployee(String id, String name) {
this.id = id;
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "OuterEmployee{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
'}';
}
}
然后定义了查询的Dao层的接口,如下:
/**
* 内部员工Dao
*/
public interface InnerEmployeeDao {
List<InnerEmployee> findInnerEmployee();
}
/**
* 外派员工Dao
*/
public interface OuterEmployeeDao {
List<OuterEmployee> findOuterEmployee();
}
最后定义了外派员工管理器OuterEmployeeManager
和员工管理器EmployeeManager
,如下:
/**
* 外派员工管理器
*/
public class OuterEmployeeManager {
private OuterEmployeeDao outerEmployeeDao;
public List<OuterEmployee> findOuterEmployee() {
return outerEmployeeDao.findOuterEmployee();
}
}
/**
* 员工管理器
*/
public class EmployeeManager {
private InnerEmployeeDao innerEmployeeDao;
public List<InnerEmployee> findInnerEmployee() {
return innerEmployeeDao.findInnerEmployee();
}
/**
* 展示员工
* @param outerEmployeeManager 外派员工管理器
*/
public void displayEmployee(OuterEmployeeManager outerEmployeeManager) {
List<InnerEmployee> innerEmployee = this.findInnerEmployee();
for (InnerEmployee employee : innerEmployee) {
System.out.println(employee);
}
List<OuterEmployee> outerEmployee = outerEmployeeManager.findOuterEmployee();
for (OuterEmployee employee : outerEmployee) {
System.out.println(employee);
}
}
}
从上面的案例来看,在员工管理器EmployeeManager
中的展示员工方法displayEmployee
中,OuterEmployee
以局部变量方式出现在该管理器中,并不是它的朋友,所有违背了迪米特法则;
同样是上面的案例,当懂得开闭原则的小红遇到时,会怎样来设计呢?接下来请看:
她会将外派员工管理器OuterEmployeeManager
做以下修改:
/**
* 外派员工管理器
*/
public class OuterEmployeeManager {
private OuterEmployeeDao outerEmployeeDao;
public List<OuterEmployee> findOuterEmployee() {
return outerEmployeeDao.findOuterEmployee();
}
/**
* 展示外派员工
*/
public void displayOuterEmployee() {
List<OuterEmployee> outerEmployee = this.findOuterEmployee();
for (OuterEmployee employee : outerEmployee) {
System.out.println(employee);
}
}
}
然后再修改EmployeeManager
,如下:
/**
* 员工管理器
*/
public class EmployeeManager {
private InnerEmployeeDao innerEmployeeDao;
public List<InnerEmployee> findInnerEmployee() {
return innerEmployeeDao.findInnerEmployee();
}
/**
* 展示员工
* @param outerEmployeeManager 外派员工管理器
*/
public void displayEmployee(OuterEmployeeManager outerEmployeeManager) {
List<InnerEmployee> innerEmployee = this.findInnerEmployee();
for (InnerEmployee employee : innerEmployee) {
System.out.println(employee);
}
outerEmployeeManager.displayOuterEmployee();
}
}
从上面小红的代码来看,在员工管理器中已然不存在了使用OuterEmployee
当局部变量的情况,所以遵循了迪米特法则;
相关链接: