第一表述:一个对象应该对其他对象保持最少了解, 通俗的讲就是一个类对自己依赖的类知道的越少越好,也就是对于被依赖的类,向外公开的方法应该尽可能的少
第二表述:如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用。如果其中的一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个调用
对象之间的耦合降到最小,符合高内聚低耦合的特性
需求V1(第一表述):当我们按下计算机的关机按钮的时候,计算机会执行一些列的动作会被执行:比如保存当前未完成的任务,然后是关闭相关的服务,接着是关闭显示器,最后是关闭电源,这一系列的操作以此完成后,计算机才会正式被关闭
class Computer{
func saveData() {
}
func closeService() {
}
func closeScreen() {
}
func closePower() {
}
func close() {
self.saveData()
self.closeService()
self.closeScreen()
self.closePower()
}
}
class Person{
func closeComputer() {
let c = Computer()
c.saveData()
c.closeService()
c.closeScreen()
c.closePower()
//或是
c.saveData()
c.close()
//....
}
}
可以看到closeComputer()方法中,我们发现这个方法无法编写:c是一个完全暴露的对象,其方法是完全公开的,那么对于Person来说,当他想要执行关闭的时候,却发现不知道该怎么操作:该调用什么方法?靠运气猜么?如果Person的对象是个不按常理出牌的,那这个Computer的对象岂不是要被搞坏么?
遵循迪米特法则,只应该暴露应该暴露的方法
class Computer{
private func saveData() {
}
private func closeService() {
}
private func closeScreen() {
}
private func closePower() {
}
func close() {
self.saveData()
self.closeService()
self.closeScreen()
self.closePower()
}
}
class Person{
func closeComputer() {
let c = Computer()
c.close()
}
}
需求V2(第二表述):计算机包括操作系统和相关硬件,我们可以将其划分为System对象和Container对象。当我们关闭计算机的时候,本质上是向操作系统发出了关机指令,而实则我们只是按了一下关机按钮,也就是我们并没有依赖System的对象,而是依赖了Container。这里Container就是我们上面所说的直接朋友---只和直接朋友通信
protocol SystemProtocol{
func close()
}
class System : SystemProtocol{
private func saveData() {
}
private func closeService() {
}
private func closeScreen() {
}
private func closePower() {
}
func close() {
self.saveData()
self.closeService()
self.closeScreen()
self.closePower()
}
}
class Container{
func sendCloseCommand() {
let system = System()
system.close()
}
}
class People{
func closeComputer() {
let c = Container()
c.sendCloseCommand()
}
}
从上面看到,和依赖倒置原则相结合之后的设计,也是符合迪米特原则的:如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用。如果其中的一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个调用,这里的第三者就是接口SystemProtocol