本文共 2351 字,大约阅读时间需要 7 分钟。
上次我们简单了解了一下什么是单例模式,今天我们继续探究。
上次的内容点这
上次们讨论的是GoF的单例设计模式,该模式是指:一个类有且只有一个对象。通常我们需要的是让实例共享一个相同的装态 比如数据库连接。Alex Martelli的建议的是开发人员应该关注状态和行为,而不是同一性,因此它也被称为Monostate(单态)模式。
先说说 MonoState 这个单词的意思,设计模式的名字都是很有意思的,因为为了方便交流、记忆,所以设计模式的命名都对 该模式的意图进行了表述。 Mono 是一个词根,英语中 Mono,Mon 都表示的是 1 的意思, state 意思为 " 状态 " 。 MonoState 的意思就是 " 单一的状态 ",MonoState 并不限制创建对象的个数,但是它的状态却只有一个状态
我们知道在python中,__dict__是用来存储对象属性的一个字典,其键为属性名,值为属性的值。所以下面我们可以使用dict来存储一个类所有对象的状态。来看下面这个例子:
class useDict: __state={ "name":"cxa"} def __init__(self): self.age=27 self.__dict__=self.__state m=useDict() m1=useDict() m.age=23 print(m) print(m1) print(m.__dict__) print(m1.__dict__)
运行以后输出结果。
<__builtin__.useDict instance at 0x7f78ceacc098> <__builtin__.useDict instance at 0x7f78ceacc128> { 'age': 23, 'name': 'cxa'} { 'age': 23, 'name': 'cxa'}
首先我们看结果 我们发现每次对useDict实例化都会创建一个新的对象,然后我们通过m修改了age属性的值后,m1的age属性值也发生了变化。
除此之外我们还可以使用__new__方法本身来实现。class useNew(object): _state={} def __new__(cls,*args,**kwargs): obj=super(useNew,cls).__new__(cls,*args,**kwargs) obj.__dict__=cls._state return obj a=useNew() a1=useNew() a.x=3 print(a) print(a1) print(a.__dict__) print(a1.__dict__)
下面是输出结果
{ 'x': 3} { 'x': 3}
两种写法的效果是一样的。
元类是一个类的类,这就意味着该类是它的元类的实例。对于已经存在的类来说,当需要创建对象的时候,将调用python的特殊方法__call__,我们可以通过使用元类的__call__方法,来控制一个对象的实例化,具体看下面的例子
一个数据库连接的例子import pymysql class MetaSingleton(type): _inst={} def __call__(cls,*args,**kwargs): if cls not in cls._inst: cls._inst[cls]=super(MetaSingleton,cls).__call__(*args,**kwargs) return cls._inst[cls] class MysqlDb(metaclass=MetaSingleton): connection=None def conn(self): if self.connection is None: self.connection= pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='Aa1234', db='user', charset='utf8mb4') self.cursor=self.connection.cursor() return self.cursor d1=MysqlDb().conn() d2=MysqlDb().conn()
介绍了这么长时间的单例模式,也许你会有疑问,那单例模式有什么缺点呢?
虽然单例模式的效果很好但是依然存在一些问题,因为单例具有全局访问权限,所以可能出现以下问题:到此为止,我们就把单例模式的相关内容介绍完了,后续也许会写关于其他设计模式的相关文章,如果你喜欢的话,转发到朋友圈和小伙儿们一起分享吧。
转载地址:http://vcmwx.baihongyu.com/