博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python设计模式之单例模式(二)
阅读量:5734 次
发布时间:2019-06-18

本文共 2351 字,大约阅读时间需要 7 分钟。

上次我们简单了解了一下什么是单例模式,今天我们继续探究。

上次的内容点这

上次们讨论的是GoF的单例设计模式,该模式是指:一个类有且只有一个对象。通常我们需要的是让实例共享一个相同的装态 比如数据库连接。Alex Martelli的建议的是开发人员应该关注状态和行为,而不是同一性,因此它也被称为Monostate(单态)模式。

Monostate单例模式的概念

先说说 MonoState 这个单词的意思,设计模式的名字都是很有意思的,因为为了方便交流、记忆,所以设计模式的命名都对 该模式的意图进行了表述。 Mono 是一个词根,英语中 Mono,Mon 都表示的是 1 的意思, state 意思为 " 状态 " 。 MonoState 的意思就是 " 单一的状态 ",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()

单例模式的缺点

介绍了这么长时间的单例模式,也许你会有疑问,那单例模式有什么缺点呢?

虽然单例模式的效果很好但是依然存在一些问题,因为单例具有全局访问权限,所以可能出现以下问题:

  • 全局变量可能在某个地方被改了但是不知道。(比如之前的那个使用__dict__的例子)。
  • 可能会对同一个对象创建多个引用。由于单例只创建一个对象,因此这种情况下会对一个对象创建对个引用。
  • 所有依赖于全局变量的类都会由于一个类的改变而紧密耦合为全局数据,从而可能在无意中影响另一个类。

到此为止,我们就把单例模式的相关内容介绍完了,后续也许会写关于其他设计模式的相关文章,如果你喜欢的话,转发到朋友圈和小伙儿们一起分享吧。

转载地址:http://vcmwx.baihongyu.com/

你可能感兴趣的文章
bzoj 2282: [Sdoi2011]消防
查看>>
我的友情链接
查看>>
centos5.9使用RPM包搭建lamp平台
查看>>
关于C#面向对象2
查看>>
Javascript String类的属性及方法
查看>>
vim编辑器如何添加或删除多行注释
查看>>
[LeetCode] Merge Intervals
查看>>
iOS开发-按钮的基本使用
查看>>
在QT和SDL搭建的框架中使用OPENGL在SDL窗口上进行绘图
查看>>
REST技术第三步 @BeanParam的使用
查看>>
模板 读入挂!
查看>>
SharePoint 读取 Site Columns 的数据并绑定到DropdownList
查看>>
Python中的对象行为与特殊方法(二)类型检查与抽象基类
查看>>
使用 axios 详解
查看>>
通信基站(dfs回溯,思维)
查看>>
nginx web加密访问
查看>>
iOS - Regex 正则表达式
查看>>
SYS_CONTEXT函数返回IP地址的一些误解
查看>>
第 68 章 Logical Volume Manager (LVM)
查看>>
膝盖中了一箭之康复篇-第八个月暨2月份目标总结
查看>>