美文网首页
依赖倒置原则

依赖倒置原则

作者: 木叶苍蓝 | 来源:发表于2023-02-26 11:40 被阅读0次

前言:
每个逻辑的实现都是由原子逻辑组成的,不可分割的原子逻辑称为低层模块,在 Python 中用抽象类来表示,由原子逻辑组装而成的就是高层模块,抽象类是不能被实例化的。细节就是实现类,通过继承抽象类而产生的类就是细节,是可以被直接实例化的。一言以蔽之,采用依赖倒置原则可以减少类间的耦合性,提高系统的稳定性,提高代码的可读性和可维护性。依赖倒置原则包含如下三层含义:
1、高层模块(由原子逻辑组装而成)不应该依赖低层模块(不可分割的原子逻辑),二者都应该依赖抽象
2、抽象(抽象类)不应该依赖细节(实现类)
3、细节应该依赖抽象

依赖倒置原则究竟倒置在哪里?

“倒置”指的是和一般面向对象的代码的设计思考方式完全相反。举个例子,假设现在有建设一个汽车城,首先会想到是这里会卖很多品牌的汽车。如奔驰,宝马,奥迪,沃尔沃等。汽车城是上层模块,汽车是下层模块。如图所示:


modb_20211009_35bbc080-2858-11ec-abb4-fa163eb4f6be.jpg

利用上图模块间依赖关系设计的代码,当每新增一个品牌的汽车(低层模块),汽车城(高层模块)就多了一个新的依赖;汽车城(高层模块)依赖所有品牌的汽车(低层模块),因为它直接创建汽车;对于不同品牌的汽车(低层模块)具体实现的任何改变都会影响到汽车城(高层模块),这就违背了依赖倒置原则。根据依赖倒置原则,高层模块不应该依赖低层模块,两者都应该依赖抽象。也就是说汽车城这个高层模块是不应该依赖汽车品牌这个低层模块,所以代码设计思路应该从下层模块开始思考并对其进行抽象。如下图所示:


modb_20211009_35f5287a-2858-11ec-abb4-fa163eb4f6be.jpg

这样就很好的解释了 “上层模块不应该依赖底层模块,它们都应该依赖于抽象”这一概念,在最开始的设计中,高层模块(汽车城)直接依赖低层模块(不同品牌的车),调整设计后高层模块和低层模块都依赖于抽象(小汽车)。

依赖倒置原则应用

先不考虑依赖倒置原则,假设有如下类图所描绘的场景


modb_20211009_36267114-2858-11ec-abb4-fa163eb4f6be.jpg

由以上类图所描绘的场景可知,司机类和奔驰类都属于细节,并没有实现或继承抽象。它们是对象级别的耦合。通过类图可知司机类 Driver 有一个用来开车的 drive() 方法,Benz 类有一个表示车辆运行的 run() 方法,并且奔驰车类 Benz 依赖于司机类 Driver,用户模块 Client 是一个高层模块,负责调用司机类 Driver 和奔驰类 Benz。未采用依赖倒置原则的代码如下:

class Driver:
    def __init__(self, name):
        self.name = name

    def drive(self, benz):
        print("%s is driving a benz" % self.name)
        benz.run()

class Benz:
    def __init__(self, name = 'benz'):
        self.name = name

    def run(self):
        print("%s is running ..." % self.name)

class BMW:
    def __init__(self, name="bmw"):
        self.name = name

    def run(self):
        print("%s is running..." % self.name)

if __name__ == "__main__":
    d = Driver("张三")
    benz = Benz()
    d.drive(benz)
    bmw = BMW()
    d.drive(bmw)

这是最不灵活的写法,如果驾驶员的车库中新增了一辆 bmw,新车无法上路。继续修改代码如下:

class Driver:
    def __init__(self, name):
        self.name = name

    def drive(self, car):
        print("%s is driving a %s" % (self.name, car.name))
        car.run()

