享元模式 FlyWeight 结构型 设计模式(十五)
意图
意图解析
考虑下图中的情景,这里面所有的“你”字,到底是不是同样的?
- 是,因为全部都是汉字“你”
- 不是,因为尽管都是汉字“你”,但是他们的字体,颜色,字号,却又明显不同,所以不是同样的
小结
享元工厂
示例代码
package flyweight; public class Color { public String Color; public Color(String color) { this.Color = color; } public String getColor() { return Color; } }
package flyweight; public abstract class Character { public abstract String getValue(); public void display(Color color) { System.out.println("字符: " + getValue() + " ,颜色: " + color.getColor()); } }
package flyweight; public class ChineseCharacter extends Character { @Override public String getValue() { return "你"; } }
package flyweight; import java.util.HashMap; public class CharacterFactory { /** * 单例模式 饿汉式创建 */ private static CharacterFactory instance = new CharacterFactory(); /** * 使用HashMap管理享元池 */ private HashMap<String, Object> hm = new HashMap<>(); private CharacterFactory() { Character character = new ChineseCharacter(); hm.put("你", character); } /** * 单例全局访问接口获取工厂 */ public static CharacterFactory getInstance() { return instance; } /** * 根据key获取池中的对象 */ public Character getCharacter(String key) { return (Character) hm.get(key); } }
结构
客户端角色Client
客户端角色维护了对所有享元对象的引用
分类
单纯享元模式
package flyweight.simple; public abstract class FlyWeight { /** * 抽象的业务逻辑方法,接受外部状态作为参数 */ abstract public void operation(String outerState); }
package flyweight.simple; public class ConcreteFlyWeight extends FlyWeight { private String innerState = null; public ConcreteFlyWeight(String innerState) { this.innerState = innerState; } /** * 外部状态作为参数传递 */ @Override public void operation(String outerState) { System.out.println("innerState = " + innerState + " outerState = " + outerState); } }
package flyweight.simple; import java.util.HashMap; public class FlyWeightFactory { /** * 单例模式 饿汉式创建 */ private static FlyWeightFactory instance = new FlyWeightFactory(); /** * 使用HashMap管理享元池 */ private HashMap<String, Object> hm = new HashMap<>(); private FlyWeightFactory() { } /** * 单例全局访问接口获取工厂 */ public static FlyWeightFactory getInstance() { return instance; } /** * 根据innerState获取池中的对象 * 存在返回,不存在创建并返回 */ public FlyWeight getFylWeight(String innerState) { if(hm.containsKey(innerState)){ return (FlyWeight) hm.get(innerState); }else{ FlyWeight flyWeight = new ConcreteFlyWeight(innerState); hm.put(innerState,flyWeight); return flyWeight; } } }
package flyweight.simple; public class Test { public static void main(String[] args){ FlyWeightFactory flyWeightFactory = FlyWeightFactory.getInstance(); FlyWeight flyWeight1 = flyWeightFactory.getFylWeight("First"); FlyWeight flyWeight2 = flyWeightFactory.getFylWeight("Second"); FlyWeight flyWeight3 = flyWeightFactory.getFylWeight("First"); System.out.println(flyWeight1); System.out.println(flyWeight2); System.out.println(flyWeight3); System.out.println(); flyWeight1.operation("outer state XXX"); flyWeight2.operation("outer state YYY"); flyWeight3.operation("outer state ZZZ"); } }
复合享元模式
复合享元角色UnsharedConcreteFlyWeight
复合享元角色,也就是不可共享的,也被称为 不可共享的享元对象
但是一个复合享元对象可以分解为多个本身是单纯享元对象的组合
这些单纯的享元对象就又是可以共享的
package flyweight.composite; public abstract class FlyWeight { /** * 抽象的业务逻辑方法,接受外部状态作为参数 */ abstract public void operation(String outerState); }
package flyweight.composite; public class ConcreteFlyWeight extends FlyWeight { private String innerState = null; public ConcreteFlyWeight(String innerState) { this.innerState = innerState; } /** * 外部状态作为参数传递 */ @Override public void operation(String outerState) { System.out.println("innerState = " + innerState + " outerState = " + outerState); } }
package flyweight.composite; import java.util.ArrayList; import java.util.List; public class UnsharedConcreateFlyWeight extends FlyWeight { private String innerState = null; public UnsharedConcreateFlyWeight(String innerState) { this.innerState = innerState; } private List<FlyWeight> list = new ArrayList<>(); public void add(FlyWeight flyWeight) { list.add(flyWeight); } @Override public void operation(String outerState) { for (FlyWeight flyWeight:list) { flyWeight.operation(outerState); } } }
package flyweight.composite; import java.util.HashMap; public class FlyWeightFactory { /** * 单例模式 饿汉式创建 */ private static FlyWeightFactory instance = new FlyWeightFactory(); /** * 使用HashMap管理享元池 */ private HashMap<String, Object> hm = new HashMap<>(); /** * 管理复合享元对象 */ private HashMap<String, Object> compositeHm = new HashMap<>(); private FlyWeightFactory() { } /** * 单例全局访问接口获取工厂 */ public static FlyWeightFactory getInstance() { return instance; } /** * 根据innerState获取池中的对象 * 存在返回,不存在创建并返回 */ public FlyWeight getFylWeight(String innerState) { if(hm.containsKey(innerState)){ return (FlyWeight) hm.get(innerState); }else{ FlyWeight flyWeight = new ConcreteFlyWeight(innerState); hm.put(innerState,flyWeight); return flyWeight; } } /** * 根据innerState获取池中的对象 * 存在返回,不存在创建并返回 */ public UnsharedConcreateFlyWeight getCompositeFylWeight(String state) { if(compositeHm.containsKey(state)){ return (UnsharedConcreateFlyWeight) compositeHm.get(state); }else{ UnsharedConcreateFlyWeight flyWeight = new UnsharedConcreateFlyWeight(state); compositeHm.put(state,flyWeight); return flyWeight; } } }
package flyweight.composite; public class Test { public static void main(String[] args){ FlyWeightFactory flyWeightFactory = FlyWeightFactory.getInstance(); FlyWeight flyWeight1 = flyWeightFactory.getFylWeight("First"); FlyWeight flyWeight2 = flyWeightFactory.getFylWeight("Second"); FlyWeight flyWeight3 = flyWeightFactory.getFylWeight("First"); System.out.println(flyWeight1); System.out.println(flyWeight2); System.out.println(flyWeight3); System.out.println("###########################################"); flyWeight1.operation("outer state XXX"); flyWeight2.operation("outer state YYY"); flyWeight3.operation("outer state ZZZ"); System.out.println("###########################################"); UnsharedConcreateFlyWeight compositeFlyWeight = flyWeightFactory.getCompositeFylWeight("composite"); compositeFlyWeight.add(flyWeight1); compositeFlyWeight.add(flyWeight2); compositeFlyWeight.operation("composite out state OOO"); } }
使用场景
- 应用程序中使用了大量的对象
- 大量的对象明显增加了程序的存储运行开销
- 对象可以提取出内部状态,并且可以分离外部状态