依赖倒置原则
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 抽象不应该依赖于具体,具体应该依赖于抽象
抽象不应该依赖于具体,具体应该依赖于抽象对于这句话,我的理解是:这句话针对类继承来说的,抽象类不能继承自具体的类,而 具体的类应该继承自抽象的类
到此为止,这篇博客就写完了,写的有点仓促,如发现有什么不对的地方,真心期待您能指出来,谢谢了