设计模式 -- 迪米特法则

2023-11-22 09:20:26 浏览数 (2)

表述(降低耦合)

第一表述:一个对象应该对其他对象保持最少了解, 通俗的讲就是一个类对自己依赖的类知道的越少越好,也就是对于被依赖的类,向外公开的方法应该尽可能的少

第二表述:如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用。如果其中的一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个调用

优点

对象之间的耦合降到最小,符合高内聚低耦合的特性

示例

需求V1(第一表述):当我们按下计算机的关机按钮的时候,计算机会执行一些列的动作会被执行:比如保存当前未完成的任务,然后是关闭相关的服务,接着是关闭显示器,最后是关闭电源,这一系列的操作以此完成后,计算机才会正式被关闭

代码语言:javascript复制
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的对象岂不是要被搞坏么?

遵循迪米特法则,只应该暴露应该暴露的方法

代码语言:javascript复制
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就是我们上面所说的直接朋友---只和直接朋友通信

代码语言:javascript复制
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

0 人点赞