[dependency-injection] 為什麼要使用依賴注入?



Answers

我認為很多時候人們對依賴注入和依賴注入框架 (或者它經常被稱為的容器 )之間的區別感到困惑。

依賴注入是一個非常簡單的概念。 代替這個代碼:

public class A {
  private B b;

  public A() {
    this.b = new B(); // A *depends on* B
  }

  public void DoSomeStuff() {
    // Do something with B here
  }
}

public static void Main(string[] args) {
  A a = new A();
  a.DoSomeStuff();
}

你寫這樣的代碼:

public class A {
  private B b;

  public A(B b) { // A now takes its dependencies as arguments
    this.b = b; // look ma, no "new"!
  }

  public void DoSomeStuff() {
    // Do something with B here
  }
}

public static void Main(string[] args) {
  B b = new B(); // B is constructed here instead
  A a = new A(b);
  a.DoSomeStuff();
}

就是這樣。 認真。 這給你很多好處。 其中兩個重要的功能是從中心位置( Main()函數)控制功能,而不是將其分散到整個程序中,並且可以更輕鬆地單獨測試每個類(因為您可以將模擬對像或其他偽造對像傳入它的構造函數而不是真正的價值)。

當然,缺點是你現在有一個超級函數可以知道你的程序使用的所有類。 這是DI框架可以提供幫助的。 但是,如果您無法理解為什麼這種方法很有價值,那麼我建議首先從手動依賴注入入手,這樣您可以更好地理解那裡的各種框架可以為您做些什麼。

Question

我試圖理解依賴注入 (DI),並再次失敗。 它看起來很愚蠢。 我的代碼從來都不是一團糟; 我幾乎不寫虛擬函數和接口(雖然我只做了一次藍月亮),並且所有配置都使用json.net(有時使用XML序列化程序)奇蹟般地序列化為一個類。

我不太明白它解決了什麼問題。 它看起來像是一種說法:“嗨,當你遇到這個函數時,返回一個這種類型的對象並使用這些參數/數據。”
但是...為什麼我會使用它? 注意我從來不需要使用object ,但我明白這是什麼意思。

在建立一個使用DI的網站或桌面應用程序時,有哪些真實情況? 我可以很容易地想出為什麼有人可能想要在遊戲中使用接口/虛函數的情況,但是它非常罕見(很少有我不記得單個實例)在非遊戲代碼中使用它。




我認為經典答案是創建一個更加分離的應用程序,它不知道在運行時將使用哪個實現。

例如,我們是中央支付提供商,與世界各地的許多支付提供商合作。 但是,當提出請求時,我不知道要撥打哪個付款處理器。 我可以用一大堆開關盒編寫一節課,例如:

class PaymentProcessor{

    private String type;

    public PaymentProcessor(String type){
        this.type = type;
    }

    public void authorize(){
        if (type.equals(Consts.PAYPAL)){
            // Do this;
        }
        else if(type.equals(Consts.OTHER_PROCESSOR)){
            // Do that;
        }
    }
}

現在想像一下,現在您需要將所有這些代碼保存在一個類中,因為它沒有正確分離,您可以想像,對於您將支持的每個新處理器,您需要創建一個新的if // switch case for然而,通過使用依賴注入(或控制反轉 - 有時稱為,意味著控製程序運行的任何人只在運行時才知道,而不是並發症),那麼這只會變得更複雜,您可以實現某些非常整潔和可維護。

class PaypalProcessor implements PaymentProcessor{

    public void authorize(){
        // Do PayPal authorization
    }
}

class OtherProcessor implements PaymentProcessor{

    public void authorize(){
        // Do other processor authorization
    }
}

class PaymentFactory{

    public static PaymentProcessor create(String type){

        switch(type){
            case Consts.PAYPAL;
                return new PaypalProcessor();

            case Consts.OTHER_PROCESSOR;
                return new OtherProcessor();
        }
    }
}

interface PaymentProcessor{
    void authorize();
}

**代碼不會編譯,我知道:)




Links