11-享元模式Quarkus实现

摘要:本文用一个实例场景描述Gof 23设计模式中的享元模式,并用Quarkus框架代码给予实现,同时也给出实现代码的UML模型。
关键字:Gof 23 设计模式 享元模式 Quarkus

1 基础知识
1.1 标准定义
享元(Flyweight)模式标准定义:运用共享技术有效地支持大量细粒度的对象。
1.2 分析和说明
享元(Flyweight)模式属于结构型设计模式。享元模式以共享的方式高效的支持大量的细粒度对象。享元模式能做到共享的关键是区分内蕴状态和外蕴状态。内蕴状态存储在享元内部,不会随环境的改变而有所不同。外蕴状态是随环境的改变而改变的。外蕴状态不能影响内蕴状态,它们是相互独立的。将可以共享的状态和不可以共享的状态从常规类中区分开来,将不可以共享的状态从类里剔除出去。客户端不可以直接创建被共享的对象,而应当使用一个工厂对象负责创建被共享的对象。享元模式大幅度的降低内存中对象的数量。
Flyweight结构如图1所示。其角色包括抽象享元(Flyweight)角色、具体享元(Concrete Flyweight)角色、复合享元(Unsharable Flyweight)角色和享元工厂(Flyweight Factory)角色等。 在这里插入图片描述
图1享元模式结构
 抽象享元(Flyweight)角色:此角色是所有具体享元类的超类,为这些规定出需要实现的公共接口。那些需要外蕴状态(External State)的操作可以通过方法的参数传入。抽象享元的接口使得享元变得可能,但是并不强制子类实行共享,因此并非所有的享元对象都是可以共享的。
 具体享元(Concrete Flyweight)角色:实现抽象享元角色所规定的接口。如果有内蕴状态的话,必须负责为内蕴状态提供存储空间。享元对象的内蕴状态必须与对象所处的周围环境无关,从而使得享元对象可以在系统内共享。有时候具体享元角色又叫做单纯具体享元角色,因为复合享元角色是由单纯具体享元角色通过复合而成的。
 复合享元(Unsharable Flyweight)角色:复合享元角色所代表的对象是不可以共享的,但是一个复合享元对象可以分解成为多个本身是单纯享元对象的组合。复合享元角色又称作不可共享的享元对象。
 享元工厂(Flyweight Factory)角色:本角色负责创建和管理享元角色。本角色必须保证享元对象可以被系统适当地共享。当一个客户端对象请求一个享元对象的时候,享元工厂角色需要检查系统中是否已经有一个符合要求的享元对象,如果已经有了,享元工厂角色就应当提供这个已有的享元对象;如果系统中没有一个适当的享元对象的话,享元工厂角色就应当创建一个新的合适的享元对象。
 客户端(Client)角色:本角色还需要自行存储所有享元对象的外蕴状态。

2 应用场景举例
公司里要有一些资料共享。这些资料包括技术文档、财务文档、行政文档、管理文档、日常文档等。享元对象的外蕴状态就是技术、财务、行政、管理、日常等类别。用例如图2所示。 在这里插入图片描述
图2 享元模式用例图
在这里可以理解Document(文档类)抽象类就是抽象享元(Flyweight)角色。TechnicalDocument类(技术文档)、FinancialDocument类(财务文档)、AdministrativeDcoment类(行政文档)是具体享元(Concrete Flyweight)角色:DocumentRepository类(资料库)就是享元工厂(Flyweight Factory)角色。其实结构类图如图3所示。TechnicalDocument类、FinancialDocument类和AdministrativeDcoment类都继承Document抽象类。Document抽象类与DocumentRepository类是聚合关系,即DocumentRepository包容多个Document。 在这里插入图片描述
图3 享元模式类图
享元模式实现顺序图见图4,实现顺序描述:① 基于DocumentRepository类实例化一个DocumentRepository对象。DocumentRepository对象在初始化的时候,在内部分别实例化AdministrativeDcoment对象,FinancialDocument对象和TechnicalDocument对象等三个对象。② 向DocumentRepository对象申请“行政文档”,③ 并获得AdministrativeDcoment对象;④ 调用AdministrativeDcoment对象的readDocument方法。⑤-⑦与②-④步骤一致,只不过申请的是“技术文档”。⑧-⑩与②-④步骤一致,只不过申请的是“财务文档”。 在这里插入图片描述
图4 享元模式实现顺序图

3.Quarkus的实现程序代码
Quarkus程序实现主要包括Document抽象类文件,DocumentRepository类文件,AdministrativeDcoment类文件,FinancialDocument类文件和TechnicalDocument类文件等5个文件。其关系如图3所示。下面分别列出这5个文件的程序代码,最后列出测试代码并显示输出结果。
Document抽象类程序代码清单01所示。
程序代码清单01

