享元模式
- 概述:当会创建大量对象时,可能会占用很多的内存,这个时候我们选择把其中重复创建的那部分对象抽取出来,如果有使用到该对象并且已经创建过了.就直接返回内存中已有的对象,避免重新创建.
- 使用场景
- 系统中有大量相似对象,并消耗大量的内存
- 这些对象可以按内蕴状态分为很多组,当把外蕴状态从对象中剔除出来时,每一组这样的对象都可以用一个对象来代替
- 系统不依赖与这些对象身份,这些对象是不可分辨的.
- 两种模式:单纯享元模式,复合享元模式
- 帮助理解:先看单纯享元模式,看懂了单纯享元模式,复合享元模式就可以认为是在单纯享元模式中加了一个Map又包了一层,以便存下更多的不同的单纯享元模式.正是因为复合享元角色所代表的对象中有很多的单纯享元对象,所以才导致复合享元角色是不可共享的享元对象.
- 设计的角色
- 抽象享元角色:给出一个抽象接口,以规定出所有具体享元角色需要实现的方法.
- 具体享元角色:实现抽象享元角色所规定的接口.如果有内蕴状态的话,必须负责为内蕴状态提供存储空间
- 复合享元角色:(只在复合享元模式中出现),复合享元角色所代表的对象时不可以共享的,但是一个符合享元对象可以分解成为多个本身时单纯享元对象的组合.
- 享元工厂角色:负责创建和管理享元角色.作用是保证享元对象可以被系统适当的共享.当客户端调用一个享元对象的时候,享元工厂会检查系统中是否已经有一个符合要求的享元对象,有的话就直接提供该对象,没有的话就创建一个合适的享元对象.
- 优点:
- 减少对象的创建
- 降低了系统的内存
- 效率提高
- 缺点:
- 提高了系统的复杂度
- 需要分离初内蕴状态和外蕴状态,而且外蕴状态具有顾优化的性质,不应该随着内蕴状态的变化而变化.否则会造成系统混乱.
代码实现
示例:某系统中会创建多个对象,其中可能会有相同(相似)的对象,可能会消耗比较大的内存,所以使用享元模式解决这一问题.
抽象享元角色类
package Flyweight;
/**
* Created by looper on 2017/8/17.
*/
public interface Flyweight {
public void operation();
}
具体享元角色类
package Flyweight;
/**
* Created by looper on 2017/8/17.
*/
public class ConcreteFlyweight implements Flyweight {
//这里指的是共享的对象的那部分相同的内蕴状态
private String name;
public ConcreteFlyweight(String name){
this.name = name;
}
@Override
public void operation() {
System.out.println("name = "+name);
}
}
享元工厂角色类
package Flyweight;
import java.util.HashMap;
import java.util.Map;
/**
* Created by looper on 2017/8/17.
*/
public class FlyweightFactory {
private Map<String,Flyweight> flyweightMap = new HashMap<>();
public Flyweight factory(String key){
//如果共享对象的工厂中有该对象就直接返回该对象
Flyweight flyweight = flyweightMap.get(key);
if(flyweight == null){
//如果共享对象的工厂中没有该对象就会自动创建一个
flyweight = new ConcreteFlyweight(key);
flyweightMap.put(key,flyweight);
}
return flyweight;
}
//查看一共有多少个对象
public void getMapSize(){
System.out.println("size = "+flyweightMap.size());
}
}
测试类
package Flyweight;
/**
* Created by looper on 2017/8/17.
*/
public class FlyweightTest {
public static void main(String[] args) {
FlyweightFactory factory = new FlyweightFactory();
Flyweight factory1 = factory.factory("西瓜");
Flyweight factory2 =factory.factory("西红柿");
Flyweight factory3 =factory.factory("苹果");
Flyweight factory4 =factory.factory("西瓜");
factory1.operation();
factory2.operation();
factory3.operation();
factory4.operation();
factory.getMapSize();
}
}
输出:
根据上面的输出结果,我们看出,我们创建了4个对象,但是实际上只创建了3个,相同的对象之间共享了.