设计模式之“单例模式”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是保证可以传入所有参数。

猜你喜欢

转载自blog.csdn.net/jishuwenming/article/details/82943335