1. 程式人生 > >設計模式之“單例模式”C++/python實現

設計模式之“單例模式”C++/python實現

       單例模式用來只允許建立一個例項的類,比如一個系統中只能有一個工作管理員,對於單伺服器多客戶端系統,伺服器也應該設為單例的。

       對於C++單例模式需要滿足以下三點:

       1)單例模式的類只提供私有的建構函式;

       2)是類定義中含有一個該類的靜態私有物件;

       3)該類提供了一個靜態的公有函式用於建立或獲取它本身的靜態私有物件;

      對於python,主要從建立物件例項的唯一性來保證一個類只能建立一個例項。如對建立例項功能加上裝飾器,裝飾器的作用是如果此類的例項已經被建立,則直接返回例項。

    c++ 實現程式碼如下:

# include <iostream>

using namespace std;

class SingleClass
{
	private:
		SingleClass()
		{ 
			cout << "this is the constructor fun" << endl;
		}
		static SingleClass* SingleExamble;
	public:
		static SingleClass* GetInstance()
		{
			if(NULL == SingleExamble)
			{
				SingleExamble = new SingleClass();
			}
			
			return SingleExamble;
		}

		void TestFun()
		{
			cout << "test the instance" << endl;
		}
};

 SingleClass* SingleClass::SingleExamble = NULL;

void main()
{
	SingleClass* SingleExamble1 = SingleClass::GetInstance();
	SingleExamble1->TestFun();

    SingleClass* SingleExamble2 = SingleClass::GetInstance();
	SingleExamble2->TestFun();

	if(SingleExamble1 == SingleExamble2)
	{
		cout << "creat single instance success!" << endl;
	}

	//複製建構函式複製單例物件
	SingleClass* SingleExamble3(SingleExamble1);
	if(SingleExamble3 == SingleExamble1)
	{
		cout << "copy constructor creat single instance success!" << endl;
	}

}



    結果:

this is the constructor fun
test the instance
test the instance
creat single instance success!
copy constructor creat single instance success!

  對於python,一般的類建立物件,如下:

#!/usr/bin/python  
# -*- coding: utf-8 -*-  
class Foo:
	a = 1

foo1 = Foo()
foo2 = Foo()

foo1.a =3

print foo1.a, foo2.a
print foo1 , foo2

結果:

3 1 <__main__.Foo instance at 0x01AAC968> <__main__.Foo instance at 0x01AAC990>

可以看到,一個類建立了兩個不同的例項,加上裝飾器後:

#!/usr/bin/python  
# -*- coding: utf-8 -*-  
def Singleton(cls):
	instance = {}
	
	def wrapper(*args, **kwargs):
		if cls not in instance.keys():
			instance[cls] = cls(*args, **kwargs)
		return instance[cls]
		
	return wrapper

@Singleton	
class Foo:
	a = 1

foo1 = Foo()
foo2 = Foo()

foo1.a =3

print foo1.a, foo2.a
print foo1 , foo2

結果:

3 3 <__main__.Foo instance at 0x01A2CA08> <__main__.Foo instance at 0x01A2CA08>

可以看到Foo類建立的兩個例項是一致的,注意*args, **kwargs是保證可以傳入所有引數。