设计模式之依赖倒置原则
发布时间:2020-12-14 05:15:51 所属栏目:百科 来源:网络整理
导读:依赖倒置原则(Dependence Invsersion 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. 翻译
依赖倒置原则(Dependence Invsersion 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)抽象不应该依赖细节(3)细节应该依赖抽象。
高层模块和低层模块容易理解,每一个逻辑的实现都是由原子逻辑组成的,不可分割的原子逻辑就是低层模块,原子逻辑的再组装就是高层模块。那什么事抽象?什么又是细节呢?在Java语言中,抽象就是指接口或抽象类,两者都是不能直接被实例化的;细节就是实现类,实现接口或继承抽象类而产生的类就是细节,其特点就是可以直接被实例化,也就是可以加上一个关键字new产生一个对象,依赖倒置原则在java语言中的表现就是:
(1)模块间的依赖通过抽象发生,实现类之间不发生直接的依赖关系,其依赖关系是通过接口或抽象类产生的
(2)接口或抽象类不依赖于实现类
(3)实现类依赖接口或抽象类。
更加精简的定义就是"面向接口编程"——OOD(Object-Oriented Design,面向对象设计)的精髓之一。
采用依赖倒置原则可以减少类间的耦合性,提高系统的稳定性,降低并行开发引起的风险,提高代码的可读性和可维护性。
在Java中,只要定义变量就必然要有类型,一个变量可以有两种类型:表面类型和实际类型,表面类型是在定义的时候赋予的类型,实际类型是对象的类型。
抽象是对实现的约束,对依赖者而言,也是一种契约,不仅仅约束自己,还同时约束自己与外部的关系,其目的是保证所有的细节不脱离契约的范畴,确保约束双方按照既定的契约(抽象)共同发展,只要抽象这根基线在,细节就脱离不了这个圆圈,始终让你的对象做到“言必信,行必果”。
依赖的三种写法:(1)构造函数传递依赖对象(2)Setter方法传递依赖对象(3)接口声明依赖对象。
练习代码:
package com.gc.designmodel; /** * * @说明 学习设计模式之依赖倒置原则(Dependence Inversion Principle,DIP) * @作者 GeneralAndroid * @创建日期 2015-9-1 下午1:13:12 * @版本号 1.0 * @since 1.0 * 采用依赖倒置原则可以减少类间的耦合性,提高系统的稳定性,降低并行开发引起的风险,提高代码的可读性和 * 可维护性。 * * 依赖倒置原则的本质就是通过抽象(接口或抽象类)使各个类或模块的实现彼此独立,不互相影响,实现模块间的松耦合。 * 在项目中使用时只要遵循以下的几个规则就可以: * (1)每个类尽量都有接口或抽象类,或者抽象类和接口两者都具备。 * (2)变量的表面类型尽量是接口或者是抽象类 * (3)任何类都不应该从具体类派生(主要不超过两层的继承还是可以忍受的) * (4)尽量不要覆写基类的方法 * (5)结合里式替换原则使用 * */ public class TestDIPDemo { public static void main(String[] args) { // // Driver1 zhangSan=new Driver1(); // Benz1 benz=new Benz1(); // //张三开奔驰车 // zhangSan.drive(benz); // IDriver zhangSan=new Driver(); // ICar benz=new Benz(); // zhangSan.drive(benz); // ICar bmw=new BMW(); // zhangSan.drive(bmw); // IDriverOne iDriverOne=new DriverOne(new Benz()); // iDriverOne.drive(); IDriverTwo iDriverTwo=new DriverTwo(); iDriverTwo.setCar(new Benz()); iDriverTwo.drive(); } } /**司机类**/ class Driver1 { /**司机的主要职责就是驾驶汽车**/ public void drive(Benz1 benz) { benz.run(); } } /**奔驰车类**/ class Benz1{ /**汽车肯定会跑**/ public void run(){ System.out.println("奔驰汽车开始运行..."); } } /**宝马车类**/ class BMW1{ /**宝马车当然也可以开动了**/ public void run(){ System.out.println("宝马汽车开始运行..."); } } /**接口只是一个抽象化的概念,是对一类事物的最抽象描述,具体的实现代码由相应的实现类来完成。 * 依赖3种写法的其中一种——接口声明依赖对象。 * **/ /**司机接口**/ interface IDriver{ /**是司机就应该会驾驶汽车**/ public void drive(ICar car); } /**司机实现类**/ class Driver implements IDriver{ /**司机的主要职责就是驾驶汽车**/ public void drive(ICar car) { // TODO Auto-generated method stub car.run(); } } /**汽车接口**/ interface ICar{ /**是汽车就应该能跑**/ public void run(); } class Benz implements ICar{ public void run() { // TODO Auto-generated method stub System.out.println("奔驰汽车开始运行..."); } } class BMW implements ICar{ public void run() { // TODO Auto-generated method stub System.out.println("宝马汽车开始运行..."); } } /***依赖的三种写法***/ /**1、构造函数传递依赖对象: * 在类中通过构造函数声明依赖对象,按照依赖注入的说法,这种方式叫做构造函数注入。 * **/ interface IDriverOne { //是司机就应该会驾驶汽车 public void drive(); } class DriverOne implements IDriverOne{ private ICar car; //构造函数注入 public DriverOne(ICar _car){ this.car=_car; } //司机的主要职责就是驾驶汽车 public void drive() { // TODO Auto-generated method stub this.car.run(); } } /**2、Setter方法传递依赖对象 * 在抽象中设置Setter方法声明依赖关系,依照依赖注入的说法,这是Setter依赖注入 * **/ interface IDriverTwo{ /**车辆型号**/ public void setCar(ICar car); /**是司机就应该会驾驶汽车**/ public void drive(); } class DriverTwo implements IDriverTwo{ private ICar car; public void setCar(ICar car) { // TODO Auto-generated method stub this.car=car; } /**司机的主要职责就是驾驶汽车**/ public void drive() { // TODO Auto-generated method stub this.car.run(); } } 转载请注明出处: http://www.voidcn.com/article/p-vsfuoaxf-ke.html (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |