一、概述
运用共享技术有效地支持大量细粒度的对象。
二、适用性
1.当一个应用程序使用了大量的对象的时候。
2.由于使用大量的独享而造成很大的存储开销的时候。
3.对象的大多数状态都可变为外部状态的时候。
4.如果删除对象的外部状态,那么可以用相对较少的共享独享取代很对组对象的时候。
5.应用程序不依赖于对象标识的时候。由于享元模式对象可以被共享,对于概念上明显有别的对象,标识测试将返回真值。
三、参与者
1.Flyweight:描述一个接口,通过这个接口Flyweight可以接受和作用于对象外部状态。
2.ConcreteFlyweight:实现Flyweight接口,并为内部状态(如果有)增加存储空间。
3.UnsharedConcreteFlyweight:并非所有的Flyweight子类都需要被共享。Flyweight接口使共享成为可能,但并不强制共享。在Flyweight对象结构的某些层次上,UnsharedConcreteFlyweight对象通常将ConcreteFlyweight对象作为子节点。
4.FlyweightFactory:创建并管理Flyweight对象。确保合理地共享Flyweight对象。当用户请求一个Flyweight对象时,FlyweightFactory提供一个已经创建好的的实例或者创建一个新的实例给它。
四、类图
五、示例
Flyweight
- package cn.lynn.flyweight;
- public interface IPerson {
- public void say(int num);
- }
ConcreteFlyweight
- package cn.lynn.flyweight;
- public class PersonImpl implements IPerson {
- @Override
- public void say(int num) {
- System.out.println("报数:" + num);
- }
- }
FlyweightFactory
- package cn.lynn.flyweight;
- import java.util.HashMap;
- import java.util.Map;
- public class PersonCache {
- private static Map<String, PersonImpl> personPool = new HashMap<String, PersonImpl>();
- public PersonCache(String key) {
- personPool.put(key, new PersonImpl());
- }
- public static IPerson getPerson(String key) {
- if(personPool.get(key) == null) {
- personPool.put(key, new PersonImpl());
- }
- return personPool.get(key);
- }
- public static int getSize() {
- return personPool.size();
- }
- }
Client
- package cn.lynn.flyweight;
- public class Client {
- public static void main(String[] args) {
- IPerson p1 = PersonCache.getPerson("张三");
- p1.say(1);
- IPerson p2 = PersonCache.getPerson("张三");
- System.out.println("p1和p2是同一个人吗?" + ((p1 == p2) ? "是" : "不是"));
- IPerson p3 = PersonCache.getPerson("李四");
- p3.say(2);
- IPerson p4 = PersonCache.getPerson("王五");
- p4.say(3);
- IPerson p5 = PersonCache.getPerson("赵六");
- p5.say(4);
- System.out.println("现有人数:" + PersonCache.getSize());
- }
- }
Result
- 报数:1
- p1和p2是同一个人吗?是
- 报数:2
- 报数:3
- 报数:4
- 现有人数:4