iOS Developer设计模式Android代码封装

【六大设计原则】依赖倒置原则

2018-06-24  本文已影响14人  杨志聪

依赖倒置原则(Dependence Inversion Principle,DIP),其原始定义是:

High level modules should not depend upon low level modules. Both should depend upon abstractions. Abstractions should not depend upon details. Details should depend upon abstractions.

翻译过来,就是两点:

1.高层模块不应该依赖低层模块,它们都应该依赖其抽象;
2.抽象不应该依赖细节,细节应该依赖抽象。

对于第一点,如果高层模块依赖于低层模块,一旦低层模块发生改变,高层模块也要跟着变动,这会导致开发成本大大提高。抽象一般是不会变化的东西,当模块之间是通过抽象形成依赖后,不管实现的细节怎么变化,只要抽象不变,程序就不需要太大的改动。

对于第二点,抽象一般指的是接口或者抽象类,细节一般指的是实现类,所以就是说:接口或者抽象类不应该依赖于实现类,而实现类应该依赖接口或者抽象类。

绕了半天,依赖倒置原则其实就是我们经常听说的面向接口编程

依赖倒置原则(或者说面向接口编程)可以减少类之间的耦合性,提高系统的稳定性,降低并行开发引起的风险,提高代码的可读性和维护性。

先举个不符合依赖倒置原则的简单例子。我们创建一个司机和一个宝马车,然后让司机开宝马车,全程没有抽象类或者接口的参与:

先创建宝马车:

@interface BMWCar : NSObject
- (void)run;
@end

@implementation BMWCar
- (void)run{
    NSLog(@"宝马车开动了");
}
@end

再创建司机:

#import "BMWCar.h"

@interface Driver : NSObject
- (void)driveCar:(BMWCar *)car;
@end

@implementation Driver
- (void)driveCar:(BMWCar *)car{
    [car run];
}
@end

然后就可以让我们的司机老王开车了:

Driver *wang = [Driver new];
BMWCar *bmw = [BMWCar new];
[wang driveCar:bmw];

这样写的问题在于司机和宝马车死死地耦合了在一起了,我们大款司机只能开宝马,其他车他是没办法开的。这样显然不合理,在真实世界里,只要我们拿了驾驶证,任何牌子的小轿车都是可以开的。合理的做法应该是把车抽象出来,然后让司机依赖车的抽象类:

创建车的抽象类Car

@interface Car : NSObject
- (void)run;
@end

@implementation Car
- (void)run{
}
@end

通过继承Car创建宝马车:

@interface BMWCar : Car
@end

@implementation BMWCar
- (void)run{
    NSLog(@"宝马车开动了");
}
@end

创建司机类,让司机和车的抽象类Car形成依赖:

#import "Car.h"

@interface Driver : NSObject
- (void)driveCar:(Car *)car;
@end

@implementation Driver
- (void)driveCar:(Car *)car{
    [car run];
}
@end

好了,下面就重新让我们的老王开车:

Driver *wang = [Driver new];
Car *bmw = [BMWCar new];
[wang driveCar:bmw];

假设又有了一辆新车奔驰:

@interface BenzCar : Car
@end

@implementation BenzCar
- (void)run{
    NSLog(@"奔驰车开动了");
}
@end

没问题,我们的老王照样可以开:

Driver *wang = [Driver new];
Car *benz = [BenzCar new];
[wang driveCar:benz];

这就是依赖倒置原则的好处。依赖倒置原则的本质就是通过抽象(接口或者抽象类)使各个类或者模块的实现彼此独立,实现类之间或者模块之间的松耦合。在实战中只要我们遵遁以下的几个规则就可以了:

  1. 每个类尽量都有接口或抽象类,或者两者具备。抽象是依赖倒置原则的基本要求;
  2. 变量的表面类型尽量是接口或者抽象类;
  3. 任何类都尽量从具体类派生。如果一个类是从具体类派生,那么这个类和它的非抽象的父类就形成强耦合;
  4. 尽量不要覆写基类的方法。如果基类是一个抽象类,而且这个方法已经实现了,子类尽量不要覆写。类间的依赖是抽象,覆写了抽象方法,会影响依赖的稳定性;
  5. 结合里氏替换原则使用。
上一篇 下一篇

猜你喜欢

热点阅读