1. 程式人生 > 其它 >設計模式-軟體設計原則-依賴倒轉原則

設計模式-軟體設計原則-依賴倒轉原則

高層模組不應該依賴低層模組,兩者都應該依賴其抽象;抽象不應該依賴細節,細節應該依賴抽象。簡單的說就是要求對抽象進行程式設計,不要對實現進行程式設計,這樣就降低了客戶與實現模組間的耦合。

下面看一個例子來理解依賴倒轉原則

【例】組裝電腦

現要組裝一臺電腦,需要配件cpu,硬碟,記憶體條。只有這些配置都有了,計算機才能正常的執行。選擇cpu有很多選擇,如Intel,AMD等,硬碟可以選擇希捷,西數等,記憶體條可以選擇金士頓,海盜船等。

類圖如下:

程式碼如下:

希捷硬碟類(XiJieHardDisk):

package com.mangoubiubiu.designpractice.yldz.before;

/** * 希捷硬碟 */ public class XiJieHardDisk { public void save(String data){ System.out.println("使用希捷硬碟儲存資料為 希捷硬碟"); } public String get(){ System.out.println("使用希捷硬碟讀取資料"); return "資料"; } }

Intel處理器(IntelCpu):

package com.mangoubiubiu.designpractice.yldz.before;


/** * intel cpu */ public class IntelCpu { public void run(){ System.out.println("使用Intel處理器"); } }

金士頓記憶體條(KingstonMemory):

package com.mangoubiubiu.designpractice.yldz.before;

public class KingstonMemory {
    public void save() {
        System.out.println("使用金士頓作為記憶體條");
    }
}

電腦(Computer):

package com.mangoubiubiu.designpractice.yldz.before;

/**
 * 電腦
 */
public class Computer {

    private KingstonMemory kingstonMemory;

    private IntelCpu intelCpu;

    private XiJieHardDisk xiJieHardDisk;


    public KingstonMemory getKingstonMemory() {
        return kingstonMemory;
    }

    public void setKingstonMemory(KingstonMemory kingstonMemory) {
        this.kingstonMemory = kingstonMemory;
    }

    public IntelCpu getIntelCpu() {
        return intelCpu;
    }

    public void setIntelCpu(IntelCpu intelCpu) {
        this.intelCpu = intelCpu;
    }

    public XiJieHardDisk getXiJieHardDisk() {
        return xiJieHardDisk;
    }

    public void setXiJieHardDisk(XiJieHardDisk xiJieHardDisk) {
        this.xiJieHardDisk = xiJieHardDisk;
    }

    public void run(){
        System.out.println("計算機工作");
        intelCpu.run();
        kingstonMemory.save();
        String data = xiJieHardDisk.get();
        System.out.println("從硬碟中獲取的資料為:" + data);
    }

}

測試類(TestComputer):

package com.mangoubiubiu.designpractice.yldz.before;

public class TestComputer {
    public static void main(String[] args) {
        Computer computer=new Computer();
        computer.setIntelCpu(new IntelCpu());
        computer.setKingstonMemory(new KingstonMemory());
        computer.setXiJieHardDisk(new XiJieHardDisk());
        computer.run();
    }
}

上面程式碼可以看到已經組裝了一臺電腦,但是似乎組裝的電腦的cpu只能是Intel的,記憶體條只能是金士頓的,硬碟只能是希捷的,這對使用者肯定是不友好的,使用者有了機箱肯定是想按照自己的喜好,選擇自己喜歡的配件。

根據依賴倒轉原則進行改進:

程式碼我們只需要修改Computer類,讓Computer類依賴抽象(各個配件的介面),而不是依賴於各個元件具體的實現類。

類圖如下:

電腦(Computer):

package com.mangoubiubiu.designpractice.yldz.after;

import com.mangoubiubiu.designpractice.yldz.before.KingstonMemory;
import com.mangoubiubiu.designpractice.yldz.before.XiJieHardDisk;

/**
 * 電腦
 */
public class Computer {

    private Cpu cpu;
    private HardDisk hardDisk;
    private Memory memory;

    public Cpu getCpu() {
        return cpu;
    }

    public void setCpu(Cpu cpu) {
        this.cpu = cpu;
    }

    public HardDisk getHardDisk() {
        return hardDisk;
    }

    public void setHardDisk(HardDisk hardDisk) {
        this.hardDisk = hardDisk;
    }

    public Memory getMemory() {
        return memory;
    }

    public void setMemory(Memory memory) {
        this.memory = memory;
    }

    public void run(){
        System.out.println("計算機工作");
        cpu.run();
        memory.save();
        String data = hardDisk.get();
        System.out.println("從硬碟中獲取的資料為:" + data);
    }

}

面向物件的開發很好的解決了這個問題,一般情況下抽象的變化概率很小,讓使用者程式依賴於抽象,實現的細節也依賴於抽象。即使實現細節不斷變動,只要抽象不變,客戶程式就不需要變化。這大大降低了客戶程式與實現細節的耦合度。