柏拉图式的编程

有困难找组织!

导航

[Design Pattern]一种基于抽象类的Singleton模式的实现

namespace UtilityLibrary.PatternAndPractice
{
    
using System;
    
using System.Globalization;
    
using System.Reflection;

    
/// <summary>
    
/// The base class that implemented the singleton pattern
    
/// </summary>
    
/// <typeparam name="T">The target type needs the singleton feature. T must:
    
/// Have and only have a private default constructor</typeparam>
    
/// <exception cref="TypeInitializationException">
    
/// Throw a TypeInitializationException if the target type doesn't fullfile the condition:
    
/// Have and only have a private default constructor
    
/// </exception>
    public abstract class SingletonBase<T> 
        
where T : class
    {
        
/// <summary>
        
/// A protected constructor which is accessible only to the sub classes.
        
/// </summary>
        protected SingletonBase() { }

        
/// <summary>
        
/// Gets the singleton instance of this class.
        
/// </summary>
        public static T Instance
        {
            
get { return SingletonFactory.Instance; }
        }

        
/// <summary>
        
/// The singleton class factory to create the singleton instance.
        
/// </summary>
        class SingletonFactory
        {
            
// Explicit static constructor to tell C# compiler
            
// not to mark type as beforefieldinit
            static SingletonFactory() 
            { 
            }

            
            
/// <summary>
            
/// Prevents a default instance of the <see cref="SingletonBase&lt;T&gt;.SingletonFactory"/> class from being created.
            
/// </summary>
            
/// <remarks>Prevent the compiler from generating a default constructor.</remarks>
            SingletonFactory() 
            { 
            }

            
internal static readonly T Instance = GetInstance();

            
/// <summary>
            
/// Gets the instance.
            
/// </summary>
            
/// <returns>The instance of type T</returns>
            static T GetInstance()
            {
                var theType 
= typeof(T);
                T instance;
                
try
                {
                    instance 
= (T)theType.InvokeMember(
                        theType.Name,
                        BindingFlags.CreateInstance 
| BindingFlags.Instance | BindingFlags.NonPublic,
                        
null
                        
null
                        
null,
                        CultureInfo.CurrentCulture);
                }
                
catch (MissingMethodException ex)
                {
                    
string pattern = 
                        
"The type '{0}' must have a private constructor to be used in the Singleton pattern.";
                    
string message = string.Format(CultureInfo.CurrentCulture, pattern, theType.FullName);
                    
throw new TypeLoadException(message, ex);
                }

                
return instance;
            }
        }
    }
}

 

 

同时使用起来也是非常的简单直观:

 

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using UtilityLibrary.PatternAndPractice;

namespace UtilityLibraryUnitTest.PatternAndPractice
{
    [TestFixture]
    
class SingletonBaseTestSuite
    {
        
class SingletonTest : SingletonBase<SingletonTest>
        {
            
private SingletonTest()
            {
            }

            
public string Name { get { return "SingletonTest"; } }
        }

        
class SingletonTestNegate : SingletonBase<SingletonTestNegate>
        {
            
public SingletonTestNegate()
            {
            }

            
public string Name { get { return "SingletonTestNegate"; } }
        }

        
class SingletonTestNegateToo : SingletonBase<SingletonTestNegate>
        {
            
private int x;
            
private SingletonTestNegateToo(int x)
            {
                
this.x = x;
            }

            
public string Name { get { return "SingletonTestNegate"; } }
        }

        [Test]
        
public void SingletonBaseTest()
        {
            
string s1 = SingletonTest.Instance.Name;
            Assert.AreEqual(
                
"SingletonTest",
                s1);

            Assert.Catch
<TypeInitializationException>(delegate{string s2 = SingletonTestNegate.Instance.Name;});

            Assert.Catch
<TypeInitializationException>(delegate { string s2 = SingletonTestNegateToo.Instance.Name; });
        }
    }
}

 

posted on 2011-08-31 22:11  五斗米  阅读(321)  评论(0编辑  收藏  举报