design-patterns - 控制反转和依赖注入(inject)

标签 design-patterns architecture dependency-injection inversion-of-control

这是一个非常谈论的概念:Ioc(控制反转)。
我使用这个概念已经有一段时间了。通常我会选择 DI(而不是服务定位器)方法在我的代码中实现 IoC。
以下是我对 IoC 的理解。

如果 classA 依赖于 classB 如果它在其中声明了 classB 的实例。它依赖于 B 类,出于某种原因(我稍后会谈到),不好,因此我们使用 DI 来解决这个问题。所以现在我们有一个名为 IClassB 的接口(interface),它将在 classA 的构造函数中传递(为了说明,我在这里使用构造函数注入(inject))。代码如下:

public class ClassA
{
    IClassB _classBObj = null;

    public ClassA(IClassB classBObj)
    {
         _classBObj = classBObj;
    }

    public void UseClassBMethod()
    {
        this._classBObj.classBMethod();
    }
}

public class ClassB:IClassB
{

    public void classBMethod()
    {
        //Some task carried out by classB.
    }
}

public interface IClassB
{
    void classBMethod();
}

下面是使它运行的代码:
class Program
{
    static void Main(string[] args)
    {
        //This code is outside of class A and hence declaring 
        //object of ClassB is not dependency
        ClassA classA=new ClassA(new ClassB);
        classA.UseClassBMethod();

    }
}

我已经演示了上面的示例,只是为了确保我对 IoC 和 DI 的理解是否正确。如果您发现任何错误,请纠正我。
现在,当我试图找出 IoC 的原因时,我发现了两个重要的原因:
  • 可测试性:当然是一个正确的问题。假设,例如,在上面的例子中,classB 方法使用 SMPTP 服务器或一些 WCF/Web 服务,我们可能无法对其进行测试。然而,我们可以创建一个实现接口(interface) IClassB 的测试 stub 类,并通过传递一个测试 stub 类的实例来继续测试。
  • 具体实现方面的依赖性:这是我无法接受的。即使我用以下代码更改了 classA 的代码:

  • public class ClassA
    {
       ClassB _classBObj = null;
    
       public ClassA()
       {
         _classBObj = new ClassB();
       }
    
       public void UseClassBMethod()
       {
          this._classBObj.classBMethod();
       }
    }
    

    IoC 如何帮助摆脱因 ClassB 对象的 classB 方法更改而出现的任何问题?如果方法签名有任何变化,我们也必须对接口(interface) IClassB 的方法签名进行更改(实际上,这增加了重构任务。)。如果方法实现发生更改,例如它占用了额外的日志记录任务,则更改将仅限于 ClassB 代码。

    这个问题我可能看起来有点愚蠢,但是有人可以提出一个场景(除了单元可测试性)我们从这种方法中受益吗?

    非常感谢您阅读本文。

    最佳答案

    这里的核心概念是你 program against an interface .
    您的代码不知道任何具体的类。

    因此,您可以在不影响代码的情况下切换具体实现。

    在您的情况下,您可以替换 ClassA classA=new ClassA(new ClassB);ClassA classA=new ClassA(new ClassC);其中有
    不同的行为,例如或多或少是最佳的,或者需要一些密码才能做某事等。

    这个想法是,如果 ClassC遵循 ClassB 的接口(interface)也实现然后你可以改变使用ClassC没有
    您的代码中的任何更改

    如果接口(interface)发生变化,你的代码当然会受到影响。这是你无法避免的。

    但是您获得的是,您可以在不影响您的代码的情况下切换和更改具体实现,并且这种更改比根据您的需要正确定义的接口(interface)更频繁地需要和发生

    关于design-patterns - 控制反转和依赖注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8786485/

    相关文章:

    design-patterns - 原型(prototype)与。享元设计模式

    CakePHP - 放置服务逻辑的位置

    c# - 创建 CaSTLe.Windsor 拦截器的问题

    python - 如何模拟用 Python 编写的 Azure 函数中使用的对象

    Python项目架构

    .net - Autofac 和 Func 工厂

    C++ 设计模式 : Possible to have inherited method private to derived class?

    hibernate ,偷懒还是不偷懒?

    reference - 开发术语和定义引用

    java - 在什么时候短 sleep 会增加而不是减少 CPU 利用率