Python与设计模式:单例模式

2020-07-08 00:00:00 模式 设计 实例 全局 老婆

前段时间,有朋友在我的读者群里问了几个关于单例模式的问题。

为了回答他的问题,我整理了单例模式的知识点,正好我也在写设计模式的系列。

上一篇是讲「策略模式」,若你还未阅读,可以点击这里查看:

Mingle Wong:Python与设计模式:策略模式zhuanlan.zhihu.com

本篇做为「设计模式系列」的第二篇,来一起看看「单例模式」。

之前在另一篇公众号文章看到一个挺搞笑的例子:

大意是讲,老婆在中国其实就是一个很形象的单例,你要娶一个老婆需要去民政局注册登记(要对类进行实例化),当你想再娶一个老婆时,这时民政局会说,不行,你已经有一个老婆了,并且它还会告诉你的老婆是谁。

然后有个朋友,还很生趣地评论说

单例模式 允许你讨无数个老婆,但终你会发现你讨来的老婆都是同一个人

玩笑之后,再回到我们的话题,先举几类我们经常见到的例子:

1、大家在解释单例模式时,经常要提到的一个例子是 Windows 的任务管理器。如果我们打开多个任务管理器窗口。显示的内容完全一致,如果在内部是两个一模一样的对象,那就是重复对象,就造成了内存的浪费;相反,如果两个窗口的内容不一致,那就会至少有一个窗口展示的内容是错误的,会给用户造成误解,到底哪个才是当前真实的状态呢?

2、一个项目中多个地方需要读取同一份配置文件,如果每次使用都是导入重新创建实例,读取文件,用完后再销毁,这样做的话,就造成不必要的IO浪费,可以使用单例模式只生成一份配置在内存中。

3、还有一个常见的例子是,一个网站的访问量、在线人数,在项目中是全局(不考虑分布式),在这种情况下,使用单例模式是一种很好的方式。

从上面看来,在系统中确保某个对象的性即一个类只能有一个实例有时是非常重要的。

按照惯例,我们先来用代码实践一下,看看如何用 Python 写单例模式。

这里介绍了三个较为常用的。

  • 使用 __new__
class User:
    _instance = None
    def __new__(cls, *args, **kwargs):
        print('===== 1 ====')
        if not cls._instance:
            print("===== 2 ====")
            cls._instance = super().__new__(cls)
        return cls._instance

    def __init__(self, name):
        print('===== 3 ====')
        self.name = name

相关文章