python-享元模式
源码地址:https://github.com/weilanhanf/PythonDesignPatterns
说明:
如果一个软件系统在运行时所创建的相同或相似对象数量太多,将导致运行代价过高,带来系统资源浪费、性能下降等问题 如何避免系统中出现大量相同或相似的对象,同时又不影响客户端程序通过面向对象的方式对这些对象进行操作呢。例如在文字编辑软件中,把每个字符当成对象处理,并分配相应的系统空间,但是随着字符串数量的增加将会逐渐耗尽系统资源,有大量细粒度的对象充斥在系统之中,导致系统运行效率低下。解决上述问题就可以使用享元模式——通过共享机制来解决系统资源消耗问题。
享元模式:运用共享技术有效地支持大量细粒度对象的复用。
内部状态(Intrinsic State):存储在享元对象内部并且不会随环境改变而改变的状态,内部状态可以共享(例如:字符的内容)
外部状态(Extrinsic State):随环境改变而改变的、不可以共享的状态。享元对象的外部状态通常由客户端保存,并在享元对象被创建之后,需要使用的时候再传入到享元对象内部。一个外部状态与另一个外部状态之间是相互独立的(例如:字符的颜色和大小)
享元池(Flyweight Pool):存储共享实例对象的地方
原理
(1) 将具有相同内部状态的对象存储在享元池中,享元池中的对象是可以实现共享的
(2) 需要的时候将对象从享元池中取出,即可实现对象的复用
(3) 通过向取出的对象注入不同的外部状态,可以得到一系列相似的对象,而这些对象在内存中实际上只存储一份
享元模式的结构
享元模式包含以下4个角色: Flyweight(抽象享元类) ConcreteFlyweight(具体享元类) UnsharedConcreteFlyweight(非共享具体享元类) FlyweightFactory(享元工厂类)
实例:
#假设有一个网上咖啡选购平台,客户可以在该平台上下订单订购咖啡,平台会根据用户位置进行线下配送。
# 假设其咖啡对象构造如下:
class Coffee:
name = ''
price =0
def __init__(self,name):
self.name = name
self.price = len(name)#在实际业务中,咖啡价格应该是由配置表进行配置,或者调用接口获取等方式得到,此处为说明享元模式,将咖啡价格定为名称长度,只是一种简化
def show(self):
print("Coffee Name:%s Price:%s"%(self.name,self.price)) """
#对应客户顾客类
class Customer:
name=""
def __init__(self,name):
self.name=name
def order(self,coffee_name):
print("%s ordered a cup of coffee:%s"%(self.name,coffee_name))
return Coffee(coffee_name)
""" """
按照一般的处理流程,用户在网上预订咖啡,其代表用户的Customer类中生成一个Coffee类,直到交易流程结束。整个流程是没有问题的。
但是在高并发的情况下,也就是说单位时间内购买咖啡的用户越来越多,生成的咖啡实例就会越来越多,系统资源消耗越来越大
避免重复实例的出现,是节约系统资源的一个突破口。引入咖啡工厂类
"""
class CoffeeFactory():
coffee_dict = {}
def getCoffee(self, name):
if self.coffee_dict.__contains__(name) == False:
self.coffee_dict[name] = Coffee(name)
return self.coffee_dict[name]
def getCoffeeCount(self):
return len(self.coffee_dict) # 咖啡工厂中,getCoffeeCount直接返回当前实例个数。重写后的Customer
class Customer:
coffee_factory=""
name=""
def __init__(self,name,coffee_factory):
self.name=name
self.coffee_factory=coffee_factory
def order(self,coffee_name):
print("%s ordered a cup of coffee:%s"%(self.name,coffee_name))
return self.coffee_factory.getCoffee(coffee_name) #假设业务中短时间内有多人订了咖啡,业务模拟如下
if __name__=="__main__":
coffee_factory=CoffeeFactory()
customer_1=Customer("A Client",coffee_factory)
customer_2=Customer("B Client",coffee_factory)
customer_3=Customer("C Client",coffee_factory)
c1_capp=customer_1.order("cappuccino")
c1_capp.show()
c2_mocha=customer_2.order("mocha")
c2_mocha.show()
c3_capp=customer_3.order("cappuccino")
c3_capp.show()
print("Num of Coffee Instance:%s"%coffee_factory.getCoffeeCount())
打印结果:
A Client ordered a cup of coffee:cappuccino
Coffee Name:cappuccino Price:10
B Client ordered a cup of coffee:mocha
Coffee Name:mocha Price:5
C Client ordered a cup of coffee:cappuccino
Coffee Name:cappuccino Price:10
Num of Coffee Instance:2
模式优点
可以减少内存中对象的数量,使得相同或者相似的对象在内存中只保存一份,从而可以节约系统资源,提高系统性能 外部状态相对独立,而且不会影响其内部状态,从而使得享元对象可以在不同的环境中被共享
模式缺点
使得系统变得复杂,需要分离出内部状态和外部状态,这使得程序的逻辑复杂化 为了使对象可以共享,享元模式需要将享元对象的部分状态外部化,而读取外部状态将使得运行时间变长
模式适用环境
一个系统有大量相同或者相似的对象,造成内存的大量耗费 对象的大部分状态都可以外部化,可以将这些外部状态传入对象中 在使用享元模式时需要维护一个存储享元对象的享元池,而这需要耗费一定的系统资源,因此,在需要多次重复使用享元对象时才值得使用享元模式
参考链接:
https://yq.aliyun.com/articles/70529?spm=a2c4e.11155435.0.0.723038da7MwIMk
python-享元模式的更多相关文章
- 设计模式-创建型模式,python享元模式 、python单例模式(7)
享元模式(Flyweight Pattern)主要用于减少创建对象的数量,以减少内存占用和提高性能.这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式. 享元模式尝 ...
- 大话设计模式Python实现- 享元模式
享元模式(Flyweight Pattern):运用共享技术有效地支持大量细粒度的对象. 下面是一个享元模式的demo: #!/usr/bin/env python # -*- coding:utf- ...
- 浅谈Python设计模式 - 享元模式
声明:本系列文章主要参考<精通Python设计模式>一书,并且参考一些资料,结合自己的一些看法来总结而来. 享元模式: 享元模式是一种用于解决资源和性能压力时会使用到的设计模式,它的核心思 ...
- python设计模式之享元模式
python设计模式之享元模式 由于对象创建的开销,面向对象的系统可能会面临性能问题.性能问题通常在资源受限的嵌入式系统中出现,比如智能手机和平板电脑.大型复杂系统中也可能会出现同样的问题,因为要在其 ...
- [Python设计模式] 第26章 千人千面,内在共享——享元模式
github地址:https://github.com/cheesezh/python_design_patterns 背景 有6个客户想做产品展示网站,其中3个想做成天猫商城那样的"电商风 ...
- 享元模式-Flyweight(Java实现)
享元模式-Flyweight 享元模式的主要目的是实现对象的共享,即共享池,当系统中对象多的时候可以减少内存的开销,通常与工厂模式一起使用. 本文中的例子如下: 使用享元模式: 小明想看编程技术的书, ...
- Matlab享元模式
享元模式(Flyweight)通过共享技术实现相同或相似对象的重用,可以减少创建对象的数量,以减少内存占用和提高性能.Java String的常量池,python logging,线程池,数据库连接池 ...
- Flyweight(享元模式)
import java.util.Hashtable; /** * 享元模式 * @author TMAC-J * 享元模式一般和工厂模式一起使用,但此处为了更好说明,只用享元模式 * 定义:享元模式 ...
- 设计模式(十二)享元模式(Flyweight Pattern)
一.引言 在软件开发过程,如果我们需要重复使用某个对象的时候,如果我们重复地使用new创建这个对象的话,这样我们在内存就需要多次地去申请内存空间了,这样可能会出现内存使用越来越多的情况,这样的问题是非 ...
- 设计模式--享元模式Flyweight(结构型)
一.享元模式 在一个系统中如果有多个相同的对象,这些对象有部分状态是可以共享的,我们运用共享技术就能有效地支持大量细粒度的对象. 二.例子 举个围棋的例子,围棋的棋盘共有361格,即可放361个棋子. ...
随机推荐
- InfluxDB概念和基本操作
InfluxDB基本概念 数据格式 在 InfluxDB 中,我们可以粗略的将要存入的一条数据看作一个虚拟的 key 和其对应的 value(field value).格式如下: cpu_usage, ...
- Lucene使用案例
Lucene是apache软件基金会4 jakarta项目组的一个子项目,是一个开放源代码的全文检索引擎工具包,但它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引 ...
- Swift5 语言参考(三) 类型
在Swift中,有两种类型:命名类型和复合类型.一个名为类型是当它的定义可以给出一个特定名称的类型.命名类型包括类,结构,枚举和协议.例如,名为的用户定义类的实例MyClass具有该类型MyClass ...
- 设置Jmeter默认为中文, 就是这么简单!
Jmeter默认加载的全英文,想要看的更加明白,想到的就是汉化了. Jmeter汉化真的非常简单,意料之外的简单,只需要到配置文件 jmeter.properties ,将里面的 “#language ...
- 安装SVN并进行汉化的详细步骤
安装SVN并进行汉化的详细步骤 SAE提供了不同的代码部署方式,可以分为两类:一是通过SVN客户端部署,这是SAE推荐的代码部署方法.另一个是通过非SVN客户端部署,即在线代码在线编辑器和推荐应用安装 ...
- github 最新项目快报
http://www.open-open.com/github/view/github2016-10-17.html
- ActiveMQ配置高可用性的方式
当一个应用被部署于生产环境,灾备计划是非常重要的,以便从网络故障,硬件故障,软件故障或者电源故障中恢复.通过合理的配置ActiveMQ,可以解决上诉问题.最典型的配置方法是运行多个Broker,一旦某 ...
- gridvew使用技巧2
GridVew1_RowDataBindGridView1.DataKeys[e.Row.RowIndex].Values[].ToString(); foreach (GridViewRow t i ...
- vue实现短信验证码登录
无论是移动端还是pc端登录或者注册界面都会见到手机验证码登录这个功能,输入手机号,得到验证码,最后先服务器发送请求,保存登录的信息,一个必不可少的功能 思路 1,先判断手机号和验证是否为空, 2,点击 ...
- SVN Hooks的介绍及使用
阅读此篇文章你可以: 对SVN Hooks有一定的了解 获取两个最常用的SVN Hooks案例 SVN hooks介绍 Hooks 钩子,主要实现的功能就是在特定事件发生之前或者之后自动执行事先定义好 ...