Let's take a look at Singleton's use case diagram:
In an actual old project, there are a lot of business classes, and do not know how to design, these business classes are designed to be singleton mode.
These business class structures in the project are as follows:
Each business class is designed as a singleton, such as:
Public classSearchhelper {Private Objectobj =New Object(); Private StaticSearchhelper Search; PrivateSearchhelper () {} Public Staticsearchhelper Instance {Get { if(Search = =NULL) { Lock(obj) {if(Search = =NULL) Search=NewSearchhelper (); } } returnsearch; } } Public stringGetsearch () {return "Path"; } }
This design is not very pleasing to the eye at the beginning of the first.
This kind of business class and single example of strong combination of the model, the actual application, but also really brought some trouble, such as this searchhelper, I sometimes need to some method to get updates the value of an entity, because its singleton class mode, directly can not get its value, had to detour.
So refactoring this module is already in front of it. Of course, you can not refactor, let the code continue to chaos, chaos, chaos, until death:-)
After some consideration, the first thought is the separation of these business classes and the pattern of the single example of a strong combination of patterns, separated so that the single case no longer rape these business classes.
As a result, there is the following:
The first step is to remove the single cases of these business classes and, after the removal, the code is structured as follows:
Public class searchhelper { private searchhelper () {} publicstring GetPath () { return"Path"; }}
In the same vein, all other business classes are removed from the singleton.
Pathhelper:
Public class pathhelper{ private pathhelper () {} publicstring GetPath () { return"Path"; }
}
Maphelper:
Public class Maphelper {
Private Maphelper () {} publicstring getmap () { return' Map"; }}
Step two: Define a singleton class, define a generic class, and use the reflection feature to enable it to dynamically create a single case on demand
Public classSingleton<t>whereT:class { StaticMutex Mutex =NewMutex (); StaticT instance; PrivateSingleton () {} Public StaticT uniqueinstance {Get{mutex.} WaitOne (); //Enter protected area if(Instance = =NULL) { Try{instance=singletoncreator.instance; } Catch(Exception ex) {Throwex; }} mutex. ReleaseMutex (); //Exit protected Area returninstance; } } classSingletoncreator {StaticSingletoncreator () {}//private object instantiated with private constructor Internal Static ReadOnlyT instance =createnewinstance (); Private StaticT createnewinstance () {//Get The current assembly objectAssembly Assembly =assembly.getexecutingassembly (); //Retrieve Assembly Typestype[] Types =Assembly. GetTypes (); foreach(Type TypeNameinchtypes) {Module Typemod=Assembly. GetModule (Typename.tostring ()); if(typeof(T). IsAssignableFrom (TypeName) &&(Typename.isclass)) {//Create and return an instance of the appropriate model object returnActivator.CreateInstance (TypeName) asT; } } Throw NewException ("New Instance not found!"); } } }
Step three: Define a dispatcher class that is used to obtain a singleton for a generic class.
1 Public class Dispatcher 2 {3public staticwhereclass4 {5 return singleton<t>. uniqueinstance; 6 }7 }
Fourth step: Define a facades class to get a single instance of the specific business class you want.
1 Public classFacades2 {3 Private StaticSearchhelper Searchhelper;4 Private StaticMaphelper Maphelper;5 Private StaticPathhelper Pathhelper;6 7 PublicSearchhelper Searchhelper8 {9 Get{returnSearchhelper;}Ten } One A PublicMaphelper Maphelper - { - Get{returnMaphelper;} the } - - PublicPathhelper Pathhelper - { + Get{returnPathhelper;} - } + Publicfacades () A { atSearchhelper = dispatcher.buildobject<searchhelper>(); -Maphelper = dispatcher.buildobject<maphelper>(); -Pathhelper = dispatcher.buildobject<pathhelper>(); - } -}
OK, so far, the singleton pattern has been completely decoupled from the business class.
Business class is business, single case is a single case, do not need to impose a single case on the business class. After refactoring, its file structure is as follows:
Refactoring: Completely decouple a singleton pattern from the business class