设计模式--享元模式
1 概述
1.1 定义
享元模式(Flywight Design)使用共享对象可有效地支持大量细粒度的对象。
1.2 细解
享元模式采用共享来避免大量拥有相似对象的资源开销(如内存)。享元对象的信息分为内部状态与外部状态。
内部状态:存储在享元对象内部的,并且是不会随环境的改变而有所改变,它们可以作为一个对象的动态附加信息,不必直接存储在具体某个对象中,属于可共享部分。
外部状态:外部状态是对象得以依赖的一个标记,是随环境改变而改变的、不可共享的状态。它是一批对象的统一标识,是唯一的一个索引值。
1.3 应用场景
享元模式是池技术的重要实现。
Apache commons-pool就是"对象池",即通过一定的规则来维护对象集合的容器,如C3P0连接池。但其是否用到了享元模式还不清楚,个人觉得没有用到。在这里写仅仅是说到了池技术,所以写一些Apache commons-pool,希望以后有时间可以看一看该对象池,自己写一个对象池。
1.3 类图
享元模式涉及的角色如下:
- Flyweight抽象享元角色:一个产品的抽象类,同时定义出对象的外部状态和内部状态的接口或实现。
- ConcreteFlywight具体享元角色:一个具体的产品类,实现抽象角色定义的业务逻辑。
- FlywightFactory享元工厂角色:池容器。
2 详解
1 public abstract class Flyweight { 2 // 内部状态 3 private String intrinsic; 4 // 外部状态 5 private final String extrinsic; 6 // 享元角色必须接受外部状态 7 public Flyweight(String extrinsic) { 8 this.extrinsic = extrinsic; 9 } 10 11 // 定义业务逻辑操作 12 public abstract void operate(); 13 14 // 内部状态的getter/setter方法 15 public void setIntrinsic(String intrinsic) { 16 this.intrinsic = intrinsic; 17 } 18 19 public String getIntrinsic() { 20 return intrinsic; 21 } 22 } 23 24 public class ConcreteFlyweight extends Flyweight { 25 // 接收外部状态 26 ConcreteFlyweight(String extrinsic) { 27 super(extrinsic); 28 } 29 30 @Override 31 public void operate() { 32 // 定义自己的业务逻辑 33 } 34 } 35 36 public class FlywightFactory { 37 // 定义池容器 38 private static Map<String, Flyweight> map = new HashMap<>(); 39 40 public static Flyweight getFlyweight(String entrinsic) { 41 Flyweight flyweight = null; 42 if(map.containsKey(entrinsic)) { 43 flyweight = map.get(entrinsic); 44 }else { 45 // 根据外部条件创建享元对象 46 flyweight = new ConcreteFlyweight(entrinsic); 47 map.put(entrinsic, flyweight); 48 } 49 return flyweight; 50 } 51 }