【设计模式 - 11】之享元模式(FlyWeight)
2016-12-11 09:09
351 查看
1 模式简介
当系统中存在大量对象时,非常容易造成内存溢出。为了解决这个问题,我们把这些对象中共有的部分抽象出来,如果有相同的业务请求,则直接返回在内存中已有的对象,避免重新创建,这就是享元模式。享元模式(FlyweightPattern)主要用于减少创建对象的数量,以减少内存占用和提高性能,即它提供了减少对象数量从而改善应用所需的对象结构的方式。享元模式尝试重用现有的同类对象,如果未找到匹配的对象,则创建新对象。
例如,JAVA中的String使用的就是享元模式:
public class Test {
public static void main(String[] args) {
String a = "abc";
String b = "abc";
System.out.println(a == b);
}
}
// 返回值:true又如,一个编辑器中如果只能输入大小写的字母,则有52个字符可以输入,此时我们只需要在编辑器中存储52个字符对象,而不需要每输入一个字符就创建一个对象。
享元模式的UML图:
享元模式的适用场景:
1) 当系统中有大量对象时;
2) 当这些对象基本相似时;
3) 当这些对象会消耗大量内存时;
4) 当这些对象需要使用缓冲池管理时。
享元模式的使用方法:
享元模式通常使用一个工厂管理,在工厂中维护一个HashTable或HashMap,使用唯一标识来存放和取出对象。另外还可以对工厂使用单例模式,保证项目中只有一个工厂。
享元模式的优点:
大大减少了对象的创建,降低了系统的内存,提高了效率。
享元模式的缺点:
提高了系统的负责度,需要分离出外部状态和内部状态,外部状态不应该随着内部状态的变化而变化,否则会造成系统的混乱。
2 实例
我们以上面说的编辑器的例子为需求,要求编辑器中只能输入字符,使用享元模式进行管理。享元接口:
public interface MyChar {
String showMyChar();
}享元实现类:
public class MyCharImpl implements MyChar {
private Character c;
public MyCharImpl(Character c) {
this.c = c;
}
@Override
public String showMyChar() {
return this.c + "";
}
}享元工厂:
public class MyCharFactory {
private static MyCharFactory instance;
private Map<Character, MyChar> charMap;
private MyCharFactory() {
this.charMap = new HashMap<Character, MyChar>();
}
/**
* 单例
*/
public static MyCharFactory getInstance() {
if (instance == null) {
synchronized (MyCharFactory.class) {
if (instance == null) {
instance = new MyCharFactory();
}
}
}
return instance;
}
/**
* 根据字符的键获取字符对象
*/
public MyChar getMyChar(Character character) {
MyChar c = charMap.get(character);
if (c == null) {
c = new MyCharImpl(character);
charMap.put(character, c);
}
return c;
}
/**
* 获取Map中存储的字符的数量
*/
public int getCharCount() {
return charMap.size();
}
}测试类:
public class Test {
public static void main(String[] args) {
MyChar char1;
MyChar char2;
MyChar char3;
MyChar char4;
MyChar char5;
MyChar char6;
char1 = MyCharFactory.getInstance().getMyChar(new Character('a'));
System.out.println("获取享元字符:" + char1.showMyChar());
System.out.println("当前享元字符数量:" + MyCharFactory.getInstance().getCharCount());
char2 = MyCharFactory.getInstance().getMyChar(new Character('b'));
System.out.println("获取享元字符:" + char2.showMyChar());
System.out.println("当前享元字符数量:" + MyCharFactory.getInstance().getCharCount());
char3 = MyCharFactory.getInstance().getMyChar(new Character('c'));
System.out.println("获取享元字符:" + char3.showMyChar());
System.out.println("当前享元字符数量:" + MyCharFactory.getInstance().getCharCount());
char4 = MyCharFactory.getInstance().getMyChar(new Character('a'));
System.out.println("获取享元字符:" + char4.showMyChar());
System.out.println("当前享元字符数量:" + MyCharFactory.getInstance().getCharCount());
char5 = MyCharFactory.getInstance().getMyChar(new Character('a'));
System.out.println("获取享元字符:" + char5.showMyChar());
System.out.println("当前享元字符数量:" + MyCharFactory.getInstance().getCharCount());
char6 = MyCharFactory.getInstance().getMyChar(new Character('d'));
System.out.println("获取享元字符:" + char6.showMyChar());
System.out.println("当前享元字符数量:" + MyCharFactory.getInstance().getCharCount());
}
}运行结果如下图所示:
最后贴出享元模式的GitHub代码地址:【GitHub - FlyWeight】。
相关文章推荐
- 设计模式(11)--Flyweight(享元模式)--结构型
- 设计模式(11)-结构型-享元模式(Flyweight)
- 【设计模式 - 11】之享元模式(FlyWeight)
- [设计模式] 11 享元模式 Flyweight
- 设计模式之11 - 享元模式FlyWeight
- 设计模式——享元模式(Flyweight)
- 设计模式学习笔记--Flyweight享元模式
- 重温设计模式(一)——享元模式(Flyweight)
- 设计模式(11)-单例模式(Flyweight)
- 一天一个设计模式之享元模式(flyweight)
- 设计模式之享元模式(Flyweight)
- 设计模式学习笔记(十二)——Flyweight享元模式
- 设计模式--Flyweight享元模式
- 设计模式学习8 -- Flyweight(享元模式)
- 设计模式学习11 Flyweight
- 重温设计模式(一)——享元模式(Flyweight)
- 设计模式--享元模式(Flyweight)
- 设计模式--享元模式(Flyweight)
- 设计模式与泡mm的关系之flyweight享元模式及享元模式的再思考
- 设计模式学习笔记(十二)——Flyweight享元模式