我正在从此来源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的对象以及没有它的功能吗?以上两个摘要是否相同?而且,这怎么会失去联系呢?

最佳答案

通过传递IWeapon的实现,您可以与想要决定创建的任何对象一起拥有任意数量的武器版本,只要它共享相同的公共接口即可。

您可以创建使用IWeapon接口的Gun或Sword对象,而Samurai类则不在乎。在班级内部使用new关键字使您无法做到这一点。相反,您只能使用Samurai知道的单个实现(因为它创建了它)。因此,如果您以后想要添加其他武器,则必须修改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);
}

10-02 05:09