重構:將單例模式從業務類中完全解耦

來源:互聯網
上載者:User

標籤:

先來看看Singleton的使用案例圖:

在一個實際的老項目中,有很多的業務類,也不知道當時如何設計的,這些業務類均被設計成了Singleton模式。

項目中這些業務類結構如下:

而每個業務類的設計均為單例,諸如:

public class SearchHelper    {        private object obj = new object();        private static SearchHelper search;        private SearchHelper(){}        public static SearchHelper Instance        {            get            {                if (search == null)                {                    lock (obj)                    {                        if (search == null)                            search = new SearchHelper();                    }                }                return search;            }        }        public string GetSearch()        {            return "Path";        }    }


這種設計初初一看,就不是很順眼。

這種業務類和單例本身強結合的模式,實際應用中,還真帶來了一些麻煩,比如這個SearchHelper, 我有時候需要對某些方法擷取更新某實體後的值,因其單例類模式,直接就無法得到其值,只好繞彎路。

於是重構這個模組,已經是擺在面前。 當然也可以不去重構,讓代碼繼續亂下去,亂下去,亂下去,直到死亡 :-)

 

經過一番考慮,首先想到的是將這些業務類和單例這個模式強結合的模式分離, 分離後讓單例不再強姦這些業務類。

 

於是,就有了下文:

第一步:將這些業務類的單例去除,出除後,代碼結構如下:

public class SearchHelper {     private SearchHelper(){}      public string GetPath()      {          return "Path";      } }

同理,去除其他所有的業務類的單例。
PathHelper:

public class PathHelper{  private PathHelper(){}   public string GetPath()   {       return "Path";   }
}

MapHelper: 

 public class MapHelper {
  private MapHelper(){} public string GetMap() { return "Map"; } }

 

第二步:定義個單例專用類,定義一個泛型類,並利用反射特性使其能夠動態按需建立單例

 public class Singleton<T> where T : class    {        static Mutex mutex = new Mutex();        static T instance;        private Singleton() { }        public static T UniqueInstance        {            get            {                mutex.WaitOne();        // enter protected area                if (instance == null)                {                    try                    {                        instance = SingletonCreator.instance;                    }                    catch (Exception ex)                    {                        throw ex;                    }                }                mutex.ReleaseMutex();   // exit protected area                return instance;            }        }        class SingletonCreator        {            static SingletonCreator() { }            // Private object instantiated with private constructor            internal static readonly T instance = CreateNewInstance();            private static T CreateNewInstance()            {                //Get the current assembly object                Assembly assembly = Assembly.GetExecutingAssembly();                // Retrieve assembly types                Type[] types = assembly.GetTypes();                foreach (Type typeName in types)                {                    Module typeMod = assembly.GetModule(typeName.ToString());                    if (typeof(T).IsAssignableFrom(typeName) && (typeName.IsClass))                    {                        // Create and return an instance of the appropriate model object                        return Activator.CreateInstance(typeName) as T;                    }                }                throw new Exception("New instance not found!");            }        }    }


第三步: 定義一個Dispatcher類,用以得到泛型類的單例。

1  public class Dispatcher2     {3         public static T BuildObject<T>() where T : class4         {5             return Singleton<T>.UniqueInstance;6         }7     }


第四步: 定義一個Facades類,用以得到想要的具體的某業務類的單例。

 1  public class Facades   2     { 3         private static SearchHelper searchHelper; 4         private static  MapHelper mapHelper; 5         private static  PathHelper pathHelper; 6  7         public SearchHelper SearchHelper 8         { 9             get { return searchHelper; }10         }11 12         public MapHelper MapHelper13         {14             get { return mapHelper; }15         }16 17         public PathHelper PathHelper18         {19             get { return pathHelper; }20         }21         public Facades()22         {23             searchHelper = Dispatcher.BuildObject<SearchHelper>();24             mapHelper = Dispatcher.BuildObject<MapHelper>();25             pathHelper = Dispatcher.BuildObject<PathHelper>();26         }       27     }

 

好了,到此為止,已經將單例模式從業務類中完全解耦。


業務類就是業務來,單例就是單例,無需將單例強加在業務類上。重構後,其檔案結構如下:

 

 

 

重構:將單例模式從業務類中完全解耦

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.