1700455200
//张三开奔驰车
1700455201
1700455202
zhangSan.drive(benz);
1700455203
1700455204
}
1700455205
1700455206
}
1700455207
1700455208
Client属于高层业务逻辑,它对低层模块的依赖都建立在抽象上,zhangSan的表面类型是IDriver,Benz的表面类型是ICar,也许你要问,在这个高层模块中也调用到了低层模块,比如new Driver()和new Benz()等,如何解释?确实如此,zhangSan的表面类型是IDriver,是一个接口,是抽象的、非实体化的,在其后的所有操作中,zhangSan都是以IDriver类型进行操作,屏蔽了细节对抽象的影响。当然,张三如果要开宝马车,也很容易,我们只要修改业务场景类就可以,实现过程如代码清单3-9所示。
1700455209
1700455210
代码清单3-9 张三驾驶宝马车的实现过程
1700455211
1700455212
public class Client{
1700455213
1700455214
public static void main(String[]args){
1700455215
1700455216
IDriver zhangSan=new Driver();
1700455217
1700455218
ICar bmw=new BMW();
1700455219
1700455220
//张三开奔驰车
1700455221
1700455222
zhangSan.drive(bmw);
1700455223
1700455224
}
1700455225
1700455226
}
1700455227
1700455228
在新增加低层模块时,只修改了业务场景类,也就是高层模块,对其他低层模块如Driver类不需要做任何修改,业务就可以运行,把“变更”引起的风险扩散降低到最小。
1700455229
1700455230
注意 在Java中,只要定义变量就必然要有类型,一个变量可以有两种类型:表面类型和实际类型,表面类型是在定义的时候赋予的类型,实际类型是对象的类型,如zhangSan的表面类型是IDriver,实际类型是Driver。
1700455231
1700455232
我们再来思考依赖倒置对并行开发的影响。两个类之间有依赖关系,只要制定出两者之间的接口(或抽象类)就可以独立开发了,而且项目之间的单元测试也可以独立地运行,而TDD(Test-Driven Development,测试驱动开发)开发模式就是依赖倒置原则的最高级应用。我们继续回顾上面司机驾驶汽车的例子,甲程序员负责IDriver的开发,乙程序员负责ICar的开发,两个开发人员只要制定好了接口就可以独立地开发了,甲开发进度比较快,完成了IDriver以及相关的实现类Driver的开发工作,而乙程序员滞后开发,那甲是否可以进行单元测试呢?答案是可以,我们引入一个JMock工具,其最基本的功能是根据抽象虚拟一个对象进行测试,测试类如代码清单3-10所示。
1700455233
1700455234
代码清单3-10 测试类
1700455235
1700455236
public class DriverTest extends TestCase{
1700455237
1700455238
Mockery context=new JUnit4Mockery();
1700455239
1700455240
@Test
1700455241
1700455242
public void testDriver(){
1700455243
1700455244
//根据接口虚拟一个对象
1700455245
1700455246
final ICar car=context.mock(ICar.class);
1700455247
1700455248
IDriver driver=new Driver();
1700455249
[
上一页 ]
[ :1.7004552e+09 ]
[
下一页 ]