1.原文
- 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. (只和自己直接的朋友交谈) (来自维基百科)
2.理解:
上面是我抄的原文和译文,感觉还可以.明确几个概念和理解
(1).这应该是一个窄接口替换宽接口的说法
<?php /* 这是一个比较宽的接口,有3个方法 */ interface Ia{ function a(); function b(); function c(); } /* 宽接口的具体实现类,实现了宽接口定义的功能, 注意这时候A的能力很多,client是用不了这么多的 */ class A implements Ia{ function a(){} function b(){} function c(){} } /* 定义一个窄接口,屏蔽掉Ia别的功能(知识),保证client了解的知识是有限的. 同时这也是一个closely的抽象,亲密的单元需要有a()功能 */ interface Ib{ function a(); function b(); } /* 实现Ib,目标是实现a方法,通过调用一个实现了Ia接口的具体实现类(面向接口编程) 为什么不拆分Ia呢?因为是还有别的调用类面向Ia编程,依赖Ia接口,拆分了Ia,别人怎么办 */ class B implements Ib{ protected $a; function __construct(Ia $a) { $this->a = $a; } function a(){ $this->a->a(); } function b(){ $this->a->b(); } //这个实现类还有别的能力(知识) function c(){} } /* 具体的调用类.逻辑上client是依赖一个实现了Ib接口的实现类的实例的.并且只了解这个实现类有一个a(),b()功能 */ class Client{ function doSomething(Ib $b){ //弄点儿事儿干... //执行一个依赖调用 $b ->a(); //再弄我自己的事儿 //如果有一个组合功能放在那儿? if(true){ $b ->a(); $b ->b(); }else{ $b ->b(); $b ->a(); } } }
(2)(3)陌生朋友,直接朋友(亲密朋友) ,其实是依赖关系是怎么诞生的.
传参(方法,构造函数),返回值约定类型这些都是直接朋友
下面这种就是陌生朋友
function test(){
$a = new A();
$a ->doSomething();
}
说白了就是不要定义局部的变量,来引用依赖.这种依赖关系耦合度很深,除了改代码没办法做修改
3.有一种防腐层的感觉,有一个亲近的朋友能解决我的所有问题.这个亲近朋友不是具体实现,而是一个代理或者说传话的.
那这个代理里面应该实现一些组合功能的逻辑么?
我认为看情况,根据这个组合逻辑是client要求的,还是Ib提供的协议.区别就是这个组合是由提供的.我建议固化在中间代理里面,再定义一个组合的约束
interface Ib { function a(); function d(); } /* 实现Ib,目标是实现a方法,通过调用一个实现了Ia接口的具体实现类(面向接口编程) */ class B implements Ib { protected $a; function __construct(Ia $a) { $this->a = $a; } function a() { $this->a->a(); } function d($param) { if ($param) { $this->a->a(); $this->a->b(); } esle{ $this->a->b(); $this->a->a(); } } //这个实现类还有别的能力(知识) function c() { } }
/* 具体的调用类.逻辑上client是依赖一个实现了Ib接口的实现类的实例的.并且只了解这个实现类有一个a()功能 */ class Client { function doSomething(Ib $b) { //弄点儿事儿干... //执行一个依赖调用 $b ->a(); //再弄我自己的事儿 //再调用这个组合能力 $b ->d(true); } }
4.抄了一段儿说法感觉更全一点儿
迪米特法则的实现方法
从迪米特法则的定义和特点可知,它强调以下两点:
从依赖者的角度来说,只依赖应该依赖的对象。
从被依赖者的角度说,只暴露应该暴露的方法。
所以,在运用迪米特法则时要注意以下 6 点。
在类的划分上,应该创建弱耦合的类。类与类之间的耦合越弱,就越有利于实现可复用的目标。
在类的结构设计上,尽量降低类成员的访问权限。
在类的设计上,优先考虑将一个类设置成不变类。
在对其他类的引用上,将引用其他对象的次数降到最低。
不暴露类的属性成员,而应该提供相应的访问器(set 和 get 方法)。
谨慎使用序列化(Serializable)功能。