4

我正在从这个来源学习构造函数注入https://softwareengineering.stackexchange.com/questions/177649/what-is-constructor-injection

我很高兴我能够理解它。但是,我对接口和类以及构造函数中的接口注入有一个基本的疑问。

具体来说,我无法理解我们如何在不创建第一个片段中的对象 Sword 的情况下注入接口。

class Samurai
{
    readonly IWeapon weapon;
    public Samurai() 
    {
        this.weapon = new Sword();
    }
    public void Attack(string target) 
    {
        this.weapon.Hit(target);
    }
}

在下面的代码片段中,他们声称它与上面的代码做同样的事情,但是松耦合。

class Samurai
{
    readonly IWeapon weapon;
    public Samurai(IWeapon weapon) 
    {
        this.weapon = weapon;
    }
    public void Attack(string target) 
    {
        this.weapon.Hit(target);
    }
}

有人可以帮我理解为什么我们没有"new"在第二个片段中使用关键字创建 Sword 对象,以及它如何在没有它的情况下运行?以上两个片段是否相同?而且,这是如何失去耦合的?

4

1 回答 1

7

传入 IWeapon 的实现允许您使用您决定创建的任何对象拥有任意数量的武器版本,只要它共享相同的公共接口。

您可以创建一个使用 IWeapon 接口的 Gun 或 Sword 对象,而您的 Samurai 类不会在意。在类中使用new关键字会阻止您这样做。相反,您被迫只使用 Samurai 知道的单一实现(因为它创建了它)。因此,如果您想稍后添加另一种武器,则必须修改 Samurai 类。如果您将其作为 API 公开给其他开发人员,那么实现这样的 Samurai 尤其糟糕,因为他们不想在您的代码中乱七八糟。

所以你会做这样的事情:

Gun gun = new Gun();
Samurai samurai = new Samurai(gun);

实现如下所示:

public class Gun : IWeapon { // Implementing IWeapon, and typecasting the class into a Weapon
   public Attack(string target) {
     // Perform attack logic here
   }
}

您的界面如下所示:

public interface IWeapon {
  void Attack(string target);
}
于 2013-11-09T05:06:11.773 回答