软件设计原则-依赖倒转原则

129 阅读3分钟

依赖倒转原则

高层模块不应该依赖低层模塄,两者都应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象。简单的说就是要求对抽象进行编程不要对实现进行编程,这样就降低了客户与实现模块间的耦合。

查看以下例子理解依赖以下依赖倒转原则

【例】组装电脑

现要组装一台电脑,需要配件 gpu,硬盘,内存条。只有这些配置都有了,计算机才能正常的运行。选择CRL有很多选择,如Inte1,AMD等,硬盘可以选择希捷,西数等,内存条可以选择金士顿,海盗船等。

//希捷硬盘
class XiJieHardDisk{
//    存储数据的方法
    func save(data:String){
        print("使用希捷硬盘存储数据为:",data)
    }
//    获取数据的方法
    func getData()->String{
        print("使用希捷硬盘取数据")
        return "数据"
    }
}
//英特尔CPU
class InterCpu{
    func run(){
        print("使用inter处理器")
    }
}
//金士顿内存条类
class KingstonMemory {
    func save(){
        print("使用金士顿内存条存储数据")
    }
}
//计算机类,将这些组件类组合起来,这些组件类没有办法单独提供功能
class Computer{
    
    var hardDisk:XiJieHardDisk
    var cpu:InterCpu
    var memory:KingstonMemory
    init(hardDisk:XiJieHardDisk,cpu:InterCpu,memory:KingstonMemory) {
        self.hardDisk = hardDisk
        self.cpu = cpu
        self.memory = memory
    }
    func run(){
        print("运行计算机")
//        hardDisk.save(data: "保存数据到硬盘")
        print("从硬盘上获取的数据", hardDisk.getData())
        cpu.run()
        memory.save()
    }
}
​

测试类

let hardDisk = XiJieHardDisk()
let memory = KingstonMemory()
let cpu = InterCpu()
​
//组装一台计算机
var computer:Computer = Computer(hardDisk: hardDisk, cpu: cpu , memory: memory)
//运行计算机
computer.run()
​

image-20220909231840540

上面代码可以看到已经组装了一台电腔,但是似乎组装的电脑的eRu只能是Inte 1的,内存条只能是金士顿的,硬盘只能是希捷的,这对用户肯定是不友好的,用户有了机箱肯定是想按照自己的喜好,选择自己喜欢的配件。

根据依赖倒转原则进行改进:

代码我们只需要修改computer类,让computer类依赖抽象(各个配件的接口),而不是依赖于各个组件具体的实现类。

更改后的代码:

/硬盘接口
protocol HardDisk{
    func save(data:String)
    func getData()->String
}
//希捷硬盘
class XiJieHardDisk:HardDisk{
//    存储数据的方法
    func save(data:String){
        print("使用希捷硬盘存储数据为:",data)
    }
//    获取数据的方法
    func getData()->String{
        print("使用希捷硬盘取数据")
        return "数据"
    }
}
​
​
//CPU接口
protocol CPU{
//    运行Cpu
    func run()
}
//英特尔CPU
class InterCpu:CPU{
    func run(){
        print("使用inter处理器")
    }
}
​
​
​
//硬盘接口
protocol Memory{
    func save()
}
//金士顿内存条类
class KingstonMemory:Memory {
    func save(){
        print("使用金士顿内存条存储数据")
    }
}
//计算机类,将这些组件类组合起来,这些组件类没有办法单独提供功能
class Computer{
    
    var hardDisk:HardDisk
    var cpu:CPU
    var memory:Memory
    init(hardDisk:XiJieHardDisk,cpu:InterCpu,memory:KingstonMemory) {
        self.hardDisk = hardDisk
        self.cpu = cpu
        self.memory = memory
    }
    func run(){
        print("运行计算机")
//        hardDisk.save(data: "保存数据到硬盘")
        print("从硬盘上获取的数据", hardDisk.getData())
        cpu.run()
        memory.save()
    }
}
​

测试代码:

let hardDisk = XiJieHardDisk()
let memory = KingstonMemory()
let cpu = InterCpu()
​
//组装一台计算机
var computer:Computer = Computer(hardDisk: hardDisk, cpu: cpu , memory: memory)
//运行计算机
computer.run()
​

image-20220909233214262

如果后期你想要换CPU的话,我们只需要创建一个AMD的CPU类实现CPU的接口,在测试代码中替换CPU品牌即可,同时也符合开闭原则。

感谢黑马程序员课程