Refactoring: Completely decouple a singleton pattern from the business class

Source: Internet
Author: User

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

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

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.