设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案,这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。所以不管你是新手还是老手,学习设计模式将对你都有莫大的帮助。
但是值得注意的是:设计模式的目的是让代码易维护、易扩展,不能为了模式而模式,因此一个简单的工具脚本是不需要用到任何模式的。
设计模式有很多,例如:工厂模式、原型模式、适配器模式、命令模式等等等等,这篇文章会持续更新。
首先我们先来看看比较常见的 单例模式。
1. 单例模式
单例模式的 python 实现有很多种,这里只介绍一种使用 __new__
的实现。
先来说说什么叫单例模式:
单例模式指确保某个类在整个系统中只存在一个实例的一种设计模式。
单例模式好处简单来说主要有以下两点好处:
- 节约内存
- 使用单例模式可进行同步控制,计数器同步、程序多处读取配置信息这些情景下若只存在一个实例,即可保证一致性。
其实单例模式并不是说我只能为类创建一个实例,而是创建的多个对象都指向一个内存,就只是名字不同而已,这样所做的修改都是同步的。。说到单例模式,不禁想起了心中的那个她,,,比如我说‘女朋友’,或者说‘小宝贝’再或者叫‘小可爱’,都是指她一个人(众人:哎呦)逃。。。
在说单例模式的实现之前,我们先来看一下__new__
方法:因为我们比较熟悉__init__
方法,我们就将他们做一个对比。
__new__
与__init__
的区别:
__new__
:创建实例对象时调用的构造方法,在调用时为对象分配内存等。
__init__
:初始化方法,用于设置实例的相关属性
python创建实例时,会先调用__new__
构造方法,然后使用__init__
进行实例初始化。
所以我们可以通过__new__
来影响实例的创建,从而实现单例。
class S:
instance = None
def __new__(cls, *args, **kwargs):
if S.instance is None:
S.instance = super().__new__(cls)
return S.instance
s1 = S()
print(id(s1))
s2 = S()
print(id(s2))
2788564479168
2788564479168
我们来解释一下上面的代码,如果这个类还没有创建实例,那么就会调用super()
的__new__
方法创建一个实例,并把这实例地址传给instance
,在这里super()
指的是object
类。如果我们又想创建一个新的对象的时候,就直接返回我们第一次创建的对象。这就保证了只有一个实例。如下面的内存分析所示:

2. 观察者模式
观察者模式:又叫发布订阅模式,定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,这个主题对象的状态发生变化时,会通知所有观察者对象,是他们能自动更新自己。这个设计模式非常适用于分布式事件处理系统。
在典型的观察者模式下:
1.发布者类应该包涵如下方法:
- 注册能够接收通知的对象
- 从主对象到注册对象,通知任何变化
- 未注册对象不能够接收任何通知信息
2.订阅者类应该包含如下:
- 发布者会调用一个订购者提供的方法,将任何改变告知注册对象。
3.当一个事件会触发了状态的改变,发表者会调用通知方法
总结:订阅者可以在发布对象中注册或者不注册,如此无论什么事件发生,都会触发发布者通过调用通知方法,去通知订购者。这个通知只会在事件发生的时候,去通知已经注册的订购者。
一个简单的python实现:
# 观察者模式(感觉有点像群发消息)
class Observer:
'''
观察者(也叫订阅者),收到任何信息时更新自己
'''
def __init__(self, name):
self.name = name
def update(self, msg):
"""收到信息后更新自己,这个函数是提供给发布者调用的,所以两个类之间还是有一定的耦合"""
print(self.name, "收到信息: ", msg)
class Subject():
'''
发布者(也可以叫做主题类),每个主题都可以有很多观察者,可以增加和删除观察者,可以发布信息
'''
def __init__(self):
self.observers = []
def add_observer(self, observer):
'''添加订阅者'''
self.observers.append(observer)
def remove_observer(self, observer):
'''移除订阅者'''
self.observers.remove(observer)
def notify(self, msg):
'''发布信息'''
for observer in self.observers:
observer.update(msg)
xiaoming = Observer('xiaoming')
lihua = Observer('lihua') # 订阅者实例
rain = Subject() # 发布者实例
rain.add_observer(xiaoming) # 小明订阅了该主题
rain.add_observer(lihua) # 李华订阅了该主题
rain.notify('下雨啦...') # 发布消息
rain.remove_observer(xiaoming) # 小明退订了该主题(他没有晒衣服)
rain.notify('收衣服啦')
xiaoming 收到信息: 下雨啦...
lihua 收到信息: 下雨啦...
lihua 收到信息: 收衣服啦
在上面的例子中xiaoming退订了消息所以他没有收到收衣服的消息。
网友评论