0

我已经阅读了有关 Dependency Inversion(SOLID 中的“D”)的内容,并在此处查看了一些示例。

但是,我看不到如何完全摆脱依赖!

根据文章,通过在消费者包中引入合同/接口,可以将关系 Consumer --> Utility 更改为 Utility --> Consumer。

此外,可以通过将合约/接口移动到单独的包(例如 Consumer --> Contracts <-- Utility)来完全解耦反向依赖关系。

现在,有了上面的布局;消费者使用实用程序不应该有工厂吗?然后带回原始依赖项,如下所示:

消费者 --> 工厂 --> 实用程序

4

1 回答 1

0

如果有帮助,我将描述一个依赖倒置原则出现在我工作的地方。

我确实使用内容管理系统 - 一个存储图像并让人们检索它们的系统。

好吧,这就是我们当前(糟糕的)C++ 代码的样子:

Retrieve()
    // code to initialize a vendor's API
    // code to pass in system credentials
    // code to clear the vendor's "current workitem list"
    // code to pull the document to the current workitem list
    // code to get content files from that document
    // code to format those files for passing back to the user

基本上,左右连接到供应商。这只是一个功能 - 在整个代码中都是相同的。

现在,想象你被告知:

“Sumith,我们正在迁移到新的成像系统 - 我们正在从供应商 ABC 迁移到供应商 XYZ。开始着手更改代码以使用新系统。”

...呃...嗯....是的...你将不得不重做所有代码。在每个函数中,在与该供应商交互的程序的每个部分中。依赖倒置的笑话基本上是这样说的,“你不会把你的灯直接塞进电线里,对吗?” 嗯,我们组有。

现在,这是依赖倒置如何处理的。

Retrieve()
    // Code that initializes an Interface we coded up
    // Code that uses that interface, to pull up a doc (which, again, is an interface)
    // Code that returns that doc interface's data

……那个界面?

Interface SimpleExample
    void Initialize();
    DocExample GetDoc();
Interface DocExample
    byte[] GetFileData();

所以,当经理说,“嘿,我们要搬到供应商 XYZ 上……”

...您需要自己思考的是,“好吧,我需要编写一个实现我的 'SimpleExample' 接口的新类,然后我可以将它直接插入我现有的代码中,而无需更改任何该程序的代码!”

现在,我正在重写整个事情,让我告诉你,依赖倒置原则已经为我节省了大量时间。我编写了一个“ContentManagement”接口(嗯,我使用的是一个抽象类,但它的功能类似)——我所要做的就是编写一个实现 ContentManagement 接口的类。然后我可以有这样的代码:

ContentManagement vendorToUse;
if (some criteria or such)
    vendorToUse = instanceOfNewVendor;
else
    vendorToUse = instanceOfOldVendor;
vendor.Initialize();
Document doc = vendor.Retrieve(...);
... etc

...尝试在没有DI 的情况下做到这一点将是一场噩梦 - 你基本上必须拥有该函数的两个单独版本。

于 2017-08-02T19:17:43.983 回答