一、网上咖啡选购平台

假设有一个网上咖啡选购平台,客户可以在该平台上下订单订购咖啡,平台会根据用户位置进行线下配送。假设其咖啡对象构造如下:

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.has_key(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

根据结果可以得知,该模式下三个用户点了两种咖啡,最终的咖啡实例为2,而不是3。

二、享元模式

享元模式定义如下:使用共享对象支持大量细粒度对象。大量细粒度的对象的支持共享,可能会涉及这些对象的两类信息:内部状态信息和外部状态信息。内部状态信息就是可共享出来的信息,它们存储在享元对象内部,不会随着特定环境的改变而改变;外部状态信息就不可共享的信息了。享元模式中只包含内部状态信息,而不应该包含外部状态信息。这点在设计业务架构时,应该有所考虑。

享元模式

三、享元模式的优点和使用场景

优点:

1、减少重复对象,大大节约了系统资源。

使用场景:

1、系统中存在大量的相似对象时,可以选择享元模式提高资源利用率。咖啡订购平台比较小,若假设一个电商平台,每个买家和卖家建立起买卖关系后,买家对象和卖家对象都是占用资源的。如果一个卖家同时与多个买家建立起买卖关系呢?此时享元模式的优势就体现出来了;

2、需要缓冲池的场景中,可以使用享元模式。如进程池,线程池等技术,就可以使用享元模式(事实上,很多的池技术中已经使得了享元模式)。

四、享元模式的缺点

1、享元模式虽然节约了系统资源,但同时也提高了系统的复杂性,尤其当遇到外部状态和内部状态混在一起时,需要先将其进行分离,才可以使用享元模式。否则,会引起逻辑混乱或业务风险;

2、享元模式中需要额外注意线程安全问题。

python 享元模式_Python与设计模式之享元模式相关推荐

  1. python高端写法_python高级篇:使用元类方式实现单例模式详解

    对于编程开发的朋友来说,设计模式应该最为熟悉不过了,如果要谈到哪种设计模式最为简单,也最容易理解,首当其冲的"单例模式"应该不为过了.本文主要讲解在python3中如何使用元类实现 ...

  2. php注册树模式,php基础设计模式大全(注册树模式、工厂模式、单列模式)

    废话不多说了,先给大家介绍注册树模式然后介绍工厂模式最后给大家介绍单列模式,本文写的很详细,一起来学习吧. php注册树模式 什么是注册树模式? 注册树模式当然也叫注册模式,注册器模式.之所以我在这里 ...

  3. java设计模式装饰者模式优点_java设计模式之--装饰者模式

    装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装饰类,用来包装 ...

  4. 设计模式之外观模式php,php设计模式(十五)外观模式

    外观模式又叫门面模式: 现在都是模块化开发了: 开发中很多时候都是在使用各种扩展包: 或者在外观模式中我们叫做子系统: 外观模式的作用就是减少子系统之间的耦合: 降低子系统的使用难度: 我们举个栗子: ...

  5. android 装饰着模式,Android与设计模式——装饰者(Decorator)模式

    在阎宏博士的<JAVA与模式>一书中开头是这样描述装饰(Decorator)模式的: 装饰模式又名包装(Wrapper)模式.装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替 ...

  6. python有几种模式_python的设计模式都有哪些?

    单例模式:Python 的单例模式最好不要借助类(在 Java 中借助类是因为 Java 所有代码都要写在类中),而是通过一个模块来实现.一个模块的模块内全局变量.模块内全局函数,组合起来就是一个单例 ...

  7. 实战python设计模式_Python与设计模式之创建型模式及实战

    用Python学习一下设计模式,如果很枯燥的话,就强行能使用的就用一下.设计模式参考Python与设计模式-途索 1. 单例模式 保证一个类仅有一个实例,并提供一个访问它的全局访问点. import ...

  8. python 生产者和消费者模式_Python爬虫:生产者和消费者模式

    认识生产者和消费者模式 生产者和消费者是多线程中很常见的一个问题.产生数据的模块,我们称之为生产者,而处理数据的模块,就称为消费者.但是单单只有生产者和消费者显然还是不够的,一般来说,我们还有一个缓冲 ...

  9. python 字典 列表 元祖_Python基础之列表、元祖、字典、集合,你都知道吗?附视频...

    前言 Python作为目前最火的编程语言之一,是一门解释型的高级编程语言,特点是简单明确.今天我们来简单介绍一下其中的列表.元祖.字典和集合,希望大家多多讨论. 列表(list) 具有以下特点: 1. ...

最新文章

  1. jquery中this与$(this)的用法区别.
  2. springboot 启动分析【难点】——如何自动扫描 @SpringBootApplication||如何加载自动配置类 @EnableAutoConfiguration||如何加载前端控制器
  3. Java编程思想:擦除的神秘之处
  4. 物料管理的容差范围维护
  5. 天际数见数据质量巡检架构优化
  6. python3高级 之 生成器
  7. mysql 避免重复添加_MySql三种避免重复插入数据的方法
  8. 产品研发过程管理专题——软件测试是提高软件产品质量的必要条件
  9. linux上容器端口映射,MacOS下的docker端口映射
  10. [收集]代码段(Code Snippets)
  11. 狮子鱼社区团购小程序独立版 安装教程及后台设置小程序APPID,微信支付,腾讯地图AppKey
  12. mysql安装版与mysql解压版议论
  13. java与nodejs使用SHA加密获得结果不同解决方法
  14. 您的SATA硬盘运行与“AHCI 模式”还是“IDE 模式”?
  15. PTA---约分最简分式 (10 分)
  16. 关于amd cpu超频 个人心得
  17. shader篇-纹理-遮罩纹理
  18. 几款科学计算显卡对比(GTX Titan X、GTX 980、Tesla K40 K80 及quadro K4200) 科学计算显卡的两个主要性能指标: 1、CUDA compute capabili
  19. 仙剑游戏系列..感想
  20. C语言:银行储蓄系统开发(中级)

热门文章

  1. hua图软件 mac_工具推荐--Mac下画图软件:Omnigraffle
  2. 基于天翼1号2021的5G切片创新应用在广州完成端到端现网验证
  3. SpringSecurity Oauth2 认证授权(二)springboot快速入门与底层介绍
  4. 图片翻译怎么弄?如何把图片翻译成中文?
  5. 程序员的自我修炼(一):打通任督二脉
  6. 调用android邮件程序,Android开发中怎样调用系统Email发送邮件(多种调用方式)
  7. 自学鸿蒙应用开发(3)- 你好,鸿蒙!
  8. 数据结构与算法题目及C++解答
  9. 安卓APP之加固技术
  10. 中小企业进行工业互联网改革的痛点和解决方案