主目录:一个面向对象设计(OOD)的学习思路设计java
引入: 高层的决定不能由于某一个低层次模块的变更而影响全局,致使整个系统的变更。编程
结构以下:学习
代码以下:this
/** * 高层 */
class GaoCeng {
ZhongCeng mZhongCeng;
public GaoCeng(ZhongCeng mZhongCeng) {
this.mZhongCeng = mZhongCeng;
}
}
/** * 中层 */
class ZhongCeng{
DiCeng mDiCeng;
public ZhongCeng(DiCeng mDiCeng){
this.mDiCeng = mDiCeng;
}
}
/** * 底层 */
class DiCeng{
}```
3. 依赖倒置正面教材
> 结构以下:

> 代码以下:
``` java
/** * 中层接口 */
interface ZhongCengInterface{
}
/** * 高层接口 */
interface GaoCengInterface{
}
/** * 高层 */
class GaoCeng {
GaoCengInterface mGaoCengInterface;
public GaoCeng(GaoCengInterface mGaoCengInterface) {
this.mGaoCengInterface = mGaoCengInterface;
}
}
/** * 中层 */
class ZhongCeng implements GaoCengInterface{
ZhongCengInterface mZhongCengInterface;
public ZhongCeng(ZhongCengInterface mZhongCengInterface){
this.mZhongCengInterface = mZhongCengInterface;
}
}
/** * 底层 */
class DiCeng implements ZhongCengInterface{
}
复制代码
既然咱们理解了DIP,那么DIP的好处不言而喻。spa
既然有好处,那么就一定有坏处:代码的增长,学习成本和代码思考时间的增长。(不过相对于后期的好处,这点咱们仍是能理解的)设计
其实理解DIP的例子就是一个很好的对比例子。 如今来一个实际一点的例子:超重提价code
以传统方式编程对象
/** * 称重器传统编程 */
class Scales{
private double readValue;//获取到的物体的重量
private double highestValue;
private double inPrice;
private double outPrice;
public Scales(double highestValue, double inPrice, double outPrice) {
this.highestValue = highestValue;
this.inPrice = inPrice;
this.outPrice = outPrice;
}
/** * 当有物体放上去后称重 */
public void startScales() {
//...readValue = ? (这里获取称重器计算的重量)
showWeigh(readValue);
double price = 0;
double diff = readValue - highestValue;
if (diff > 0) {
outWeighWarn(diff);
price += highestValue * inPrice;
price += diff * outPrice;
} else {
price += readValue * inPrice;
}
showPrice(price);
}
/** * 显示重量 */
private void showWeigh(double weigh) {
}
/** * 超重提醒 */
private void outWeighWarn(double outWeigh) {}
/** * 显示价格 */
private void showPrice(double price) {
}
}
复制代码
依赖倒置后接口
/** 称重接口*/
interface Weigh {
double read();
}
/** 最大重量、范围内价格、范围外价格的设置*/
interface Value{
double highestValue();
double inPrice();
double outPrice();
}
/** 显示器接口*/
interface Show {
void outWeighWarn(double diff);
void showWeigh(double weigh);
void showPrice(double price);
}
class Scales{
private Weigh mWeigh;
private Show mShow;
private Value mValue;
public Scales(Weigh mWeigh, Show mShow, Value mValue) {
this.mShow = mShow;
this.mWeigh = mWeigh;
this.mValue = mValue;
}
/** * 当有物体放上去后称重 */
public void startScales() {
mShow.showWeigh(mWeigh.read());
double price = 0;
double diff = mWeigh.read() - mValue.highestValue();
if (diff > 0) {
mShow.outWeighWarn(diff);
price += mValue.highestValue() * mValue.inPrice();
price += diff * mValue.outPrice();
} else {
price += mWeigh.read() * mValue.inPrice();
}
mShow.showPrice(price);
}
}
复制代码
咱们能够看出依赖倒置后使代码可复用,能够是任意的称重装置,能够是任意的显示装置,只要它们实现对应的接口便可。高层没必要在乎底层具体是什么东西。ip
每一个程序都会有违反这些规则的状况,有时必须建立具体类的实例。此外,这些规则对于那些具体但却稳定的类来讲彷佛不太合理。若是一个具体类不太会改变,而且也不会建立其余相似的派生类,那么依赖于它并不会形成损害,好比说String类型。
然而,咱们编写的大多数具体类都是不稳定的,咱们将它们隐藏在抽象接口后面,隔离它们的不稳定性。
因为抽象将高层和细节彼此隔离,因此代码也很是容易维护
[^foot1]: 敏捷软件开发 第12章 依赖倒置原则(DIP)