博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
重构:将单例模式从业务类中完全解耦
阅读量:5332 次
发布时间:2019-06-14

本文共 4319 字,大约阅读时间需要 14 分钟。

先来看看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
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
() where T : class4 {5 return Singleton
.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
();24 mapHelper = Dispatcher.BuildObject
();25 pathHelper = Dispatcher.BuildObject
();26 } 27 }

 

好了,到此为止,已经将单例模式从业务类中完全解耦。

业务类就是业务来,单例就是单例,无需将单例强加在业务类上。重构后,其文件结构如下:

 

 

 

转载于:https://www.cnblogs.com/startpoint/p/4218216.html

你可能感兴趣的文章
给mysql数据库字段值拼接前缀或后缀。 concat()函数
查看>>
迷宫问题
查看>>
【FZSZ2017暑假提高组Day9】猜数游戏(number)
查看>>
泛型子类_属性类型_重写方法类型
查看>>
eclipse-将同一个文件分屏显示
查看>>
mysql5.x升级至mysql5.7后导入之前数据库date出错的解决方法!
查看>>
对闭包的理解
查看>>
练习10-1 使用递归函数计算1到n之和(10 分
查看>>
Oracle MySQL yaSSL 不明细节缓冲区溢出漏洞2
查看>>
windows编程ASCII问题
查看>>
.net webService代理类
查看>>
Code Snippet
查看>>
Node.js Express项目搭建
查看>>
zoj 1232 Adventure of Super Mario
查看>>
1201 网页基础--JavaScript(DOM)
查看>>
组合数学 UVa 11538 Chess Queen
查看>>
oracle job
查看>>
Redis常用命令
查看>>
XML学习笔记(二)-- DTD格式规范
查看>>
IOS开发学习笔记026-UITableView的使用
查看>>