Python版设计模式: 创建型模式:单例模式和工厂模式家族
一. 单例模式(Singleton)
所谓单例模式,也就是说不管什么时候都要确保只有一个对象实例存在。很多情况下,整个系统中只需要存在一个对象,所有的信息都从这个对象获取,比如系统的配置对象,或者是线程池。这些场景下,就非常适合使用单例模式。
总结起来,就是说不管初始化一个对象多少次,真正干活的对象只会生成一次并且在首次生成。
用Python 实现单例模式的方法有很多,先来看第一种方式。
# !/usr/bin/python3
# -*- coding:utf-8 -*- class singleton(object):
"""
单列模式
""" class _A(object):
"""
真正干活的类,对外隐藏。
""" def __init__(self):
pass def display(self):
""" 返回当前实例的ID,是全局唯一的"""
return id(self) # 类变量,用于存储_A 的实例
_instance = None def __init__(self):
""" 先判断类变量中是否已经保存了_A 的实例,如果没有则创建一个后返回"""
if singleton._instance is None:
singleton._instance = singleton._A() def __getattr__(self, attr):
return getattr(self._instance, attr) if __name__ == "__main__":
# 创建2个实例
s1 = singleton()
s2 = singleton()
print(id(s1), s1.display())
print(id(s2), s2.display())
# !/usr/bin/python3 # -*- coding:utf-8 -*- class singleton(object): """ 单列模式 """ class _A(object): """ 真正干活的类,对外隐藏。 """ def __init__(self): pass def display(self): """ 返回当前实例的ID,是全局唯一的""" return id(self) # 类变量,用于存储_A 的实例 _instance = None def __init__(self): """ 先判断类变量中是否已经保存了_A 的实例,如果没有则创建一个后返回""" if singleton._instance is None: singleton._instance = singleton._A() def __getattr__(self, attr): return getattr(self._instance, attr) if __name__ == "__main__": # 创建2个实例 s1 = singleton() s2 = singleton() print(id(s1), s1.display()) print(id(s2), s2.display())
Output:
1917919737784 1917919737896
1917919738008 1917919737896
以上的单列模式实现中,借助了使用类变量 Singleton._instance 来存储创建的实例,并且保证只会创建一次实例。由于 Python 是一门动态语言,可以在运行时改变类定义。上面的代码中,在首次初始化 Singleton 时,将首次生成类 _A 的实例,并将其存储到 Singleton._instance 中,以后每次初始化 Singleton 时都从 Singleton._instance 获取真正干活的实例,这样就实现了单例模式。
从输出中可以看到,尽管创建了两个不同的实例(实例 ID 不同),但是访问其属性的时候得到的 ID 是一致的。以上代码虽然很好的实现了单例模式,但是在真正的项目开发中这种方式却不够灵活,因为要将真正干活的类内置在单例类中。 我们知道在 Python 中装饰器很好用,那能否将单例类实现成一个装饰器呢?答案是肯定的,下面实现代码。
# !/usr/bin/python3
# -*- coding:utf-8 -*-
import sqlite3
from flask import current_app
from flask import _app_ctx_stack as stack class SQLite3(object):
def __init__(self, app=None):
self.app = app
if app is not None:
self.init_app(app) def init_app(self, app):
"""典型的 Flask 扩展的初始化方式"""
app.config.setdefault('SQLITE3_DATABASE', ':memory:')
app.teardown_appcontext(self.teardown) def connect(self):
"""连接到 sqlite 数据库"""
return sqlite3.connect(current_app.config['SQLITE3_DATABASE']) def teardown(self, exception):
"""关闭 sqlite 链接"""
ctx = stack.top
if hasattr(ctx, 'sqlite3_db'):
ctx.sqlite3_db.close() @property
def connection(self):
"""
单例模式在这里:使用 flask._app_ctx_stack 存放 sqlite 链接,
每次获取数据库链接时都通过 connection 获取
"""
ctx = stack.top
if ctx is not None:
if not hasattr(ctx, 'sqlite3_db'):
ctx.sqlite3_db = self.connect()
return ctx.sqlite3_db
在以上的代码中,在每次使用数据库的时候通过 SQLite3.connection 获取数据库连接就可以了。SQLite3.connection保证了数据库连接只会发生一次,其原理和之前实现单例模式的方式相同,只不过这里存储实例的地方变成 flask._app_ctx_stack了。
通过以上几段代码,可以看到单例模式的实现只需要找一个变量存放创建的实例,然后每次获取实例时,先检查变量中是否已保存实例,如果没有则创建一个实例并将其存放到变量中,以后都从这个变量中获取实例就可以了。单例模式中,只会创建一次实例。
Python版设计模式: 创建型模式:单例模式和工厂模式家族的更多相关文章
- python设计模式---创建型之单例模式
数据结构和算法是基本功, 设计模式是最佳实现. 作为程序员,必须有空了就练一练哈. # coding = utf-8 """ # 经典单例 class Singleton ...
- java设计模式--创建型模式(一)
2016-04-24 10:10:34 创建型模式:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式 注意:工厂模式可以分为三类: 1)简单工厂模式(Simple Factory) 2)工厂 ...
- C#设计模式-创建型模式(转)
一.简单工厂模式 简单工厂模式Simple Factory,又称静态工厂方法模式.它是类的创建模式.是由一个工厂对象决定创建出哪一种产品类的实例,是不同的工厂方法模式的一个特殊实现. 优点: u 模式 ...
- 设计模式(三): FACTORY工厂模式 -- 创建型模式
1.定义 定义一个用于创建对象的接口,让子类决定实例化哪一个类,Factory Method使一个类的实例化延迟到了子类. 2.适用场景 1.第一种情况是对于某个产品,调用者清楚地知道应该使用哪个具体 ...
- Java设计模式(3)——创建型模式之抽象工厂模式(Abstract Factory)
一.概述 抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式.抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体情况下,创建多个产品族中的产品对象. UML图: 其他的过多概念不再 ...
- 设计模式----创建型模式之工厂模式(FactoryPattern)
工厂模式主要分为三种简单工厂模式.工厂方法模式.抽象工厂模式三种.顾名思义,工厂主要是生产产品,作为顾客或者商家,我们不考虑工厂内部是怎么一个流程,我们要的是最终产品.将该种思路放在我们面向对象开发实 ...
- java设计模式 -------- 创建模式 之 抽象工厂模式
本文是自己学习所做笔记,欢迎转载,但请注明出处:http://blog.csdn.net/jesson20121020 工厂方法模式和抽象工厂模式不好区分清楚: 工厂方法模式特点: 1. 一个抽象产品 ...
- python 设计模式之工厂模式 Factory Pattern (简单工厂模式,工厂方法模式,抽象工厂模式)
十一回了趟老家,十一前工作一大堆忙成了狗,十一回来后又积累了一大堆又 忙成了狗,今天刚好抽了一点空开始写工厂方法模式 我看了<Head First 设计模式>P109--P133 这25页 ...
- PHP面向对象-设计模式 单例模式 简单工厂模式 工厂方法模式
1.单例模式 单例模式是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例的特殊类.通过单例模式可以保证系统中一个类只有一个实例.即一个类只有一个对象实例. 要实现每一个类只有一个实例,就需 ...
- [19/04/23-星期二] GOF23_创建型模式(工厂模式、抽象工厂模式)
一.工厂模式(分为:简单工厂模式.工厂方法模式.抽象工厂模式) 实现了创建者和调用者的分离 核心本质:1.实例化对象,用工厂方法代替new操作:2.将选择实现类.创建对象统一管理和控制,从而将调用者跟 ...
随机推荐
- Yii 2.x 日志记录器-类图
- python爬虫的一些心得
爬虫用于从网上得到目标数据,根据需要对其予以利用,加以分析,得到想要的实验成果.现在讲一讲我这两天学到的东西. 第一,爬虫的算法结构,包括以下几个方面: (1)读取网络数据 (2)将获取的数据解析为目 ...
- 关于Linux下转换oracle字符集
前阵子给以同事导oracle数据库,但是发现导入后数据都是乱码,下面是自己解决这个问题的一些小整理. 比如: #su oralce $export ORACLE_SID=orcl $export OR ...
- Django简介和安装
Django 最开源地方就是可以使用强大第三方插件1,Django默认没有提供对象(Object)级别的权限控制,我们可以通过该Django Guardian 扩展来帮助Django实现对象级别的权限 ...
- gitignore 规范
gitignore 应该包含 5 块内容: 当前项目需要忽略的文件 项目性质需要忽略的文件(比如是 nodejs 项目,有些文件就需要忽略) 所有项目都需要忽略的文件(比如日志.临时文件) 操作系统需 ...
- Css3新特性总结之边框与背景(二)
一.条纹背景 利用background为linear-gradient函数实现,linear-gradient取值如下: <angle>:角度,渐变的方向 to left right to ...
- dagride实现模糊查询
一:首行放置搜索元素(可以是easyui中的input.datetimebox.combox等等) 将各个元素的value值获取到存为Json格式(data{a:..,b:..,c:..}),再回车或 ...
- dagger2记录篇
作为一个码农,什么都不用多讲,贴代码 build project build module Application public class App extends Application { pri ...
- Python 环境搭建,开发工具,基本语法
python环境 https://www.python.org/downloads/ 现在pthon有两个版本 一个是3.5系列的 , 一个是2.7系列的.建议用3.5版本的 开发工具 PyCharm ...
- appfuse:Excel导出
1.pom.xml <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi< ...