python设计模式之单例模式(二)

本文涉及的产品
云数据库 RDS MySQL,集群版 2核4GB 100GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用版 2核4GB 50GB
简介: 上次我们简单了解了一下什么是单例模式,今天我们继续探究。上次的内容点这上次们讨论的是GoF的单例设计模式,该模式是指:一个类有且只有一个对象。通常我们需要的是让实例共享一个相同的装态 比如数据库连接。

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

上次们讨论的是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__)

下面是输出结果

<useNew object at 0x7f78ceb873d0>
<useNew object at 0x7f78ceb87b50>
{'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__的例子)。
  • 可能会对同一个对象创建多个引用。由于单例只创建一个对象,因此这种情况下会对一个对象创建对个引用。
  • 所有依赖于全局变量的类都会由于一个类的改变而紧密耦合为全局数据,从而可能在无意中影响另一个类。

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

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
17天前
|
设计模式 缓存 安全
Java设计模式的单例模式应用场景
Java设计模式的单例模式应用场景
25 4
|
1月前
|
设计模式 SQL 安全
【设计模式】第二篇:单例模式的几种实现And反射对其的破坏
一个普通实例化,一个反射实例化 但是我们如果通过反射的方式进行实例化类,会有什么问题呢? public static void main(String[] args) throws Exception { Lazy1 lazy1 = getLazy1();
22 5
|
2天前
|
设计模式 安全 C++
C++一分钟之-C++中的设计模式:单例模式
【7月更文挑战第13天】单例模式确保类只有一个实例,提供全局访问。C++中的实现涉及线程安全和生命周期管理。基础实现使用静态成员,但在多线程环境下可能导致多个实例。为解决此问题,采用双重检查锁定和`std::mutex`保证安全。使用`std::unique_ptr`管理生命周期,防止析构异常和内存泄漏。理解和正确应用单例模式能提升软件的效率与可维护性。
8 2
|
5天前
|
设计模式 安全 Java
Java面试题:设计模式如单例模式、工厂模式、观察者模式等在多线程环境下线程安全问题,Java内存模型定义了线程如何与内存交互,包括原子性、可见性、有序性,并发框架提供了更高层次的并发任务处理能力
Java面试题:设计模式如单例模式、工厂模式、观察者模式等在多线程环境下线程安全问题,Java内存模型定义了线程如何与内存交互,包括原子性、可见性、有序性,并发框架提供了更高层次的并发任务处理能力
18 1
|
28天前
|
设计模式 存储 算法
Python中的设计模式与最佳实践
【6月更文挑战第12天】```markdown 设计模式是软件开发中的标准解决方案,提升代码复用、可维护性。本文讨论了Python中的设计模式应用,如单例、工厂、观察者、策略、装饰器、原型、建造者、命令、状态、中介者和适配器模式。每个模式都有相应的Python示例,展示如何在实际编程中应用。适配器模式转换接口,外观模式简化复杂系统,两者都增强了代码的兼容性和易用性。设计模式是软件设计的重要工具,帮助解决常见问题,降低耦合度,提高系统灵活性。
32 4
Python中的设计模式与最佳实践
|
10天前
|
设计模式 安全 Java
技术成神之路:设计模式(一)单例模式
【7月更文挑战第3天】技术成神之路:设计模式(一)单例模式
16 1
|
14天前
|
设计模式 JavaScript 前端开发
js设计模式【详解】—— 单例模式
js设计模式【详解】—— 单例模式
7 1
|
22天前
|
设计模式 安全 Java
Java中的单例模式是一种设计模式,它保证一个类只有一个实例,并提供一个全局访问点
Java单例模式确保类仅有一个实例,并提供全局访问点。常见实现包括: - 饿汉式:静态初始化,线程安全。 - 懒汉式:延迟初始化,需同步保证线程安全。 - 双重检查锁定:优化懒汉式,减少同步开销。 - 静态内部类:延迟加载,线程安全。 - 枚举:简洁线程安全,不适用于复杂构造。 - 容器实现:如Spring框架,用于依赖注入。选择依据需求,如延迟加载、线程安全和扩展性。
41 10
|
22天前
|
设计模式 缓存 安全
Java设计模式的单例模式应用场景
Java设计模式的单例模式应用场景
21 8
|
19天前
|
设计模式 SQL 安全
Java设计模式:单例模式之六种实现方式详解(二)
Java设计模式:单例模式之六种实现方式详解(二)

相关实验场景

更多