设计模式(5)-----依赖倒转原则 依赖倒转原则

定义

  A.高层模块不应该依赖底层模块。两个都应该依赖抽象。

  B.抽象不应该依赖细节。细节应该依赖抽象。

  在面向对象的世界里,所谓的抽象指的就是借口和抽象类,而对于依赖倒转原则自己更深的理解就是“面向接口编程”。

例子

  在一个汽车自动检测系统中,该系统可以自动对车子进行run和stop的检测。

package com.csdhsm.designpattem.dependence;

/**  
 * @Title:  JeepCar.java   
 * @Description: 吉普车
 * @author: Han   
 * @date:   2016年6月19日 下午2:41:33   
 */  
public class JeepCar {
    
    public void run() {
        System.out.println("Jeep Is Running");
    }
    
    public void stop() {
        System.out.println("Jeep Is Stop");
    }
}
package com.csdhsm.designpattem.dependence;

/**  
 * @Title:  AutoSystem.java   
 * @Description: 汽车自动系统
 * @author: Han   
 * @date:   2016年6月19日 下午2:40:09   
 */  
public class AutoSystem {
    
    private JeepCar jeepCar;
    
    public AutoSystem(JeepCar jeepCar) {
        this.jeepCar = jeepCar;
    }
    
    public void runCar() {
        jeepCar.run();
    }
    
    public void stopCar() {
        jeepCar.stop();
    }
}

  客户端

package com.csdhsm.designpattem.dependence;

public class Solution {
    public static void main(String[] args) {
        JeepCar jeepCar = new JeepCar();
        AutoSystem system = new AutoSystem(jeepCar);
        
        system.runCar();
        system.stopCar();
    }
}

  很明显,需求是满足了的,但是这样的一个结构是非常脆弱和僵硬的,在软件的世界里,需求随时都有可能会变化,如果今天不检查吉普车了,换成福特车了,很尴尬的是我们的自动系统仿佛不能够检测福特车,修改AutoSystem,想要检车福特车并不难,但是这样很明显就违背了我们上一个原则,开放-封闭原则。仔细想一想,但凡是满足run和stop两个动作的车型,都应该是能被检测的,所以我们只需要添加一个RunableAndStopable接口,问题就很好解决了。

  RunableAndStopable接口

package com.csdhsm.designpattem.dependence;

/**  
 * @Title:  RunableAndStopable.java   
 * @Description: 接口设计,可以run和stop的车
 * @author: Han   
 * @date:   2016年6月19日 下午2:49:18   
 */  
public interface RunableAndStopable {
    
    public void run();
    
    public void stop();
}
package com.csdhsm.designpattem.dependence;

/**  
 * @Title:  JeepCar.java   
 * @Description: 吉普车
 * @author: Han   
 * @date:   2016年6月19日 下午2:41:33   
 */  
public class JeepCar implements RunableAndStopable {
    
    public void run() {
        System.out.println("Jeep Is Running");
    }
    
    public void stop() {
        System.out.println("Jeep Is Stop");
    }
}
package com.csdhsm.designpattem.dependence;

/**  
 * @Title:  FordCar.java   
 * @Description: 福特车
 * @author: Han   
 * @date:   2016年6月19日 下午2:51:03   
 */  
public class FordCar implements RunableAndStopable {

    @Override
    public void run() {
        System.out.println("Ford Is Running");
    }

    @Override
    public void stop() {
        System.out.println("Ford Is Stop");
    }
}
package com.csdhsm.designpattem.dependence;

/**  
 * @Title:  AutoSystem.java   
 * @Description: 汽车自动系统
 * @author: Han   
 * @date:   2016年6月19日 下午2:40:09   
 */  
public class AutoSystem {
    
    /**
     * 实现了RunableAndStopable接口的车
     */
    private RunableAndStopable car;
    
    public AutoSystem(RunableAndStopable car) {
        this.car = car;
    }
    
    public void runCar() {
        car.run();
    }
    
    public void stopCar() {
        car.stop();
    }
}

  客户端

package com.csdhsm.designpattem.dependence;

public class Solution {
    public static void main(String[] args) {
        RunableAndStopable car = new FordCar();
        AutoSystem system = new AutoSystem(car);
        
        system.runCar();
        system.stopCar();
    }
}

  OK,成功,下回再遇到什么宝马车,马拉车都不怕啦,只要你可以run和stop,都可以被我检测。