Python:设计模式之单例模式

简介: Python:设计模式之单例模式

单例模式:

1、确保类有且只有一个对象被创建

2、为对象提供一个全局访问点

3、控制共享资源的并行访问


实现单例最简单的方式:

使构造函数私有化,并创建一个静态方法来完成对象初始化


使用场景:

一个类要求只有一个实例对象


单例模式的缺点

1、全局变量可能被误修改

2、对同一个对象创建多个引用

3、所有依赖于全局变量的类都会由于一个类的改变而紧密耦合为全局数据,从而可能在无意中影响另一个类


一、经典的单例模式

只允许Singleton类生成一个实例


# -*- coding: utf-8 -*-
class Singleton(object):
    def __new__(cls):
        if not hasattr(cls, "_instance"):
            cls._instance = super(Singleton, cls).__new__(cls)
        return cls._instance
if __name__ == '__main__':
    s1 = Singleton()
    s2 = Singleton()
    print(s1)
    print(s2)
    print(s1 == s2)
    print(s1 is s2)
"""
<__main__.Singleton object at 0x1021d58d0>
<__main__.Singleton object at 0x1021d58d0>
True
True
"""

二、懒汉式实例化

实际对象创建发生在 get_instance()


# -*- coding: utf-8 -*-
class Singleton(object):
    __instance = None
    def __init__(self):
        if not Singleton.__instance:
            print("create...")
        else:
            print("already exist...")
    @classmethod
    def get_instance(cls):
        if not cls.__instance:
            cls.__instance = Singleton()
        return cls.__instance
if __name__ == '__main__':
    s1 = Singleton.get_instance()  # 实例化
    s2 = Singleton.get_instance()  # 已存在,不会实例化
    print(s1)
    print(s2)
    print(s1 == s2)
    print(s1 is s2)
"""
create...
<__main__.Singleton object at 0x101ad5860>
<__main__.Singleton object at 0x101ad5860>
True
True
"""

三、单态模式 Monostate

所有对象共享相同的状态


# -*- coding: utf-8 -*-
class Borg(object):
    __data = {"age": 23}
    def __init__(self):
        self.__dict__ = self.__data
if __name__ == '__main__':
    b1 = Borg()
    b2 = Borg()
    # b1 和 b2是不同的对象,共享了相同的属性
    print(b1)
    print(b2)
    # 修改b1对象, b2对象的属性也变化了
    b1.name = "Tom"
    print(b1.__dict__)
    print(b2.__dict__)
"""
<__main__.Borg object at 0x102345f60>
<__main__.Borg object at 0x1023452e8>
{'age': 23, 'name': 'Tom'}
{'age': 23, 'name': 'Tom'}
"""

四、基于元类的单例

元类控制类的实例化


# -*- coding: utf-8 -*-
class MetaSingleton(type):
    _instances = {}
    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super(MetaSingleton, cls).__call__(*args, **kwargs)
        return cls._instances[cls]
class Logger(metaclass=MetaSingleton):
    pass
if __name__ == '__main__':
    logger1 = Logger()
    logger2 = Logger()
    print(logger1)
    print(logger2)
"""
<__main__.Logger object at 0x1013658d0>
<__main__.Logger object at 0x1013658d0>
"""

五、单例模式应用一

对数据库进行同步操作


# -*- coding: utf-8 -*-
class MetaSingleton(type):
    _instances = {}
    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super(MetaSingleton, cls).__call__(*args, **kwargs)
        return cls._instances[cls]
import sqlite3
class Database(metaclass=MetaSingleton):
    connection = None
    def __init__(self, db_url):
        self.db_url = db_url
    def get_cursor(self):
        if self.connection is None:
            self.connection = sqlite3.connect(self.db_url)
            self.cursor = self.connection.cursor()
        return self.cursor
if __name__ == '__main__':
    db_url = "db.sqlite3"
    cursor1 = Database(db_url).get_cursor()
    cursor2 = Database(db_url).get_cursor()
    print(cursor1)
    print(cursor2)
"""
<sqlite3.Cursor object at 0x101b4c490>
<sqlite3.Cursor object at 0x101b4c490>
"""

六、单例模式应用二

监控服务器,共享服务器数据


# -*- coding: utf-8 -*-
class HealthCheck(object):
    _instance = None
    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super(HealthCheck, cls).__new__(cls, *args, **kwargs)
        return cls._instance
    def __init__(self):
        self.servers = []
    def add_server(self, server):
        self.servers.append(server)
    def pop_server(self):
        return self.servers.pop()
    def show_server(self):
        print("*" * 10)
        for server in self.servers:
            print(server)
        print("*" * 10)
if __name__ == '__main__':
    h1 = HealthCheck()
    h2 = HealthCheck()
    h1.add_server("server1")
    h1.add_server("server2")
    h1.add_server("server3")
    h2.pop_server()
    h2.show_server()
    """
    **********
    server1
    server2
    **********
    """

总结

1、当要求一个类只有一个对象时,就可以使用单例模式

2、经典单例模式,允许多次实例化,但返回同一个对象

3、Borg或Monostate单态模式允许创建共享相同状态的多个对象

4、单例模式可应用于多个服务间,实现一致的数据库操作

