单件模式

写好的代码就是为了以后少写一些代码。

单件模式就是为了实现在一个应用程序中保证只有一个类的实例在运行。在一个应用程序中用到多个单件类的话,其实也不需要实现好多遍。下面是C++和C#实现的泛型的单件模式示例代码。注意:在ConcreteSingleton中Operation函数中操作的资源要实现线程安全,自己添加保护措施。

C++代码:

// locker.h
#pragma once

#include <windows.h>
namespace hangba
{
	namespace designpattern
	{
		class Locker
		{
		public:
			Locker();
			virtual ~Locker();
			void Lock();
			void Unlock();

		private:
			CRITICAL_SECTION m_cs;
		};

	}
}

// locker.cpp
#include "stdafx.h"
#include "Locker.h"

using namespace hangba::designpattern;

Locker::Locker()
{
	InitializeCriticalSection(&m_cs);
}


Locker::~Locker()
{
	DeleteCriticalSection(&m_cs);
}

void Locker::Lock()
{
	EnterCriticalSection(&m_cs);
}

void Locker::Unlock()
{
	LeaveCriticalSection(&m_cs);
}

// singleton.h
#pragma once

#include <memory>
#include "Locker.h"
using namespace std;
namespace hangba
{
	namespace designpattern
	{
		template<typename T>
		class Singleton
		{
		public:
			static T* GetInstance()
			{
				if (m_pInstance.get() == nullptr)
				{
					m_locker.Lock();
					if (m_pInstance.get() == nullptr)
					{
						m_pInstance.reset(new T);
					}
					m_locker.Unlock();
				}
				return m_pInstance.get();
			}
		private:
			Singleton(const Singleton&)
			{

			}
			Singleton& operator=(const Singleton&)
			{

			}
			Singleton()
			{

			}
			virtual ~Singleton()
			{

			}

		private:
			friend class auto_ptr<T>;
			static auto_ptr<T> m_pInstance;
			static Locker m_locker;
		};
		template<typename T>
		auto_ptr<T> Singleton<T>::m_pInstance;
		template<typename T>
		Locker Singleton<T>::m_locker;

#define DECLARE_SINGLTON_CLASS(T) \
	friend class auto_ptr<T>; \
	friend class Singleton<T>;
	}
}

// ConcreteSingleton.h
#pragma once
#include "../hangba/designpattern/Singleton.h"
using namespace hangba::designpattern;
#include <iostream>
using namespace std;

class ConcreteSingleton
{
public:
	void Operation()
	{
		cout << "ConcreteSingleton's operation()" << endl;
	}
	DECLARE_SINGLTON_CLASS(ConcreteSingleton);
private:
	ConcreteSingleton();
	virtual ~ConcreteSingleton();
};

typedef Singleton<ConcreteSingleton> CONCRETE_SINGLETON;

// ConcreteSingleton.cpp
#include "stdafx.h"
#include "ConcreteSingleton.h"


ConcreteSingleton::ConcreteSingleton()
{
}


ConcreteSingleton::~ConcreteSingleton()
{
}


// 单件模式.cpp
// 单件模式.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "ConcreteSingleton.h"

int _tmain(int argc, _TCHAR* argv[])
{
	// 用法一
	ConcreteSingleton* p1 = Singleton<ConcreteSingleton>::GetInstance();
	p1->Operation();

	// 用法二
	ConcreteSingleton* p2 = CONCRETE_SINGLETON::GetInstance();
	p2->Operation();

	// 用法三
	CONCRETE_SINGLETON::GetInstance()->Operation();

	// 测试p1和p2
	if (p1 == p2)
	{
		cout << "单件模式获取到的数据是相同的" << endl;
	}
	else
	{
		cout << "单件模式获取到的数据是不相同的" << endl;
	}

	getchar();
	return 0;
}




C#代码:

/*
 * 由SharpDevelop创建。
 * 用户: hangba
 * 日期: 2016/3/7
 * 时间: 10:39
 * 
 * 要改变这种模板请点击 工具|选项|代码编写|编辑标准头文件
 */
using System;

namespace 单件模式
{
	/// <summary>
	/// Description of SingletonException.
	/// </summary>
	public sealed class SingletonException : Exception
	{
		public SingletonException(string message) : base(message)
		{
		}
	}
}


/*
 * 由SharpDevelop创建。
 * 用户: hangba
 * 日期: 2016/3/7
 * 时间: 10:22
 * 
 * 要改变这种模板请点击 工具|选项|代码编写|编辑标准头文件
 */
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;

namespace 单件模式
{
	/// <summary>
	/// Description of Singleton.
	/// </summary>
	public class Singleton<T> where T : class
	{
		private static readonly object locker = new object();
		private static T instance;
		public static T Instance
		{
			get
			{
				if (instance == null)
				{
					lock(locker)
					{
						if (instance == null)
						{
							ConstructorInfo ci = typeof(T).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[0], null);
							if (ci == null)
							{
								throw new SingletonException("allocate T failed.");
							}
							instance = (T)ci.Invoke(null);
						}
					}
				}
				return instance;
			}
		}
	}
}


/*
 * 由SharpDevelop创建。
 * 用户: hangba
 * 日期: 2016/3/7
 * 时间: 10:48
 * 
 * 要改变这种模板请点击 工具|选项|代码编写|编辑标准头文件
 */
using System;

namespace 单件模式
{
	/// <summary>
	/// Description of ConcreteSingleton.
	/// </summary>
	public class ConcreteSingleton
	{
		public void Operation()
		{
			System.Console.WriteLine("ConcreteSingleton's Operation.");
		}
		private ConcreteSingleton()
		{
		}
		
		public static ConcreteSingleton Instance
		{
			get
			{
				return Singleton<ConcreteSingleton>.Instance;
			}
		}
	}
}


/*
 * 由SharpDevelop创建。
 * 用户: hangba
 * 日期: 2016/3/7
 * 时间: 10:22
 * 
 * 要改变这种模板请点击 工具|选项|代码编写|编辑标准头文件
 */
using System;

namespace 单件模式
{
	class Program
	{
		public static void Main(string[] args)
		{
			// 使用方法
			try
			{
				ConcreteSingleton.Instance.Operation();
			}
			catch (SingletonException e)
			{
				System.Console.WriteLine(e.Message);
			}
			// 比较测试
			try
			{
				ConcreteSingleton cs1 = ConcreteSingleton.Instance;
				ConcreteSingleton cs2 = ConcreteSingleton.Instance;
				if (cs1 == cs2)
				{
					System.Console.WriteLine("多个线程获取到的实例是一样的。");
				}
				else
				{
					System.Console.WriteLine("多个线程获取到的实例是不一样的。");
				}
			}
			catch (SingletonException e)
			{
				System.Console.WriteLine(e.Message);
			}
			

			
			// TODO: Implement Functionality Here
			
			Console.Write("Press any key to continue . . . ");
			Console.ReadKey(true);
		}
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值