11-享元(Flyweight)模式Ruby实现
Posted 架构设计模式
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了11-享元(Flyweight)模式Ruby实现相关的知识,希望对你有一定的参考价值。
摘要:本文用一个实例场景描述Gof 23设计模式中的享元模式,并用Ruby程序代码给予实现,同时也给出实现代码的UML模型。
关键字:Gof 23 设计模式 享元模式 Ruby
Flyweight Patternbased on Ruby
REN gang
Abstract:This paper gives a scene example to describe theuse of Flyweight Pattern of Gof 23 Design Pattern, and achieves the example by Ruby,at the same time, gives the UML model of realization of the example.
Key word: Gof 23 Design Pattern Flyweight Pattern Ruby
1. 标准定义
享元(Flyweight)模式标准定义:运用共享技术有效地支持大量细粒度的对象。
2. 分析和说明
享元(Flyweight)模式属于结构型设计模式。享元模式以共享的方式高效的支持大量的细粒度对象。享元模式能做到共享的关键是区分内蕴状态和外蕴状态。内蕴状态存储在享元内部,不会随环境的改变而有所不同。外蕴状态是随环境的改变而改变的。外蕴状态不能影响内蕴状态,它们是相互独立的。将可以共享的状态和不可以共享的状态从常规类中区分开来,将不可以共享的状态从类里剔除出去。客户端不可以直接创建被共享的对象,而应当使用一个工厂对象负责创建被共享的对象。享元模式大幅度的降低内存中对象的数量。
Flyweight结构如图1所示。其角色包括抽象享元(Flyweight)角色、具体享元(Concrete Flyweight)角色、复合享元(Unsharable Flyweight)角色和享元工厂(Flyweight Factory)角色等。
图1享元模式结构
抽象享元(Flyweight)角色:此角色是所有具体享元类的超类,为这些规定出需要实现的公共接口。那些需要外蕴状态(External State)的操作可以通过方法的参数传入。抽象享元的接口使得享元变得可能,但是并不强制子类实行共享,因此并非所有的享元对象都是可以共享的。
具体享元(Concrete Flyweight)角色:实现抽象享元角色所规定的接口。如果有内蕴状态的话,必须负责为内蕴状态提供存储空间。享元对象的内蕴状态必须与对象所处的周围环境无关,从而使得享元对象可以在系统内共享。有时候具体享元角色又叫做单纯具体享元角色,因为复合享元角色是由单纯具体享元角色通过复合而成的。
复合享元(Unsharable Flyweight)角色:复合享元角色所代表的对象是不可以共享的,但是一个复合享元对象可以分解成为多个本身是单纯享元对象的组合。复合享元角色又称作不可共享的享元对象。
享元工厂(Flyweight Factory)角色:本角色负责创建和管理享元角色。本角色必须保证享元对象可以被系统适当地共享。当一个客户端对象请求一个享元对象的时候,享元工厂角色需要检查系统中是否已经有一个符合要求的享元对象,如果已经有了,享元工厂角色就应当提供这个已有的享元对象;如果系统中没有一个适当的享元对象的话,享元工厂角色就应当创建一个新的合适的享元对象。
客户端(Client)角色:本角色还需要自行存储所有享元对象的外蕴状态。
3 应用场景举例
公司里要有一些资料共享。这些资料包括技术文档、财务文档、行政文档、管理文档、日常文档等。享元对象的外蕴状态就是技术、财务、行政、管理、日常等类别。
在这里可以理解Document(文档类)抽象类就是抽象享元(Flyweight)角色。TechnicalDocument类(技术文档)、FinancialDocument类(财务文档)、AdministrativeDcoment类(行政文档)是具体享元(Concrete Flyweight)角色:DocumentRepository类(资料库)就是享元工厂(Flyweight Factory)角色。其实结构类图如图2所示。TechnicalDocument类、FinancialDocument类和AdministrativeDcoment类都继承Document抽象类。Document抽象类与DocumentRepository类是聚合关系,即DocumentRepository包容多个Document。
图2 享元模式类图
3.Ruby的实现程序代码
Ruby程序实现主要包括Document抽象类,DocumentRepository类,AdministrativeDcoment类,FinancialDocument类和TechnicalDocument类等5个类。其关系如图2所示。下面分别列出这5个类的程序代码,最后列出测试代码并显示输出结果。
程序代码清单
#!/structuralpatterns/flyweight
class Document def readDocument end end
class AdministrativeDcoment < Document
def readDocument puts "请阅读行政文档。" end end
class FinancialDocument < Document
def readDocument puts "请阅读财务文档。" end end
class TechnicalDocument < Document
def readDocument puts "请阅读技术文档。" end end
class DocumentRepository
def initialize() @DocumentMap = Hash.new end
def initizeRepository @DocumentMap["行政文档"] = AdministrativeDcoment.new @DocumentMap["技术文档"] = TechnicalDocument.new @DocumentMap["财务文档"] = FinancialDocument.new end
def getDocument(docType) @object = nil if @DocumentMap.key?(docType) @object = @DocumentMap[docType] else puts "没有此类文档。" @object end end end
# ————————main主程序应用————————
repository = DocumentRepository.new repository.initizeRepository
doc1 = repository.getDocument("行政文档") if doc1 != nil then doc1.readDocument end
doc2 = repository.getDocument("技术文档") if doc2 != nil then doc2.readDocument end
doc3 = repository.getDocument("财务文档") if doc3 != nil then doc3.readDocument end
BEGIN { puts "———这是flyweight的输出开始———" }
END { puts "———这是flyweight的输出结束———" }
|
享元模式测试类输出结果如下所示:
———这是flyweight的输出开始——— 请阅读行政文档。 请阅读技术文档。 请阅读财务文档。 ———这是flyweight的输出结束——— |
参考文献
[1] E.Gamma, R.Helm, R.Johnson, andVlissides. Design Patterns Elements of Reusable Object Oriented Software. Addison-Wesley,1995
[2] E.Gamma, R.Helm, R.Johnson, andVlissides.著,李英军等译,设计模式:可复用面向对象软件的基础,北京:机械工业出版社.2000.9.
[3] (日)高桥征义,(日)后藤裕藏 著,何文斯 译,Ruby基础教程(第4版),北京:人民邮电出版社.2014.09
[4] 许勇 等编著,Ruby on Rails 程序设计 深入剖析与范例应用,北京:清华大学出版社.2013.07
[5] (美)梅茨 著,张雪平,彭晓东译,面向对象设计实践指南:Ruby语言描述,北京:人民邮电出版社.2014.01
[6] Ruby官方网站:www.ruby-lang.org.
[7] Ruby教程 http://www.runoob.com/ruby/ruby-tutorial.html.
以上是关于11-享元(Flyweight)模式Ruby实现的主要内容,如果未能解决你的问题,请参考以下文章