#写在前面

这个设计模式理解起来很容易。百度百科上说的有点绕口。

#享元模式的定义

运用共享技术来有効地支持大量细粒度对象的复用。

它通过共享已经存在的对橡大幅度减少需要创建的对象数量、避免大量相似类的开销,从而提高系统资源的利用率。

#优点

相同对象只要保存一份,这降低了系统中对象的数量,从而降低了系统中细粒度对象给内存带来的压力。

#缺点

1.为了共享对象,需要将不能共享的状态外部化,会增加程序的复杂性

2.对享元模式的外部状态会增长运行时间

#享元模式中存在的两种状态

1.内部状态,不会随着环境的改变而改变,可共享的部分

2.外部状态,会随着环境的改变而改变,是不可共享的部分.

享元模式就是要区分这两种状态,并将外部状态外部化。

#应用实例

1.java中的String,如果有则返回,如果没有就创建一个字符串保存在字符串缓冲池里面。

2.数据库的数据池

#应用场景

1.系统中存在大量的相似对象

2.细粒度的对象都具备较接近的外部状态,而且内部状态与环境无关,也就是说对象没有特定身份

3.需要缓冲池的场景

#享元模式的主要角色

抽象享元角色(Flyweight):是所有的具体享元类的基类,为具体享元规范需要实现的公共接口,非享元的外部状态以参数的形式通过方法传入。

具体享元(Concrete Flyweight)角色:实现抽象享元角色中所规定的接口。

非享元(Unsharable Flyweight)角色:是不可以共享的外部状态,它以参数的形式注入具体享元的相关方法中。

享元工厂(Flyweight Factory)角色:负责创建和管理享元角色。当客户对象请求一个享元对象时,享元工厂检査系统中是否存在符合要求的享元对象,如果存在则提供给客户;如果不存在的话,则创建一个新的享元对象。

#举例说明什么是具体享元角色和非具体享元角色

举下围棋的例子

棋子:是抽象享元角色

白子:具体享元角色

黑子:具体享元角色

围棋工厂:是享元工厂角色

下棋的位置:非具体享元角色

#享元模式的结构图

#举个例子1

class Flyweight(object):

def __init__(self, str):

self.str = str

def display(self):

print("show the string: " + self.str)

class FlyweightFactory(object):

def __init__(self):

self.flyweights = {}

def getFlyweight(self, obj):

flyweight = self.flyweights.get(obj)

if flyweight == None:

flyweight = Flyweight(str(obj))

self.flyweights[obj] = flyweight

return flyweight

def showFlyweights(self):

for i in self.flyweights:

self.flyweights[i].display()

print(len(self.flyweights))

if __name__ == "__main__":

flyweightfactory = FlyweightFactory()

fly1 = flyweightfactory.getFlyweight("hello1")

fly2 = flyweightfactory.getFlyweight("hello1")

fly3 = flyweightfactory.getFlyweight("hello2")

fly4 = flyweightfactory.getFlyweight("hello2")

fly5 = flyweightfactory.getFlyweight("hello3")

flyweightfactory.showFlyweights()

out:

show the string: hello2

show the string: hello1

show the string: hello3

3

#举个例子2

import random

from enum import Enum

TreeType=Enum("TreeType",("apple","cherry","peach"))

class Tree:

pool={} #数目池

def __new__(cls,tree_type):

obj=cls.pool.get(tree_type,None) #获取树苗类型

if not obj: #如果之前没有创建过

obj=object.__new__(cls) #开辟一块内存空间

cls.pool[tree_type]=obj #在池子里添加这个树苗类型和他的内存空间

obj.tree_type=tree_type #内存空间里添加树苗类型

return obj #返回树苗类型空间

def render(self,age,x,y):

print("创建了一个新的种类{}的树苗,他的年龄是{},地点位于{},{}".format(

self.tree_type,age,x,y

))

def main():

rnd=random.Random()

age_min,age_max=1,30 #树苗年龄在1-30之间随机

min_point,max_point=0,100 #随机地点

tree_counter=0

print(rnd)

for _ in range(10): #10个苹果树

t1=Tree(TreeType['apple'])

t1.render(rnd.randint(age_min,age_max),

rnd.randint(min_point,max_point),

rnd.randint(min_point, max_point))

tree_counter+=1

for _ in range(3): #3个cherry树

t2=Tree(TreeType['cherry'])

t2.render(rnd.randint(age_min,age_max),

rnd.randint(min_point,max_point),

rnd.randint(min_point, max_point))

tree_counter+=1

for _ in range(5): #5个peach树

t3=Tree(TreeType['peach'])

t3.render(rnd.randint(age_min,age_max),

rnd.randint(min_point,max_point),

rnd.randint(min_point, max_point))

tree_counter+=1

print("树苗创建了{}个".format(tree_counter))

print("树苗完成创建:{}种类".format(len(Tree.pool)))

t4=Tree(TreeType['cherry'])

t5 = Tree(TreeType['cherry'])

t6=Tree(TreeType['apple'])

print("{}----{}是同一颗树吗? {}".format(id(t4),id(t5),id(t4)==id(t5)))

