https://en.wikipedia.org/wiki/Law_of_Demeter
The Law of Demeter (LoD) or principle of least knowledge is a specific case of loose coupling.
One mistake many Java programmer makes it exposing internal detail of object using getter methods and this is where principle of least knowledge alerts you.
In short, the Law of Demeter aims to keep you from doing things like this:
objectA.getObjectB().getObjectC().doSomething(); ===> contrvsery
When you write code like this, not only are you exposing yourself to changes in the ObjectA class, you're also exposing yourself to changes that may occur in ObjectB and ObjectC as well.
Forces
The Law of Demeter (LoD) or principle of least knowledge is a specific case of loose coupling.
- Each unit should have only limited knowledge about other units: only units "closely" related to the current unit.
- Each unit should only talk to its friends; don't talk to strangers.
- Only talk to your immediate friends.
The fundamental notion is that a given object should assume as little as possible about the structure or properties of anything else (including its subcomponents), in accordance with the principle of "information hiding".
a module should not know about the inner details of the objects it manipulates. If a code depends upon internal details of a particular object, there is good chance that it will break as soon as internal of that object changes. One mistake many Java programmer makes it exposing internal detail of object using getter methods and this is where principle of least knowledge alerts you.
In short, the Law of Demeter aims to keep you from doing things like this:
objectA.getObjectB().getObjectC().doSomething(); ===> contrvsery
When you write code like this, not only are you exposing yourself to changes in the ObjectA class, you're also exposing yourself to changes that may occur in ObjectB and ObjectC as well.
Forces
- Your classes will be "loosely coupled"; your dependencies are reduced.
- Reusing your classes will be easier.
- Your classes are less subject to changes in other classes.
- Your code will be easier to test.
- Classes designed this way have been proven to have fewer errors.
Exception 1: Data Structures
Exception 2: The Builder Pattern and Other Fluent APIs
When an API is designed to be fluent (and therefore, usually chained), there’s no good reason to lose the readability just to be a strict Law of Demeter follower. For example, java 8’s Stream API would be worthless if you didn’t allow yourself to chain methods.
http://www.dan-manges.com/blog/37
Models should define business logic and be able to stand alone from views.
http://c2.com/cgi/wiki?LawOfDemeter
Practice
https://medium.com/@orhanobut/yet-again-law-of-demeter-4a7e8fa7707d
private void showAvatar(){
Image image = user.getAccount().getImage();
}
==>
http://blog.csdn.net/vking_wang/article/details/8455636
Exception 2: The Builder Pattern and Other Fluent APIs
When an API is designed to be fluent (and therefore, usually chained), there’s no good reason to lose the readability just to be a strict Law of Demeter follower. For example, java 8’s Stream API would be worthless if you didn’t allow yourself to chain methods.
http://www.dan-manges.com/blog/37
Models should define business logic and be able to stand alone from views.
http://c2.com/cgi/wiki?LawOfDemeter
Practice
https://medium.com/@orhanobut/yet-again-law-of-demeter-4a7e8fa7707d
private void showAvatar(){
Image image = user.getAccount().getImage();
}
==>
| ||
public Image getAvatar(){ | ||
if (account == null) { | ||
return; | ||
} | ||
account.getImage(); | ||
} | ||
} | ||
public class Foobar { | ||
public void showAvatar() { | ||
Image image = user.getAvatar(); | ||
} | ||
} |
又称最少知识原则(Least Knowledge Principle),一个对象应该对其他对象有最少的了解
一个类对自己依赖的类知道的越少越好。也就是说,对于被依赖的类来说,无论逻辑多么复杂,都尽量地的将逻辑封装在类的内部,对外除了提供的public方法,不对外泄漏任何信息。
类与类之间的关系越密切,耦合度越大,当一个类发生改变时,对另一个类的影响也越大。
迪米特法则包含4层含义:
1)只和朋友交流
Only talk to your immediate friends.两个对象之间的耦合就成为朋友关系。即,出现在成员变量、方法输入输出参数中的类就是朋友;局部变量不属于朋友。
--> 不与无关的对象发生耦合!
方针:不要调用从另一个方法中返回的对象中的方法!只应该调用以下方法:
- 该对象本身的方法
- 该对象中的任何组件的方法
- 方法参数中传入的对象的方法
- 方法内部实例化的对象的方法
例如:Teacher类可以命令TeamLeader对Students进行清点,则Teacher无需和Students耦合,只需和TeamLeader耦合即可。
反例:
public float getTemp(){ Thermometer t = station.getThermometer(); return t.getTemp(); }客户端不应该了解气象站类中的温度计对象;应在气象站类中直接加入获取温度的方法。改为:
public float getTemp(){ return station.getTemp(); }
2)朋友间也应该有距离
即使是朋友类之间也不能无话不说,无所不知。
--> 一个类公开的public属性或方法应该尽可能少!
3)是自己的就是自己的
如果一个方法放在本类中也可以、放在其他类中也可以,怎么办?
--> 如果一个方法放在本类中,既不增加类间关系,也对本类不产生负面影响,就放置在本类中。
4)谨慎使用Serializable
否则,若后来修改了属性,序列化时会抛异常NotSerializableException。
建议:
迪米特法则的核心观念是:类间解耦。
其结果是产生了大量中转或跳转类。