Gof23种设计模式(11)——享元模式(Flyweight)

2020年8月14日10:16:38 评论 49

1 基础知识

1.1 标准定义

享元(Flyweight)模式标准定义:运用共享技术有效地支持大量细粒度的对象。

1.2 分析和说明

享元(Flyweight)模式属于结构型设计模式。享元模式以共享的方式高效的支持大量的细粒度对象。享元模式能做到共享的关键是区分内蕴状态和外蕴状态。内蕴状态存储在享元内部,不会随环境的改变而有所不同。外蕴状态是随环境的改变而改变的。外蕴状态不能影响内蕴状态,它们是相互独立的。将可以共享的状态和不可以共享的状态从常规类中区分开来,将不可以共享的状态从类里剔除出去。客户端不可以直接创建被共享的对象,而应当使用一个工厂对象负责创建被共享的对象。享元模式大幅度的降低内存中对象的数量。

Flyweight结构如图1所示。其角色包括抽象享元(Flyweight)角色、具体享元(Concrete Flyweight)角色、复合享元(Unsharable Flyweight)角色和享元工厂(Flyweight Factory)角色等。

Gof23种设计模式(11)——享元模式(Flyweight)

图1 享元模式结构

 抽象享元(Flyweight)角色:此角色是所有具体享元类的超类,为这些规定出需要实现的公共接口。那些需要外蕴状态(External State)的操作可以通过方法的参数传入。抽象享元的接口使得享元变得可能,但是并不强制子类实行共享,因此并非所有的享元对象都是可以共享的。

 具体享元(Concrete Flyweight)角色:实现抽象享元角色所规定的接口。如果有内蕴状态的话,必须负责为内蕴状态提供存储空间。享元对象的内蕴状态必须与对象所处的周围环境无关,从而使得享元对象可以在系统内共享。有时候具体享元角色又叫做单纯具体享元角色,因为复合享元角色是由单纯具体享元角色通过复合而成的。

 复合享元(Unsharable Flyweight)角色:复合享元角色所代表的对象是不可以共享的,但是一个复合享元对象可以分解成为多个本身是单纯享元对象的组合。复合享元角色又称作不可共享的享元对象。

 享元工厂(Flyweight Factory)角色:本角色负责创建和管理享元角色。本角色必须保证享元对象可以被系统适当地共享。当一个客户端对象请求一个享元对象的时候,享元工厂角色需要检查系统中是否已经有一个符合要求的享元对象,如果已经有了,享元工厂角色就应当提供这个已有的享元对象;如果系统中没有一个适当的享元对象的话,享元工厂角色就应当创建一个新的合适的享元对象。

 客户端(Client)角色:本角色还需要自行存储所有享元对象的外蕴状态。

2 应用场景举例

公司里要有一些资料共享。这些资料包括技术文档、财务文档、行政文档、管理文档、日常文档等。享元对象的外蕴状态就是技术、财务、行政、管理、日常等类别。用例如图2所示。

Gof23种设计模式(11)——享元模式(Flyweight)

图2 享元模式用例图

在这里可以理解Document(文档类)抽象类就是抽象享元(Flyweight)角色。TechnicalDocument类(技术文档)、FinancialDocument类(财务文档)、AdministrativeDcoment类(行政文档)是具体享元(Concrete Flyweight)角色:DocumentRepository类(资料库)就是享元工厂(Flyweight Factory)角色。其实结构类图如图3所示。TechnicalDocument类、FinancialDocument类和AdministrativeDcoment类都继承Document抽象类。Document抽象类与DocumentRepository类是聚合关系,即DocumentRepository包容多个Document。

Gof23种设计模式(11)——享元模式(Flyweight)

图3 享元模式类图

享元模式实现顺序图见图4,实现顺序描述:
①基于DocumentRepository类实例化一个DocumentRepository对象。DocumentRepository对象在初始化的时候,在内部分别实例化AdministrativeDcoment对象,FinancialDocument对象和TechnicalDocument对象等三个对象。
②向DocumentRepository对象申请“行政文档”,
③并获得AdministrativeDcoment对象;
④调用AdministrativeDcoment对象的readDocument方法。
⑤-⑦与②-④步骤一致,只不过申请的是“技术文档”。
⑧-⑩与②-④步骤一致,只不过申请的是“财务文档”。

Gof23种设计模式(11)——享元模式(Flyweight)

图4 享元模式实现顺序图

3.Java的实现程序代码

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

Document抽象类程序代码清单01所示。

程序代码清单01

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

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

程序代码清单02

public class DocumentRepository {

	private Map<String, Document> DocumentMap = new HashMap<String, Document>();

	public DocumentRepository() {
		initizeRepository();
	}

	private void initizeRepository() {
		DocumentMap.put("行政文档", new AdministrativeDcoment());
		DocumentMap.put("技术文档", new TechnicalDocument());
		DocumentMap.put("财务文档", new 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

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

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

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

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

程序代码清单04

public class Client {

	public static void main(String[] args) {

		DocumentRepository repository = new DocumentRepository();
		Document doc1 = repository.getDocument("行政文档");
		doc1.readDocument();

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

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

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

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

4 扩展和说明

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


参考链接

7种结构型模式

Gof23种设计模式(6)——适配器模式(Adapter)
Gof23种设计模式(7)——桥接模式(Bridge)
Gof23种设计模式(8)——组合模式(Composite)
Gof23种设计模式(9)——装饰器模式(Decorator)
Gof23种设计模式(10)——外观模式(Facade)
Gof23种设计模式(11)——享元模式(Flyweight)
Gof23种设计模式(12)——代理模式(Proxy)
Gof23种设计模式 —— 结构型模式总结和比较

回到总目录Gof23种设计模式(全解析)

(转载自微信公众号:架构设计模式)

素课网
  • 本文由 发表于 2020年8月14日10:16:38
  • 转载请注明:https://www.suketech.com/9274.html
设计模式:面向对象设计的六大原则 - 总结 设计模式

设计模式:面向对象设计的六大原则 – 总结

开闭原则是面向对象设计中最基础的设计原则,它指导我们如何建立稳定灵活的系统。开闭原则可能是设计模式六项原则中定义最模糊的一个了,它只告诉我们对扩展开放,对修改关闭,可是到底如何才能做到对扩展开放,对修...
匿名

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: