簡體   English   中英

簡單的依賴注入就足夠了,為什么要使用工廠模式

[英]Why using the factory pattern when a simple dependecy injection is enough

我正在看這個例子,以了解工廠模式的使用。

我真的是這個領域的專家,所以請原諒我這個愚蠢的問題。

我的問題是我看不到工廠模式的使用,該模式返回給我們接口,我們可以在需要使用它時直接注入它。

在上面的示例中,我將執行以下操作:

public class Program
{
    // register the interfaces with DI container in a separate config class (Unity in this case)
    private readonly IShippingStrategy _shippingStrategy;

    public Program(IShippingStrategy shippingStrategy)
    {
        _shippingStrategy= shippingStrategy;
    }

    public int DoTheWork(Order order)
    {
        // assign properties just as an example
        order.ShippingMethod = "Fedex";
        order.OrderTotal = 90;
        order.OrderWeight = 12;
        order.OrderZipCode = 98109;

        int shippingCost = _shippingStrategy.CalculateShippingCost(order);

        return shippingCost;
    }
}

而不是注入工廠:

public class Program
{
    // register the interfaces with DI container in a separate config class (Unity in this case)
    private readonly IShippingStrategyFactory _shippingStrategyFactory;

    public Program(IShippingStrategyFactory shippingStrategyFactory)
    {
        _shippingStrategyFactory = shippingStrategyFactory;
    }

    public int DoTheWork(Order order)
    {
        // assign properties just as an example
        order.ShippingMethod = "Fedex";
        order.OrderTotal = 90;
        order.OrderWeight = 12;
        order.OrderZipCode = 98109;

        IShippingStrategy shippingStrategy = _shippingStrategyFactory.GetShippingStrategy(order);
        int shippingCost = shippingStrategy.CalculateShippingCost(order);

        return shippingCost;
    }
}

當我們可以將接口直接注入到需要使用它的任何地方時,為什么還要花大筆錢創建一個工廠(從而增加一個額外的層)?

我想您不希望只想再寫一篇有關工廠模式的文章,而不僅僅是一個簡短的綜合答案。 因此,我想重點關注兩件事。

更大的靈活性

最常見的是,您會在基本上說的地方設置合成根目錄...

“如果有人想要IAnyService ,他應該獲得MyAnyServiceImplementation ”。

這對於您的應用程序是固定的。 設置完成后,您的依賴項注入容器將為您注冊的類實例提供服務,但您不應嘗試再次重新配置該容器。 這非常適合啟動靈活性,例如通過應用程序的配置為數據訪問組件注冊實現。 說...

“如果有人想要IUserRepository ,他應該得到MsSqlUserRepository因為我們正在使用MSSQL服務器”。

當然,具有“不可變”的構成根將限制在運行時根據應用程序狀態選擇實現的可能性。

相反,您可以注入一個類,該類決定當前狀態以選擇哪種服務實現。 數據驗證是該模式的典型場景,因為系統上不同實體的規則可能不同。 這里的流行詞是“規則模式”或“策略模式”。

終身控制

可以將一個長期存在的類實例視為一個視圖(用戶界面)或與其相連的任何類(例如一個視圖模型或控制器)。 只要用戶在視圖上處於活動狀態,該類就處於活動狀態。 例如,通過將一個類實例注入到視圖控制器的構造函數中,只要視圖存在,就可以持有它的活動實例。

例如,假設您要使用數據存儲庫連接到數據庫。 這些數據庫訪問調用應該很短,並且您不想長時間保持打開狀態。 使用存儲庫工廠,您可以非常精確地控制生存期,並確保在使用該類后將其刪除:

using (var repository = new _factory.CreateRepository(...))
{
    return repository.GetAnything();
}

這樣,只要視圖控制器有效,就可以注入並存活一個非常輕量級的類-工廠。 繁重的類-連接事物-不應長期存在,僅在需要時創建。

實際上,如果不需要加載數據,則很有可能根本不會實例化存儲庫(例如,由於前期緩存命中)。 如果您將直接注入存儲庫,則可以保證在每種情況下內存中都存在一個長期存在的實例。

如果檢查工廠代碼,則可以看到,根據訂單的ShippingMethod,工廠將返回IShippingStrategy的不同實現。 由於僅在調用DoTheWork之后才知道ShippingMethod,因此在構造類時不可能注入正確的實現(並且同一類甚至可能需要針對不同順序的不同實現)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM