Joh*_*ith 0 php law-of-demeter
我知道它被认为是坏的:
$this->laptop->getKeyboard()->getTouchpad()->getLbutton();
Run Code Online (Sandbox Code Playgroud)
要么
$this->laptop->getKeyboard()->getCapslock()->isLedOn();
Run Code Online (Sandbox Code Playgroud)
它被解释为"我们不想要大量的 - > - > - > - >" - 但我想让这种结构变得有形,我的意思是它不能脱钩.我理解,如果架构师改变了,它必须在任何地方完成,但它不会发生.再说一次,如何解决这个问题?
Demeter法是关于依赖性而不是 - >(或其他语言中的点).
例如,如果您有一个流畅的界面(方法返回此),该法律不适用.
您希望您的课程依赖于最少数量的其他课程.
如果你的班级依赖于其他10个班级,那么任何一个班级的改变都可以打破它.理解你班级的作用更难.测试这样的课程也很难.
如果你有$field->getDependency1()->getDependency2()或者没关系$field->dependency1->dependency2- 你的代码仍然依赖于其他两个类并且知道dependency1的内部结构(它内部有dependency2).
您可以通过告诉不要求原则来解决您的问题.在OOD中,您不希望使用仅包含数据的结构.您希望拥有知道如何处理其字段的对象.
例如,你可以重构:
$oldBalance = $bank->getAccount()->getBalance();
$bank->getAccount()->setBalance($oldBalance - $amount);
Run Code Online (Sandbox Code Playgroud)
至:
$bank->withdraw($amount);
Run Code Online (Sandbox Code Playgroud)
在银行类:
function withdraw($amount) {
$this->account->withdraw($amount);
}
Run Code Online (Sandbox Code Playgroud)
在Account类中:
function withdraw($amount) {
$this->balance = $this->balance - $amount;
}
Run Code Online (Sandbox Code Playgroud)
你有更多的方法,但现在使用$ bank的代码,对账户及其余额一无所知.您可以轻松地测试该类仅模拟$ bank字段.您还有更多可重用的代码.
想象一下这个对话:
You: Hey Laptop, get me the I/O devices
Laptop: There you go
You: Hey IODevices, get me the keyboard
IODevices: There you go
You: Hey Keyboard, get me the touchpad
Keyboard: There you go
You: Hey Touchpad, I want to press your left button
Touchpad: Consider it done Boss!
Run Code Online (Sandbox Code Playgroud)
男人,你是怪物电子迷,或者你是为了生活 - 你知道你的笔记本电脑的每一小块!;)
与此:
You: Hey Laptop, I want to press left button on the touchpad
// Laptop gets the job done
Laptop: Done Boss!
Run Code Online (Sandbox Code Playgroud)
在第二次谈话中,引擎盖下,
Laptop调用它的依赖IODevices(你不需要知道任何关于它的东西),IODevices调用它的依赖Keyboard(Latop不需要知道它),Keyboard得到它的依赖Touchpad(IODevices不需要知道它 - 实际上这是一个不好的例子,但是......你明白了)然后调用pressLeftButton()它.也就是说,你不关心细节,你想要做的就是pressLeftButton.您不需要知道如何Keyboard和Touchpad相关,从每个方法等返回什么.您有必须实现的公共接口.
这使得每个人都高兴,因为当你更换什么可以打破KeyboardXyz与KeyboardAbc,只要后者实现了相同的接口.