廢話
1. 為了提升自己的學習效率,通過寫部落格的方式從被動學習轉化為一定程度的主動學習。
2.有一件每天都能堅持做的事情,可能更讓人有或者的感覺?
在讀《單元測試的藝術》的緒論的時候,有很多不懂的名詞,就去查了一下,一些印象深刻的就記了些筆記。
Mostly I stopped using property setters and am mostly using constructor injection.
什麼是依賴注入(Dependency Injection)
依賴注入是用來實作代碼的松耦合的一種模式。如果一個對象需要進行另一個對象的建立,管理等過程,這樣就會帶來一種緊耦合。
例子:在一個遊戲裡面,我是一個武士,我有一把劍,我拿劍攻擊。
///劍的類
class Sword
{
public void Hit(string target)
{
Console.WriteLine("Chopped {0} clean in half", target);
}
}
///武士的類,會用到那把劍,是以在裡面建立了一個劍的實體
class Samurai
{
readonly Sword sword;
public Samurai()
{
this.sword = new Sword();
}
public void Attack(string target)
{
this.sword.Hit(target);
}
}
///主函數,武士拿着劍去攻擊别人
class Program
{
public static void Main()
{
var warrior = new Samurai();
warrior.Attack("the evildoers");
}
}
這裡的武士就依賴于劍這個實體,是一種緊耦合。因為當我想給這武士換一把武器的時候。我需要去修改武士這個類的實作。
根據依賴倒置原則(DIP):高層子產品不應該依賴于底層子產品,二者都應該依賴于抽象。針對接口程式設計,不要針對實作程式設計。
這裡
Sword
類就是底層子產品,而我們以上用的方法就屬于針對實作的程式設計。
那應該怎麼修改呢?
///劍的抽象 是武器
interface IWeapon
{
void Hit(string target);
}
///底層子產品是劍,它應該依賴于武器這個抽象接口(繼承,實作也是一種依賴關系)。
class Sword : IWeapon
{
public void Hit(string target)
{
Console.WriteLine("Chopped {0} clean in half", target);
}
}
- 屬性注入
///高層子產品 是武士,他也應該依賴于武器這個抽象接口(組合也是一種依賴關系)
///這就是一種屬性注入(property injection),将武器作為武士的一種屬性,通過特定函數來設定它
class Samurai
{
IWeapon weapon;
public Samurai() { }
public void SetWeapon(IWeapon weapon)
{
this.weapon = weapon;
}
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);
}
}
- 方法注入
class Samurai
{
public void Attack(string target, IWeapon weapon)
{
weapon.Hit(target);
}
}
以上就是實作依賴注入的三種方式
- Constructor Injection
- Setter or property Injection
- Method Injection
還有第四種,我還沒有學到。
- Service Locator Injection
還有這幾種方式的優劣或者适用場景還有待學習,希望後續能夠繼續學習,繼續分享。