一、享元模式概述
定义:
享元模式:运用共享技术有效的支持大量细粒度对象的复用。
二、享元模式结构与实现
2.1 享元模式的结构
享元模式主要有4个角色:
- Flyweight(抽象享元类):声明类具体享元类公共的方法,一般是接口或抽象类。
- ConcreteFlyweight(具体享元类):实现了抽象享元接口,为内部状态提供了存储空间。
- UnsharedConcreteFlyweight(非共享具体享元类):不能被共享的抽象享元类的子类。
- FlyweightFactory(享元工厂类):用于创建并管理享元对象,它针对抽象享元类编程,将各种类型的具体享元对象存储在一个享元池中。
2.2 享元模式的实现
案例实现。
//抽象享元类
public abstract class BaseDoc {
private String content;
public void display(TextStyle ts) {
System.out.println("文字内容:" + getContent() + ",颜色:" + ts.getColor() + ",文字大小:" + ts.getFontSize());
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
//具体享元类
public class TextDoc extends BaseDoc{
public TextDoc(String content) {
super.setContent(content);
}
}
//外部状态类
public class TextStyle {
private String color;
private String fontSize;
public TextStyle(String color, String fontSize) {
this.color = color;
this.fontSize = fontSize;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public String getFontSize() {
return fontSize;
}
public void setFontSize(String fontSize) {
this.fontSize = fontSize;
}
}
//享元工厂类
public class BaseDocFactory {
public static Map<String, BaseDoc> flyweights = new HashMap<>();
public static BaseDoc getBaseDoc(String key) {
if (flyweights.containsKey(key)) {
return flyweights.get(key);
} else {
BaseDoc baseDoc = new TextDoc(key);
flyweights.put(key, baseDoc);
return baseDoc;
}
}
}
//客户端
public class client {
public static void main(String[] args) {
/**
* 案例需求描述:
* 在屏幕中显示一个文本文档,其中相同的字符串共享一个对象,而这些字符串的颜色和大小可以不同。
* 现使用享元模式设计一个方案实现字符串对象的共享。
*/
BaseDoc hello = BaseDocFactory.getBaseDoc("hello");
BaseDoc hello2 = BaseDocFactory.getBaseDoc("hello");
System.out.println(hello==hello2);
BaseDoc world = BaseDocFactory.getBaseDoc("world");
BaseDoc java = BaseDocFactory.getBaseDoc("java");
hello.display(new TextStyle("red","16px"));
hello2.display(new TextStyle("blue","18px"));
world.display(new TextStyle("pink","15px"));
java.display(new TextStyle("black","20px"));
}
}
三、享元模式优缺点和适用环境
3.1 享元模式的优点
- 可以减少内存中对象的数量,使得相同或者相似对象在内存中只保存一份,从而可以节约系统资源,提供系统性能。
- 享元模式的外部状态相对独立,而且不会影响其内部状态,从而使享元对象可以在不同的环境中被共享。
3.2 享元模式的缺点
- 享元模式使系统变得复杂,需要分离出内部状态和外部状态,这使得程序复杂化。
- 为了使对象可以共享,享元模式需要将享元对象的部分状态外部化,而读取外部状态将使运行时间变长。
3.3 享元模式的适用环境
- 一个系统有大量相同或者相似的对象,赵城内存的大量耗费;
- 对象的大部分状态可以外部化,可以将这些外部状态传入对象中;
- 需要多次重复使用享元对象。
四、其他
享元模式以共享的方式高效地支持大量细粒度对象的重用,享元对象能做到共享的关键是区分了内部状态和外部状态。
内部状态是存储在享元对象内部并且不会随环境改变而改变的状态,内部状态可以共享。
外部状态是随环境改变而改变的,不可用共享的状态。
【参考文献】:
本文是根据刘伟的《Java设计模式》一书的学习笔记,仅供学习用途,勿做其他用途,请尊重知识产权。
【本文代码仓库】:https://gitee.com/xiongbomy/java-design-pattern.git