程式碼常常改來改去的,但怎麼樣在需求改變的時候,只改動最少的東西捏??
這邊介紹一下 "Dependency Injection 依賴注入" 的技巧~~
舉個例子搭車好了
有一個人搭賓士車
public class Human
{
Benz _c;
public Human()
{
_c = new Benz();
...
}
}
因為這裡 Human 直接參與了 new Benz() (賓士) 的創建過程,所以如果Benz創建過程有改的話 Human也要改,hen麻煩。
現實生活上也不會發生,反正人搭車,人又不是汽車製造商,今天汽車換零件。乾我屁事XD?
所以我們把車改成 "參數" 的方式丟進去就好了~
public class Human
{
Benz _c;
public Human(Benz b)
{
_c = b;
}
}
ok改成這樣之後 怎麼做汽車跟我就無關咯,反正我只是要搭而已。
有天又想改搭Ferrari(法拉利)了,結果又要改Human。hen麻煩又要改?
不用我們把剛剛的參數 改成 ICar 好了,反正有車搭就行了。( 抽象層次往上提升 )
public interface ICar
{
}
public class Benz : ICar
{
}
public class Ferrai : ICar
{
}
public class Human
{
ICar_c;
public Human(ICar c)
{
_c = c;
}
}
好啦改成這樣之後以後要什麼車都可以直接 "依賴注入" 進 human 裡面拉~
這裡就用到物件導向 "多形" 的好處了。
比如
new Human( new Benz() );
new Human( new Ferrai() );
但其實也沒人規定一定要是汽車吧 , 可以是火車,公車,三輪車有的沒的,只要是交通工具(ITransportaion)就行了
所以也可以改成 ( 抽象程度再提升一階 )
public interface ITransportaion
{
}
public interface ICar : ITransportaion
{
}
public class Human
{
ITransportaion _c;
public Human(ITransportaion c)
{
_c = c;
}
}
好啦改完之後,以後要換成火車也沒問題啦~
這就是一步一步解耦合
從搭個車還要管車子怎麼生產的,到想改搭飛機都行,反正不關我的事,只要能到目的地就好。
上面的例子,我們盡可能地讓各個Class的關聯性不要那麼高
所以最後我們抽象出 ITransportaion 讓 Human 只依賴 ITransportaion 這個介面達到更好的擴充性。
另外 Dependency Injection 對於 "抽象層次" 有很重要的關係,抽象層次越高,擴充性就越好。
如果單單只是用 Dependency Injection 其實意義並不大的感覺。
另外 Dependency Injection 也可以方便測試。
在測試 Human 類別時。
還要創建一台車,往往粉麻煩(取決於創建複雜度)(可能還有環境搭建之類的)
但我們抽離出 ITransportaion 之後做假的測試資料就很方便拉~
沒有留言:
張貼留言