享元模式-Flyweight
名称:
享元模式(Flyweight Pattern)-对象结构型模式
问题:
The flyweight design pattern enables use sharing of objects to support large numbers of fine-grained objects efficiently.
运用共享技术有效地支持大量细粒度的对象。
适用性:
-一个应用程序使用了大量的对象。
-完全由于使用大量的对象,造成很大的存储开销。
-对象的大多数状态都可变为外部状态。
-如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象。
-应用程序不依赖于对象标示。由于Flyweight对象可以被共享,对于概念上明显有别的对象,标识测试将返回真值。
协作:
-Flyweight执行时所需的状态必定是内部的或外部的。内部状态存储于ConcreteFlyweight对象之中;而外部对象则由Client对象存储或计算。当用户调用flyweight对象的操作时,将该状态传递给他。
-用户不应直接对ConcreteFlyweight类进行实例化,而只能从FlyweightFactory对象得到ConcreteFlyweight对象,这可以保证对他们适当地进行共享。
优点和缺点:
会产生运行时的开销。然而,空间上的节省抵消了这些开销。
解决方案:
1、 模式的参与者
1、Flyweight
-描述一个接口,通过这个接口flyweight可以接受并作用于外部状态。
2、ConcreteFlyweight
-实现Flyweight接口,并为内部状态(如果有的话)增加存储空间。ConcreteFlyweight对象必须是可共享的。它所存储的状态必须是内部的;即,它必须独立于ConcreteFlyweight对象的场景。
3、UnsharedConcreteFlyweight
-并非所有的Flyweight子类都需要被共享。Flyweight接口使共享成为可能,但它并不强制共享。在Flyweight对象结构的某些层次,UnsharedConcreteFlyweight对象通常将ConcreteFlyweight对象作为子节点。
4、FlyweightFactory
-创建并管理flyweight对象。
-确保合理地共享flyweight。当用户请求一个flyweight时,FlyweightFactory对象提供一个已创建的实例或创建一个。
5、Client
-维持一个对flyweight的引用。
-计算或者存储一个(多个)flyweight的外部状态。
2.实现方式
class UnsharedConcreteFlyweight { private String sharedInfo; UnsharedConcreteFlyweight(String sharedInfo) { this.sharedInfo= sharedInfo; } public String getSharedInfo() { return sharedInfo; } public void setSharedInfo(String sharedInfo) { this.sharedInfo=sharedInfo; } }
interface Flyweight { public void operation(UnsharedConcreteFlyweight state); }
class ConcreteFlyweight implements Flyweight { private String key; ConcreteFlyweight(String key) { this.key=key; } public void operation(UnsharedConcreteFlyweight outState) { outState.getSharedInfo() } }
class FlyweightFactory { private HashMap<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+" is exist!"); } else { flyweight=new ConcreteFlyweight(key); flyweights.put(key, flyweight); } return flyweight; } }
public class FlyweightPattern { public static void main(String[] args) { FlyweightFactory factory=new FlyweightFactory(); Flyweight f01=factory.getFlyweight("a"); Flyweight f02=factory.getFlyweight("a"); Flyweight f03=factory.getFlyweight("a"); Flyweight f11=factory.getFlyweight("b"); Flyweight f12=factory.getFlyweight("b"); f01.operation(new UnsharedConcreteFlyweight("1a。")); f02.operation(new UnsharedConcreteFlyweight("2a。")); f03.operation(new UnsharedConcreteFlyweight("3a。")); f11.operation(new UnsharedConcreteFlyweight("1b。")); f12.operation(new UnsharedConcreteFlyweight("2b。")); } }
JAVA 中的 String,如果有则返回,如果没有则创建一个字符串保存在字符串缓存池里面。
参考资料
《设计模式:可复用面向对象软件的基础》