public abstract class Document {	
	public void readDocument(){	};
}

DocumentRepository类程序代码清单02所示。
程序代码清单02

@ApplicationScoped
public class DocumentRepository {
	
	private AdministrativeDcoment administrativeDcoment;	
	private TechnicalDocument technicalDocument;	
	private FinancialDocument financialDocument;
	
	private Map<String,Document> DocumentMap = new HashMap<String,Document>();	
	
	public DocumentRepository (AdministrativeDcoment administrativeDcoment,
			TechnicalDocument technicalDocument,FinancialDocument financialDocument){			
		this.administrativeDcoment = administrativeDcoment;
		this.technicalDocument = technicalDocument;
		this.financialDocument = financialDocument;		
	}
	
	public void initizeRepository (){
		DocumentMap.put("行政文档", this.administrativeDcoment);
		DocumentMap.put("技术文档", this.technicalDocument);
		DocumentMap.put("财务文档", this.financialDocument);		
	}	
	
	public Document getDocument(String docType){		
		if (DocumentMap.containsKey(docType)){
			return DocumentMap.get(docType);
		}
		System.out.print("没有此类文档。");
		return null;
	}
}

AdministrativeDcoment类,FinancialDocument类和TechnicalDocument类都是继承Document类,其程序代码清单03所示。
程序代码清单03

@ApplicationScoped
public class AdministrativeDcoment extends Document{	
	public void readDocument(){
		System.out.println("请阅读行政文档。");
	}
}

@ApplicationScoped
public class FinancialDocument extends Document{	
	public void readDocument(){
		System.out.println("请阅读财务文档。");
	}
}

@ApplicationScoped
public class TechnicalDocument extends Document{	
	public void readDocument(){
		System.out.println("请阅读技术文档。");
	}
}

享元模式测试程序的代码清单04如下:
程序代码清单04

public class FlyweightClient implements QuarkusApplication {
	@ConfigProperty(name = "gof23.structuralpattern.flyweight.title", defaultValue = "gof23")
	String title;
	
	@Inject	DocumentRepository repository ;
	
	@Override
	public int run(String... args) {		
		System.out.println("———————" + title + "演示输出————————");	
		
		repository.initizeRepository();
		Document doc1 = repository.getDocument("行政文档");
		doc1.readDocument();

		Document doc2 = repository.getDocument("技术文档");
		doc2.readDocument();

		Document doc3 = repository.getDocument("财务文档");
		doc3.readDocument();
		return 0;
	}

	public static void main(String... args) {
		Quarkus.run(FlyweightClient.class, args);
	}
}

享元模式测试类输出结果如下所示:

请阅读行政文档。
请阅读技术文档。
请阅读财务文档。

4. 相关Quarkus程序源码下载
可以直接从github上获取代码,读者可以从github上clone预先准备好的示例代码。

git clone https://github.com/rengang66/quarkus-sample-gof23.git

这是一个Maven项目,然后Maven导入工程。该程序位于“src\main\java\com\iiit\quarkus\sample\gof23\structuralpattern\flyweight”目录中。
同时也可以从gitee上clone预先准备好的示例代码,命令如下:

git clone https://gitee.com/rengang66/quarkus-sample-gof23.git

5 扩展和说明
享元模式实际上是工厂模式和单例模式的结合体。一方面通过工厂模式来创建出新的对象,另一方面,这些创建的对象仅实例化一次。

参考文献

[1] E.Gamma, R.Helm, R.Johnson, and Vlissides. Design Patterns Elements of Reusable Object Oriented Software. Addison-Wesley, 1995
[2] E.Gamma, R.Helm, R.Johnson, and Vlissides.著,李英军等译,设计模式:可复用面向对象软件的基础,北京:机械工业出版社.2000.9.
[3] 阎宏,Java与模式,北京:电子工业出版社. 2002.10
[4] 王俊峰 戚晓滨. 设计模式和UML. 计算机应用研究,1999.16(5), 27-29,39.
[5] 陈琴 朱正强. UML在设计模式描述中的应用. 计算机工程与设计,2003.24(4), 81-84.
[6] 孔金金 顾春华. 设计模式对领域驱动设计的支持及其应用. 计算机与现代化,2008.(11), 46-49,53.
[7] 顾明. 基于软件设计模式的GIS中间件描述. 计算机应用与软件,2008.25(3), 86-88.
[8] 蔡文貌 王自强 都思丹. 设计模式在机器人控制系统中的应用. 科学技术与工程,2008.8(1), 199-202.
[9] 李欢 孙建伶. 应用于Portlet模型的flyweight设计模式. 计算机工程与设计,2004.25(12), 2279-2281.
[10] 于源. 基于构件/构架的模具CAM软件体系结构研究. 组合机床与自动化加工技术,2005.(9), 26-28.
[11] Quarkus官网. https://quarkus.io/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值