源码地址: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-享元模式的更多相关文章

  1. 设计模式-创建型模式,python享元模式 、python单例模式(7)

    享元模式(Flyweight Pattern)主要用于减少创建对象的数量,以减少内存占用和提高性能.这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式. 享元模式尝 ...

  2. 大话设计模式Python实现- 享元模式

    享元模式(Flyweight Pattern):运用共享技术有效地支持大量细粒度的对象. 下面是一个享元模式的demo: #!/usr/bin/env python # -*- coding:utf- ...

  3. 浅谈Python设计模式 - 享元模式

    声明:本系列文章主要参考<精通Python设计模式>一书,并且参考一些资料,结合自己的一些看法来总结而来. 享元模式: 享元模式是一种用于解决资源和性能压力时会使用到的设计模式,它的核心思 ...

  4. python设计模式之享元模式

    python设计模式之享元模式 由于对象创建的开销,面向对象的系统可能会面临性能问题.性能问题通常在资源受限的嵌入式系统中出现,比如智能手机和平板电脑.大型复杂系统中也可能会出现同样的问题,因为要在其 ...

  5. [Python设计模式] 第26章 千人千面,内在共享——享元模式

    github地址:https://github.com/cheesezh/python_design_patterns 背景 有6个客户想做产品展示网站,其中3个想做成天猫商城那样的"电商风 ...

  6. 享元模式-Flyweight(Java实现)

    享元模式-Flyweight 享元模式的主要目的是实现对象的共享,即共享池,当系统中对象多的时候可以减少内存的开销,通常与工厂模式一起使用. 本文中的例子如下: 使用享元模式: 小明想看编程技术的书, ...

  7. Matlab享元模式

    享元模式(Flyweight)通过共享技术实现相同或相似对象的重用,可以减少创建对象的数量,以减少内存占用和提高性能.Java String的常量池,python logging,线程池,数据库连接池 ...

  8. Flyweight(享元模式)

    import java.util.Hashtable; /** * 享元模式 * @author TMAC-J * 享元模式一般和工厂模式一起使用,但此处为了更好说明,只用享元模式 * 定义:享元模式 ...

  9. 设计模式(十二)享元模式(Flyweight Pattern)

    一.引言 在软件开发过程,如果我们需要重复使用某个对象的时候,如果我们重复地使用new创建这个对象的话,这样我们在内存就需要多次地去申请内存空间了,这样可能会出现内存使用越来越多的情况,这样的问题是非 ...

  10. 设计模式--享元模式Flyweight(结构型)

    一.享元模式 在一个系统中如果有多个相同的对象,这些对象有部分状态是可以共享的,我们运用共享技术就能有效地支持大量细粒度的对象. 二.例子 举个围棋的例子,围棋的棋盘共有361格,即可放361个棋子. ...

随机推荐

  1. ie6兼容性处理

    IE6下border-bottom不起作用? 在IE6下,border-bottom:1px solid #000 不起作用,但border:1px solid #000 其作用. (经过测试,对于b ...

  2. iOS--各种bug详解

    1.为什么传的参数都对,但是就是请求不下来数据. 答:检查下传的字符串中,是不是有多的空格. 例如: 错误:{"startIndex":"1","en ...

  3. 安装rlwrap方便sqlplus使用

    rlwrap包 这是一个为方便使用SQL*PLUS的技巧,为了能像在DOS命令窗口中那样运行SQL*Plus,使用向上.向下键来跳回之前已经执行过的SQL语句. 需要在Linux上安装rlwrap包, ...

  4. python--使用pickle序列化对象

    pickle序列化对象 如果希望透明地存储 Python 对象,而不丢失其身份和类型等信息,则需要某种形式的对象序列化:它是一个将任意复杂的对象转成对象的文本或二进制表示的过程. 同样,必须能够将对象 ...

  5. MyBatis框架介绍及其实操

    一.基本概念和介绍 数据持久化的概念 数据持久化是将内存中的数据模型转换为存储模型,以及将存储模型转换为内存中的数据模型的统称.例如,文件的存储.数据的读取等都是数据持久化操作.数据模型可以是任何数据 ...

  6. 解决Maven的Could not resolve archetype org.apache.maven.archetypes:maven-archetype-quickstart

    eclipse配置好了Maven,创建maven-archetype-quickstart项目报错如下: Could not resolve archetype org.apache.maven.ar ...

  7. ActiveMQ配置高可用性的方式

    当一个应用被部署于生产环境,灾备计划是非常重要的,以便从网络故障,硬件故障,软件故障或者电源故障中恢复.通过合理的配置ActiveMQ,可以解决上诉问题.最典型的配置方法是运行多个Broker,一旦某 ...

  8. CompoundScope说明

    A class scope adds capabilities to keep track of changes in relatedclass scopes - this allows client ...

  9. 简单聊聊SOA和微服务

    转自:https://juejin.im/post/592f87feb123db0064e5ef7c  (2017-06) 简单聊聊SOA和微服务 架构设计中的朴素主义 前两天和一个朋友聊天,他向我咨 ...

  10. 数据存储之属性列表Plist

    常用的数据存储有属性列表.偏好设置.归档.sqlite.coreData.上一博客了解了沙盒,现在了解下属性列表Plist. 通常通过NSArray.NSDictionary集合类的WriteToFi ...