相关文章
|
5月前
|
设计模式 SQL 人工智能
Python设计模式:从代码复用到系统架构的实践指南
本文以Python为实现语言,深入解析23种经典设计模式的核心思想与实战技巧。通过真实项目案例,展示设计模式在软件开发中的结构化思维价值,涵盖创建型、结构型、行为型三大类别,并结合Python动态语言特性,探讨模式的最佳应用场景与实现方式,帮助开发者写出更清晰、易维护的高质量代码。
208 1
|
5月前
|
设计模式 人工智能 算法
Python设计模式:从代码复用到系统架构的实践指南
本文探讨了电商系统中因支付方式扩展导致代码臃肿的问题,引出设计模式作为解决方案。通过工厂模式、策略模式、单例模式等经典设计,实现代码解耦与系统扩展性提升。结合Python语言特性,展示了模块化、装饰器、适配器等模式的实战应用,并延伸至AI时代的设计创新,帮助开发者构建高内聚、低耦合、易维护的软件系统。
324 0
|
7月前
|
设计模式 缓存 安全
【设计模式】【创建型模式】单例模式(Singleton)
一、入门 什么是单例模式? 单例模式是一种设计模式,确保一个类只有一个实例,并提供一个全局访问点。它常用于需要全局唯一对象的场景,如配置管理、连接池等。 为什么要单例模式? 节省资源 场景:某些对象创
256 15
|
5月前
|
设计模式 人工智能 算法
python 设计模式
工厂模式是一种创建型设计模式,通过定义创建对象的接口,将实例化延迟到子类,实现对象创建与使用的分离。它包括简单工厂模式、工厂方法模式和抽象工厂模式,适用于不同复杂度的对象创建场景,提高系统灵活性和可扩展性。
100 4
|
9月前
|
设计模式 机器学习/深度学习 前端开发
Python 高级编程与实战:深入理解设计模式与软件架构
本文深入探讨了Python中的设计模式与软件架构,涵盖单例、工厂、观察者模式及MVC、微服务架构,并通过实战项目如插件系统和Web应用帮助读者掌握这些技术。文章提供了代码示例,便于理解和实践。最后推荐了进一步学习的资源,助力提升Python编程技能。
|
9月前
|
设计模式 安全 Java
设计模式:单例模式
单例模式是一种创建型设计模式,确保一个类只有一个实例,并提供全局访问点。它通过私有化构造函数、自行创建实例和静态方法(如`getInstance()`)实现。适用于数据库连接池、日志管理器等需要全局唯一对象的场景。常见的实现方式包括饿汉式、懒汉式、双重检查锁、静态内部类和枚举。线程安全问题可通过`synchronized`或双重检查锁解决,同时需防止反射和序列化破坏单例。优点是避免资源浪费,缺点是可能增加代码耦合度和测试难度。实际开发中应优先选择枚举或静态内部类,避免滥用单例,并结合依赖注入框架优化使用。
|
8月前
|
设计模式 存储 安全
设计模式-单例模式练习
单例模式是Java设计模式中的重要概念,确保一个类只有一个实例并提供全局访问点。本文详解单例模式的核心思想、实现方式及线程安全问题,包括基础实现(双重检查锁)、懒汉式与饿汉式对比,以及枚举实现的优势。通过代码示例和类图,深入探讨不同场景下的单例应用,如线程安全、防止反射攻击和序列化破坏等,展示枚举实现的简洁与可靠性。
143 0
|
10月前
|
设计模式 存储 安全
设计模式2:单例模式
单例模式是一种创建型模式,确保一个类只有一个实例,并提供全局访问点。分为懒汉式和饿汉式: - **懒汉式**:延迟加载,首次调用时创建实例,线程安全通过双重检查锁(double check locking)实现,使用`volatile`防止指令重排序。 - **饿汉式**:类加载时即创建实例,线程安全但可能浪费内存。 示例代码展示了如何使用Java实现这两种模式。
234 4
|
设计模式 开发者 Python
Python编程中的设计模式:工厂方法模式###
本文深入浅出地探讨了Python编程中的一种重要设计模式——工厂方法模式。通过具体案例和代码示例,我们将了解工厂方法模式的定义、应用场景、实现步骤以及其优势与潜在缺点。无论你是Python新手还是有经验的开发者,都能从本文中获得关于如何在实际项目中有效应用工厂方法模式的启发。 ###
|
11月前
|
存储 IDE Shell
Python单例模式中的问题
本文介绍了Python中几种常见的单例模式实现方式及其优缺点。首先,装饰器形式的单例模式通过包装类为函数来确保单例,但存在无法使用`isinstance()`和联合类型符号`|`的问题。其次,元类形式的单例模式通过自定义元类来实现单例,解决了装饰器模式的缺陷,但在继承同样使用元类的类时可能会遇到冲突。最后,模块级单例模式和类属性单例模式虽然简单直接,但不具备通用性,需要针对每种类型单独实现。总结来看,元类形式的单例模式相对较为理想,尽管可能需要打补丁,但对用户透明且不影响客户端代码。作者:三叔木卯,来源:稀土掘金。
148 12

热门文章

最新文章

推荐镜像

更多