嗚嗚喔學習筆記: 5月 2020

搜尋此網誌

2020年5月12日 星期二

C# Dependency Injection 依賴注入

程式碼常常改來改去的,但怎麼樣在需求改變的時候,只改動最少的東西捏??
這邊介紹一下 "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 之後做假的測試資料就很方便拉~

2020年5月5日 星期二

Unity Get Sprite Index of Texture , Unity 查找在Texture中的Sprite Index


using System; using System.Linq; using UnityEditor; using UnityEngine;


public static class SpriteUtility

{

public static byte GetSpriteIndex(Sprite sp)

{

if (sp)

{

string spriteSheet = AssetDatabase.GetAssetPath(sp.texture);

Sprite[] sprites = AssetDatabase.LoadAllAssetsAtPath(spriteSheet)

.OfType<Sprite>().ToArray();


int index = Array.FindIndex(sprites, s => s.name == sp.name);

return (byte)index;

}

else

{

return 0;

}

}

}