设计模式之——享元(Flyweight)模式
享元模式定义
它使用共享物件,用来尽可能减少内存使用量以及分享资讯给尽可能多的相似物件;它适合用于只是因重复而导致使用无法令人接受的大量内存的大量物件。通常物件中的部分状态是可以分享。
享元模式的优点
- 相同对象只保存一份,降低了系统中对象的数量,降低了系统中细粒度对象给内存带来的压力。
享元模式的缺点
- 为了使对象可以共享,需要将一些不能共享的状态外部化,增加了程序的复杂性。
- 读取其外部状态会使运行时间变长。
享元模式的实现
定义非享元角色
/**
* @ClassName UnsharedFlyweight
* @Description TODO
* @Author mamingcong
* @Date 2020/6/13 20:16
* @Version 1.0
*/
public class UnsharedFlyweight {
private String state;
public UnsharedFlyweight(String state) {
this.state = state;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
}
定义抽象享元角色
/**
* @ClassName Flyweight
* @Description TODO
* @Author mamingcong
* @Date 2020/6/13 20:14
* @Version 1.0
*/
public interface Flyweight {
public void operate(UnsharedFlyweight unsharedFlyweight);
}
定义具体享元
/**
* @ClassName RealFlyweight
* @Description TODO
* @Author mamingcong
* @Date 2020/6/13 20:18
* @Version 1.0
*/
public class RealFlyweight implements Flyweight {
private String key;
public RealFlyweight(String key) {
this.key = key;
System.out.println("具体享元" + key + "被创建!");
}
@Override
public void operate(UnsharedFlyweight unsharedFlyweight) {
System.out.println("非享元信息:" + unsharedFlyweight.getState());
}
}
定义享元工厂
/**
* @ClassName FlyweightFactory
* @Description TODO
* @Author mamingcong
* @Date 2020/6/13 20:20
* @Version 1.0
*/
public class FlyweightFactory {
private Map<String, Flyweight> flyweights = new HashMap<String, Flyweight>();
public Flyweight getFlyweight(String key) {
Flyweight flyweight = (Flyweight) flyweights.get(key);
if (flyweight != null) {
System.out.println("具体享元" + key + "已经存在,被成功获取!");
} else {
flyweight = new RealFlyweight(key);
flyweights.put(key, flyweight);
}
return flyweight;
}
}
测试
/**
* @ClassName Test
* @Description TODO
* @Author mamingcong
* @Date 2020/6/13 20:22
* @Version 1.0
*/
public class Test {
public static void main(String[] args) {
FlyweightFactory factory = new FlyweightFactory();
Flyweight f01 = factory.getFlyweight("A");
Flyweight f02 = factory.getFlyweight("A");
Flyweight f11 = factory.getFlyweight("B");
Flyweight f12 = factory.getFlyweight("B");
f01.operate(new UnsharedFlyweight("第1次调用A"));
f02.operate(new UnsharedFlyweight("第2次调用A"));
f11.operate(new UnsharedFlyweight("第1次调用B"));
f12.operate(new UnsharedFlyweight("第2次调用B"));
}
}
运行结果
具体享元A被创建!
具体享元A已经存在,被成功获取!
具体享元B被创建!
具体享元B已经存在,被成功获取!
非享元信息:第1次调用A
非享元信息:第2次调用A
非享元信息:第1次调用B
非享元信息:第2次调用B
享元模式的使用场景
- 如果一个应用程序使用了大量的对象,而这些对象造成了很大的存储开销的时候就可以考虑是否可以使用享元模式。
- 由于享元模式需要额外维护一个保存享元的数据结构(Map),所以应当在有足够多的享元实例时才值得使用享元模式。