python 设计模式(二) 六大设计原则三 依赖倒置原则(Dependence Inversion Principle)

依赖倒置原则

1 高层级的模块不应该依赖于低层次的模块,它应该依赖于低层次模块的抽象

2 抽象不应该依赖于具体,具体应该依赖于抽象

1 高层次的模块不应该依赖于低层次的模型,它应该依赖于低层次模块的抽象

什么叫高层次模型,通常所说的客户端就是高层次模型,而其调用的接口即是低层次的模型,这句话也可以说,客户端不应该依赖于接口的具体,而是依赖于接口的抽象。

依赖倒置原则的百度百科,举了一个很好的例子。在这里我就对这个例子进行Python实现。

现在有一款自动驾驶系统,它可以装在buick,ford两款车上使用。先上个未符合依赖倒置的例子。这个例子中,客户端即autosystem依赖于具体接口(buick,ford)。而不是依赖于抽象 car。

class Ford(object):
    def __init__(self):
        self.type = 'ford'

    def ford_run(self):
        print('%s is running' % self.type)

    def ford_turn(self):
        print('%s is turning' % self.type)

    def ford_stop(self):
        print('%s is stopping' % self.type)


class Buick(object):
    def __init__(self):
        self.type = 'buick'

    def buick_run(self):
        print('%s is running' % self.type)

    def buick_turn(self):
        print('%s is turning' % self.type)

    def buick_stop(self):
        print('%s is stopping' % self.type)


class AutoSystem(object):

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

    def car_run(self):
        if self.car.type == 'ford':
            self.car.ford_run()
        else:
            self.car.buick_run()
            
    def car_turn(self):
        if self.car.type == 'ford':
            self.car.ford_turn()
        else:
            self.car.buick_turn()

    def car_stop(self):
        if self.car.type == 'ford':
            self.car.ford_stop()
        else:
            self.car.buick_stop()


if __name__ == '__main__':
    ford = Ford()
    buick = Buick()
    autosystem = AutoSystem(ford)
    autosystem.car_run()
    autosystem.car_turn()
    autosystem.car_stop()
    autosystem.car = buick
    print('*'*100)
    autosystem.car_run()
    autosystem.car_turn()
    autosystem.car_stop()

结果如下

ford is running
ford is turning
ford is stopping
****************************************************************************************************
buick is running
buick is turning
buick is stopping

从结果看,对于这种不符合依赖倒置的代码也可以很好的实现功能。但这是采用面向过程的思想实现的。面向对象的实现是一种流程化的思想,上层永远要依赖于下层的具体实现。如果现在想把这种自动驾驶系统用在卡迪拉克(cadillac),那么就要修改上层的客户端了,就要写很多if else。这对于喜欢偷懒的程序员是致命的。为此,出现了面向对象。下面实现符合依赖倒置原则的代码。首先要抽象出car类

import abc


class Car(object):
    __metaclass__ = abc.ABCMeta

    @abc.abstractmethod
    def car_run(self, *args, **kwargs):
        pass

    @abc.abstractmethod
    def car_turn(self, *args, **kwargs):
        pass

    @abc.abstractmethod
    def car_stop(self, *args, **kwargs):
        pass


class Ford(Car):
    def __init__(self):
        self.type = 'ford'

    def car_run(self):
        print('%s is running' % self.type)

    def car_turn(self):
        print('%s is turning' % self.type)

    def car_stop(self):
        print('%s is stopping' % self.type)


class Buick(Car):
    def __init__(self):
        self.type = 'buick'

    def car_run(self):
        print('%s is running' % self.type)

    def car_turn(self):
        print('%s is turning' % self.type)

    def car_stop(self):
        print('%s is stopping' % self.type)


class Cadillac(Car):
    def __init__(self):
        self.type = 'cadillac'

    def car_run(self):
        print('%s is running' % self.type)

    def car_turn(self):
        print('%s is turning' % self.type)

    def car_stop(self):
        print('%s is stopping' % self.type)


class AutoSystem(object):

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

    def car_run(self):
        self.car.car_run()

    def car_turn(self):
        self.car.car_turn()

    def car_stop(self):
        self.car.car_stop()


if __name__ == '__main__':
    ford = Ford()
    buick = Buick()
    cadillac = Cadillac()
    autosystem = AutoSystem(ford)
    autosystem.car_run()
    autosystem.car_turn()
    autosystem.car_stop()
    autosystem.car = buick
    print('*'*100)
    autosystem.car_run()
    autosystem.car_turn()
    autosystem.car_stop()
    print("*"*100)
    autosystem.car = cadillac
    autosystem.car_run()
    autosystem.car_turn()
    autosystem.car_stop()

结果

ford is running
ford is turning
ford is stopping
****************************************************************************************************
buick is running
buick is turning
buick is stopping
****************************************************************************************************
cadillac is running
cadillac is turning
cadillac is stopping

2 抽象不应该依赖于具体,具体应该依赖于抽象

抽象不应该依赖于具体,具体应该依赖于抽象对于这句话,我的理解是:这句话针对类继承来说的,抽象类不能继承自具体的类,而 具体的类应该继承自抽象的类

到此为止,这篇博客就写完了,写的有点仓促,如发现有什么不对的地方,真心期待您能指出来,谢谢了

猜你喜欢

转载自blog.csdn.net/ruguowoshiyu/article/details/81177852