简介
-
面向对象编程中,通过增加类与对象的数量可以很方便的解决一些扩展性的问题,但是如何系统中的对象的数量过多时会导致系统性能的下降。享元模式就是为了解决这个问题而产生的。使用共享技术实现相同或者相似的对象的重用。
-
优点:
- 享元模式的优点在于它可以极大减少内存中对象的数量,使得相同对象或相似对象在内存中只保存一份。
- 享元模式的外部状态相对独立,而且不会影响其内部状态,从而使得享元对象可以在不同的环境中被共享。
-
缺点:
- 享元模式使得系统更加复杂,需要分离出内部状态和外部状态,这使得程序的逻辑复杂化。
- 为了使对象可以共享,享元模式需要将享元对象的状态外部化,而读取外部状态使得运行时间变长。
-
适用环境
- 一个系统有大量相同或者相似的对象,由于这类对象的大量使用,造成内存的大量耗费。
- 对象的大部分状态都可以外部化,可以将这些外部状态传入对象中。
- 使用享元模式需要维护一个存储享元对象的享元池,而这需要耗费资源,因此,应当在多次重复使用享元对象时才值得使用享元模式。
实现
单纯的享元模式
-
类图:
-
代码实现如下:
/** *享元接口 */ public interface IFlyWeight { void opertation(String outState); } /** *具体的享元类 */ public class ConcreteFlyWeight implements IFlyWeight { private String inState; public ConcreteFlyWeight(String intate) { this.inState = inState; } @Override public void opertation(String outState) { System.out.println("instate:" + inState); System.out.println("outState:" + outState); } } /** *享元工厂 */ public class FlyWeightFactory { private Map<String, IFlyWeight> flyWeightPool = new HashMap<>(); public IFlyWeight factory(String key) { IFlyWeight flyWeight = flyWeightPool.get(key); if (flyWeight == null) { flyWeight = new ConcreteFlyWeight(key); flyWeightPool.put(key, flyWeight); } return flyWeight; } } /** 使用 */ public class Client { public static void main(String[] args) { FlyWeightFactory flyWeightFactory = new FlyWeightFactory(); IFlyWeight flyWeight1 = flyWeightFactory.factory("a"); IFlyWeight flyWeight2 = flyWeightFactory.factory("b"); IFlyWeight flyWeight3 = flyWeightFactory.factory("a"); IFlyWeight flyWeight4 = flyWeightFactory.factory("b"); flyWeight1.opertation("1"); flyWeight2.opertation("2"); flyWeight3.opertation("3"); flyWeight4.opertation("4"); System.out.println("f1:" + flyWeight1.hashCode() + ";;f2:" + flyWeight2.hashCode() + ";;" + "f3:" + flyWeight3.hashCode() + ";;f4:" + flyWeight4.hashCode()); } }
复合享元模式
-
类图:
-
代码实现:
/** *享元接口 */ public interface IFlyWeight { void opertation(String outState); } /** *具体的享元类 */ public class ConcreteFlyWeight implements IFlyWeight { private String inState; public ConcreteFlyWeight(String intate) { this.inState = inState; } @Override public void opertation(String outState) { System.out.println("instate:" + inState); System.out.println("outState:" + outState); } } /** *复合享元类 */ public class ConcreteCompositeFlyWeight implements IFlyWeight { private Map<String, IFlyWeight> flyWeightMap = new HashMap<>(); @Override public void opertation(String outState) { System.out.println("ConcreteCompositeFlyWeight outstate:" + outState); for (String state : flyWeightMap.keySet()) { flyWeightMap.get(state).opertation(outState); } } public void addConcreteFlyWeight(String state, IFlyWeight flyWeight) { flyWeightMap.put(state, flyWeight); } } /** *享元工厂 */ public class FlyWeightFactory { private Map<String, IFlyWeight> flyWeightPool = new HashMap<>(); public IFlyWeight factory(String key) { IFlyWeight flyWeight = flyWeightPool.get(key); if (flyWeight == null) { flyWeight = new ConcreteFlyWeight(key); flyWeightPool.put(key, flyWeight); } return flyWeight; } public IFlyWeight factory(List<String> states) { ConcreteCompositeFlyWeight weight = new ConcreteCompositeFlyWeight(); for (String s : states) { weight.addConcreteFlyWeight(s, factory(s)); } return weight; } } /** 使用 */ public class Client { public static void main(String[] args) { FlyWeightFactory flyWeightFactory = new FlyWeightFactory(); IFlyWeight flyWeight1 = flyWeightFactory.factory("a"); IFlyWeight flyWeight2 = flyWeightFactory.factory("b"); IFlyWeight flyWeight3 = flyWeightFactory.factory("a"); IFlyWeight flyWeight4 = flyWeightFactory.factory("b"); flyWeight1.opertation("1"); flyWeight2.opertation("2"); flyWeight3.opertation("3"); flyWeight4.opertation("4"); System.out.println("f1:" + flyWeight1.hashCode() + ";;f2:" + flyWeight2.hashCode() + ";;" + "f3:" + flyWeight3.hashCode() + ";;f4:" + flyWeight4.hashCode()); List<String> states = new ArrayList<>(); states.add("a"); states.add("b"); states.add("d"); states.add("e"); IFlyWeight flyWeight = flyWeightFactory.factory(states); flyWeight.opertation("composite1"); } }