`
youyu4
  • 浏览: 435915 次
社区版块
存档分类
最新评论

设计原则--最少知识原则

 
阅读更多

定义:一个对象应该对其他对象保持最少的了解。

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

解决方案:尽量降低类与类之间的耦合。

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

         迪米特法则又叫最少知道原则,最早是在1987年由美国Northeastern University的Ian Holland提出。通俗的来讲,就是一个类对自己依赖的类知道的越少越好。也就是说,对于被依赖的类来说,无论逻辑多么复杂,都尽量地的将逻辑封装在类的内部,对外除了提供的public方法,不对外泄漏任何信息。迪米特法则还有一个更简单的定义:只与直接的朋友通信。首先来解释一下什么是直接的朋友:每个对象都会与其他对象有耦合关系,只要两个对象之间有耦合关系,我们就说这两个对象之间是朋友关系。耦合的方式很多,依赖、关联、组合、聚合等。其中,我们称出现成员变量、方法参数、方法返回值中的类为直接的朋友,而出现在局部变量中的类则不是直接的朋友。也就是说,陌生的类最好不要作为局部变量的形式出现在类的内部。

         举一个例子:有一个集团公司,下属单位有分公司和直属部门,现在要求打印出所有下属单位的员工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的方法,总公司直接调用来打印,从而避免了与分公司的员工发生耦合。

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

 

分享到:
评论

相关推荐

    设计模式(十二)迪米特原则(最少知识原则).zip

    迪米特原则(Least Knowledge Principle,LKP),也被称为最少知识原则,是软件设计中的一个重要概念,属于面向对象设计的基本原则之一。这个原则的核心思想是降低类与类之间的耦合度,使得系统更加灵活,可维护性和...

    24种设计模式介绍与6大设计原则-PDF版 查阅方便

    6. 迪米特法则(最少知识原则):一个对象应该对其他对象有最少的了解,减少对象间的交互。 二、24种设计模式 1. 创建型模式:单例模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式,它们主要解决对象创建...

    JAVA设计模式-原则和23种设计模式归纳总结

    本资源首先介绍了设计模式的六大原则,包括单一责任原则、开闭原则、里氏替换原则、接口隔离原则、合成复用原则和最少知道原则。然后,资源对23种设计模式进行了分类和总结,包括创建型模式、结构型模式和行为型模式...

    C++设计原则 完整整理 快速理解设计原则

    - 也称为最少知识原则,它要求一个对象应当尽量少地了解其依赖对象的内部细节。一个对象只应该与其直接的朋友通信,避免深层的耦合。遵循这个原则可以减少类之间的交互复杂性,提高系统的可维护性。 7. **合成/...

    软件开发设计原则

    这些原则包括单一职责原则、开放封闭原则、里氏替换原则、最少知识原则、接口隔离原则和依赖倒置原则等。 1. 单一职责原则(Single Responsibility Principle - SRP) 单一职责原则是指一个类应该只有一个原因去...

    一些软件设计的原则一些软件设计的原则

    迪米特法则提倡每个对象应该对其他对象有最少的了解,也称为最少知识原则。这意味着对象只应与其直接的朋友交互,而不应了解过多的外部细节。遵循这一原则可以降低模块间的耦合,提高系统的可维护性。 以上原则...

    产品造型设计基础-基本原则.ppt

    蛋的一头大一头小便于生产,形状防止直线滚动,蛋壳的厚度和构造既保护了内部,又易于幼雏破壳,且用料最少实现最大空间,形态和线条和谐美观,这些都是设计原则的生动体现。 此外,科技原则也对产品造型设计有着...

    JAVA 24种设计模式介绍与6大设计原则.pdf

    5. 迪米特法则(Law of Demeter, LoD)或最少知识原则:一个对象应当对其他对象有尽可能少的了解。 6. 开闭原则(Open/Closed Principle, OCP):软件实体应当对扩展开放,对修改关闭。这意味着在不修改现有系统的...

    软件设计6原则

    简称DIP)、里氏替换原则(Liskov Substitution Principle,简称LSP)、最少知识原则(Least Knowledge Principle)以及迪米特法则(Law of Demeter,简称LoD)。下面将对这六个原则进行详细解读: 1. 单一责任原则...

    有关废物最少化专家系统的设计论文-.docx

    总结来说,废物最少化专家系统是结合了人工智能技术与环保理念的创新工具,它的设计与实施涉及到多学科的合作,遵循实用、系统、协同、用户导向、知识分离和统一表示等原则,旨在为企业提供高效、环保的废物处理策略...

    设计模式与设计原则.pdf

    5. 迪米特法则(Law of Demeter, LoD):也称作最少知识原则,它要求一个对象对其他对象有最少的了解。也就是说,一个对象应当尽可能少地与其他对象发生相互作用。 6. 开闭原则(Open/Closed Principle, OCP):...

    面向对象设计的基本原则

    - 也称为最少知识原则,它建议一个对象应该尽量少地了解其他对象的内部细节。每个对象都应尽量减少与外部对象的交互,只与直接的朋友通信。这有助于降低系统的复杂性,增强模块的独立性。 在实际编程中,设计模式...

    软件设计的七大原则(OOD)

    其中包括SRP(单一职责原则)、OCP(开闭原则)、LSP(里氏替换原则)、ISP(接口分离原则)、DIP(依赖倒置原则)、CRP(组合/聚合复用原则)和PLK(最小知识原则)。 一、SRP(Single Responsibility Principle)...

    设计模式六大原则详解 经典

    迪米特法则(Law of Demeter,LoD),又称最少知识原则,提倡一个对象应该尽量少地了解其他对象的内部细节。遵循这一原则可以减少类之间的交互,降低系统的复杂性,使得修改和扩展变得更容易。 这六大原则共同构成...

    设计模式(23种)与设计原则(6种)

    6. **最少知识原则**(Principle of Least Knowledge, PLK,又称迪米特法则):一个对象应该对其他对象尽可能少地了解。它鼓励松耦合,使得每个对象只处理自己职责范围内的事情。 接下来,我们简要介绍23种设计模式...

    设计模式和原则(很实用)

    5. **迪米特法则**:也称为最少知道原则,一个对象应该对其他对象有最少的了解,减少对象间的交互,降低耦合。 6. **合成/聚合复用原则**:优先使用对象组合或聚合,而不是继承,因为继承会带来较高的耦合度。 ...

    设计模式六大原则

    设计模式六大原则(5):迪米特法则(最少知识原则) 定义:一个对象应该对其他对象有最少的了解,只和直接的朋友通信。 问题由来:过度耦合导致系统复杂度增加,维护困难。 解决方案:限制对象之间的交互,尽量减少...

    android框架设计模式和设计原则

    6. **迪米特法则(LSP)**:也称最少知识原则,一个对象应当对其他对象有尽可能少的了解,降低类之间的耦合。 7. ** SOLID原则**:这五个原则的总称,是面向对象设计的基本原则。 在Android框架中,比如Android ...

Global site tag (gtag.js) - Google Analytics