class Benz:
    def __init__(self, name="benz"):
        self.name = name
    
    def run(self):
        print("%s is running ..." %self.name)

class BMW:
    def __init__(self, name="bmw"):
        self.name = name

    def bmw_run(self):
        print("%s is running ..." % self.name)

if __name__ == "__main__":
    d = Driver("张三")
    benz = Benz()
    d.drive(benz)
    print("#" * 20)
    bmw = BMW()
    d.drive(bmw)

以上代码中,如果 benz 或 bmw 的运行方法不是 run,那么将会报错。此时需要将 Car 类的run方法进行抽象,来对子类进行约束。上面代码的设计没有使用依赖倒置原则,我们已经郁闷的发现,模块与模块之间耦合度太高,生产力太低,只有需求一变就会面临代码的大面积重构。现在引入依赖倒置原则,重新设计的类图如下:


modb_20211009_372f38ca-2858-11ec-abb4-fa163eb4f6be.jpg
from abr import ABCMeta, abstractmethod

class Driver:
    __metaclass__ = ABCMeta

    def __init__(self, name):
        self.name = name

    @abstarctmethod
    def drive(self, car):
        pass

class Car:
    __metaclass__ = ABCMeta
    def __init__(self, name):
        self.name = name

    @abstractmethod
    def run(self):
        pass

class BenzCar(Car):
    def run(self):
        print("%s is running ..." % self.name)

class BmwzCar(Car):
    def run(self):
        print("%s is running ..." % self.name)

class CarDrive(Driver):
    def drive(self, car):
        print("%s is driving a car ..." % self.name)
        car.run()

if __name__ == "__main__":
    rs = CarDrive("张三")
    bz = BenzCar("奔驰")
    bm = BmwCar("宝马")

    rs.drive(bz)
    rs.drive(bm)

相关文章

  • 依赖倒置原则

    依赖倒置原则 “依赖倒置原则(Dependence Inversion Principle,DIP)” 定义: 高...

  • 依赖倒置/好莱坞原则/控制反转

    # 请描述什么是依赖倒置原则,为什么有时候依赖倒置原则又被称为好莱坞原则? 依赖倒置原则: - 高层模块不应该依赖...

  • 第二周

    请描述什么是依赖倒置原则,为什么有时候依赖倒置原则又被称为好莱坞原则? 依赖倒置原则 Dependency Inv...

  • 依赖倒置原则(DIP)

    依赖倒置原则定义 依赖倒置原则(Dependence Inversion Principle ,DIP)定义如下:...

  • 依赖倒置原则

    个人博客原文:依赖倒置原则 设计模式六大原则之三:依赖倒置原则。 简介 姓名 :依赖倒置原则 英文名 :Depen...

  • 架构师训练营第2周命题作业

    一.请描述什么是依赖倒置原则,为什么有时候依赖倒置原则又被称为好莱坞原则? 1.依赖倒置原则描述: 1.1. 高...

  • 框架设计[week 2]

    作业一: 1.请描述什么是依赖倒置原则,为什么有时候依赖倒置原则又被称为好莱坞原则? 依赖倒置原则: 高层模块不应...

  • 架构师训练营第二周作业

    1. 请描述什么是依赖倒置原则,为什么有时候依赖倒置原则又被称为好莱坞原则? 答:依赖倒置原则,英文缩写DIP,全...

  • 架构师训练营第2周作业 面向对象设计原则

    请描述什么是依赖倒置原则,为什么有时候依赖倒置原则又被称为好莱坞原则? 依赖倒置原则的标准描述如下: 高层模块不应...

  • 六大设计原则-依赖倒置原则

    依赖倒置原则 Dependency Inversion Principle 简称DIP。 什么是依赖倒置原则 1....

网友评论

      本文标题:依赖倒置原则

      本文链接:https://www.haomeiwen.com/subject/tdazkdtx.html