我正在从此来源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);
}