print("{}----{}是同一颗树吗? {}".format(id(t5), id(t6), id(t6) == id(t5)))

if __name__ == '__main__':

main()

参考

http://c.biancheng.net/view/1371.html(下围棋)

https://www.runoob.com/design-pattern/flyweight-pattern.html

https://www.cnblogs.com/hujingnb/p/10171607.html

http://dongweiming.github.io/python-flyweight.html

https://blog.csdn.net/weixin_42557907/article/details/84204040(例子2出处)

https://blog.csdn.net/u013346751/article/details/78426104(例子1出处)

python 享元模式_python 设计模式之享元(Flyweight)模式相关推荐

  1. python中的装饰器、装饰器模式_python 设计模式之装饰器模式 Decorator Pattern

    #写在前面 已经有一个礼拜多没写博客了,因为沉醉在了<妙味>这部小说里,里面讲的是一个厨师苏秒的故事.现实中大部分人不会有她的天分.我喜欢她的性格:总是想着去解决问题,好像从来没有怨天尤人 ...

  2. python 装饰器 继承_Python设计模式之装饰器模式

    装饰器模式 无论何时我们想对一个对象添加额外的功能,都有下面这些不同的可选方法. 如果合理,可以直接将功能添加到对象所属的类(例如,添加一个新的方法) 使用组合 使用继承 注意,本文中的Decorat ...

  3. 从java多态到策略模式_设计模式中的多态——策略模式详解

    2. 策略模式详解 2.1 策略模式定义 策略模式定义了一系列算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式让算法独立于使用它的客户端而独立的变化. 可以使用多态进行类比来理解策略模 ...

  4. python抽象工厂模式_Python设计模式之抽象工厂模式

    Python设计模式之抽象工厂模式 这篇文章主要为大家详细介绍了Python设计模式之抽象工厂模式,感兴趣的小伙伴们可以参考一下 python面向对象编程入门,我们需要不断学习进步 "&qu ...

  5. python的out模式_Python设计模式之状态模式

    状态模式 面向对象编程着力于在对象交互时改变它们的状态.在很多问题中,有限状态机(通常名为状态机)是一个非常方便的状态转换建模(并在必要时以数学方式形式化)工具.首先,什么是状态机?状态机是一个抽象机 ...

  6. python 命令模式_python 设计模式之命令模式

    命令模式介绍: 在面向对象编程中,命令模式是概括所有方法信息的设计模式. 此模式对象包涵方法名,及其相关参数值. 命令模式是一个分类的观察者设计模式,在命令模式下,对象被概括为一个命令表单,此表单包涵 ...

  7. python 设计模式 原型模式_python设计模式–原型模式

    套用书里的一个例子,两年前你写了一本书,现在你要在此书 的基础上修订一版,你会在新版本中加入一些最新的元素,但是与之前的书相比你有很多的地方其实是不用修改的,但是你又不想直接把上一版拿过来改,万一改的 ...

  8. python 命令模式_python设计模式(十六):命令模式-阿里云开发者社区

    "行为请求者"与"行为实现者"通常呈现一种"紧耦合".但在某些场合,比如要对行为进行"记录.撤销/重做.事务"等处理,这 ...

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

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

最新文章

  1. 陈天奇:我是如何从机器学习小白一步一步成长为你们心目中的大神的
  2. codeforces-73C. LionAge II
  3. Elasticsearch的Scroll操作
  4. linux有没有递归函数,递归函数
  5. 哪些名人在学python_盘点计算机界十位顶级人物,看看你认识几个?
  6. 矢量合成和分解的法则_专题14 运动的合成与分解
  7. C#LeetCode刷题之#40-组合总和 II(Combination Sum II)
  8. avl树 php,PHP实现平衡二叉树(AVL树)
  9. 深度学习的1000+篇文章总结
  10. 四阶龙格库塔法求解微分方程【MATLAB】
  11. HTML制作简单的个人简历网页
  12. 亲戚关系关系算法java程序_亲戚换算(亲戚称谓计算器)
  13. PC - 电脑应该多久清洁一次?
  14. 外卖 webpp2---hesdar组件
  15. outlook邮箱邮件大小限制_Office Outlook 2010、2013附件大小超过了允许的范围限制三种解决方法图解...
  16. Monokai主题详细配色
  17. 如何学习stm32,怎么学习stm32,不是仅仅看教程,照着写复制代码
  18. 源码天空java新闻_Java UpdateRequest类代码示例
  19. Comet OJ 夏季欢乐赛 完全k叉树
  20. 纳维斯托克方程_托克如何检验其网络安全性

热门文章

  1. kali linux 升级命令_作为高级Java,你应该了解的Linux知识
  2. 树莓派安装Ubuntu MATE及ROS系统
  3. 【AVR ASF4库函数学习笔记】一、使用Microchip Studio图形化配置工程
  4. sql loader 参数详解
  5. Linux 内核打印级别
  6. [react-router] 在history模式中push和replace有什么区别?
  7. react学习(38)----react是什么
  8. 前端学习(3164):react-hello-react之添加todoList
  9. [html] HTML5的video怎么取消自动播放?
  10. 工作381-兼容移动端头部