享元模式:
以共享的方式高效的支持大量细粒度对象。享元对象共享的关键是区分内蕴状态和外蕴状态。内蕴状态是存储在享元对象内部的,并且不会随环境的改变而改变。外蕴状态是随环境改变而改变的、不可共享的状态。外蕴状态必须由客户端保存,在需要使用的时候再传入到享元对象内部。外蕴状态不能影响内蕴状态,两者是相互独立的。
种类:
根据享元对象的内部表象,享元模式可分为单纯享元模式和复合享元模式。
单纯享元模式:
所有的享元对象都是可以共享的
抽象享元角色(Flyweight):所有具体享元类的超类。规定出需要实现的公共接口。需要外蕴状态的操作可以通过调用方法以参数形式传入。
具体享元角色(ConcreteFlyweight):实现抽象享元角色接口,如果有内蕴状态的话,必须为内蕴状态提供存储空间。
享元工厂角色(Flyweight):负责创建和管理享元角色。必须保证享元对象可以被系统适当的共享。客户端调用享元对象时,检查系统是否有符合要求的享元对象,有则返回该对象,无则创建新对象。
客户端角色(Client):维护一个对所有享元对象的引用,自行存储所有享元对象的外蕴状态。
复合享元模式:
abstract class Flyweight{ abstract public void operation(String state); }
抽象享元角色声明了operation(state)方法,其中state参数代表享元对象的外蕴状态。
class ConcreteFlyweight extends Flyweight{ private Character intrinsicState = null; public ConcreteFlyweight(Character intrinsicState) { this.intrinsicState = intrinsicState; } public void operation(String state) { System.out.println("Intrinsic State = " + intrinsicState); System.out.println("Extrinsic State = " + state); } }
具体享元类实现了抽象享元角色所给定的接口,这里就是operation()方法,享元角色可以具有内蕴状态。这里Character类型的intrinsicState属性为内蕴状态,它的值应该在享元对象被创建时赋予,所有的内蕴状态在对象创建之后就不能在改变。享元对象的有外蕴状态的话,必须存储在客户端,再由客户端传入享元对象。
class FlyweightFactory{ private HashMap files = new HashMap(15); private Flyweight lnkFlyweight; public FlyweightFactory() { } public Flyweight factory(Character state){ if(files.containsKey(state)){ return (Flyweight) files.get(state); }else{ Flyweight fly = new ConcreteFlyweight(state); files.put(state,fly); return fly; } } public void checkFlyweight(){ Flyweight fly; int i = 0; System.out.println("============checkFlyweight============"); for (Iterator it = files.entrySet().iterator(); it.hasNext(); ){ Map.Entry e = (Map.Entry) it.next(); System.out.println("Item " + (++i) + " : " + e.getKey()); } System.out.println("============checkFlyweight============"); } }
客户端不能直接将具体享元类实例化,而必须通过一个工厂对象,利用一个factory()方法得到享元对象,一般而言,享元工厂对象在整个系统中只有一个,因此可以使用单例模式。
客户端需要单纯享元对象的时候,需要调用享元工厂的factory()方法,并传入所需的单纯享元对象的内蕴状态,由工厂方法产生所需的享元对象。
复合享元对象:
抽象享元角色(Flyweight):所有具体享元类的超类,规定出实现的公共接口。外蕴状态的操作通过方法的参数传入。接口并不强制子类实行共享,并非所有的享元对象都可以共享。
具体享元(ConcreteFlyweight):实现抽象享元角色接口,有内蕴状态的话,必须为内蕴状态提供存储空间(初始化)。内蕴状态必须与对象所处环境无关。可以在系统内共享,又叫单纯具体享元角色,复合享元角色由单纯具体享元角色复合而成。
复合享元角色(UnsharableFlyweight): 不可共享,但可以分解成为多个单纯享元对象的组合。又称作不可共享的享元对象。
享元工厂角色(FlyweightFactory):负责创建和管理享元角色。必须保证享元对象可以被系统适当地共享。客户端请求享元对象时,享元工厂角色必须检查系统是否符合要求的享元对象,如果有则返回这个享元对象,没有则创建一个新的享元对象。
客户端角色(Client):需要自行存储所有享元角色的外蕴状态。
抽象享元角色:
abstract class Flyweight{ abstract public void operation(String state); }
具体享元角色:
class ConcreteFlyweight extends Flyweight{ private Character intrinsicState = null; public ConcreteFlyweight(Character intrinsicState) { this.intrinsicState = intrinsicState; } public void operation(String state) { System.out.println("Intrinsic State = " + intrinsicState); System.out.println("Extrinsic State = " + state); } }
实现抽象享元角色所声明的接口,operation()方法接收一个外蕴状态作为参数
为内蕴状态提供存储空间,这里就是intrinsicState属性,享元模式本身对内蕴状态的存储类型没有要求。
具体复合享元角色:
class ConcreteCompositeFlyweight extends Flyweight{ private HashMap files = new HashMap(); private Flyweight flyweight; public ConcreteCompositeFlyweight() { } public void add(Character key,Flyweight fly){ files.put(key, fly); } public void operation(String extrinsicState){ Flyweight fly; for (Iterator it = files.entrySet().iterator(); it.hasNext(); ){ Map.Entry e = (Map.Entry) it.next(); fly = (Flyweight) e.getValue(); fly.operation(extrinsicState); } } }
复合享元对象由享元对象通过复合而成,因此提供了类似add()这样的聚合管理方法。复合享元对象具有不同的聚集元素,聚集元素在复合享元对象被创建后加入。意味着复合享元对象的状态是会改变的,因此复合享元对象是不能共享的。
复合享元对象实现了抽象享元角色接口,这里是operation()方法,这个方法有一个参数,代表复合享元对象的外蕴状态。一个复合享元对象的所有单纯享元对象元素的外蕴状态都是和复合享元对象的外蕴状态相等的。而一个复合享元对象所含有的单纯享元对象的内蕴状态一般是不相等的,不然就没有利用价值了。
享元工厂角色:
class FlyweightFactory{ private HashMap files = new HashMap(15); public FlyweightFactory() { } public Flyweight factory(String compositeState){ ConcreteCompositeFlyweight compositeFly = new ConcreteCompositeFlyweight(); int length = compositeState.length(); Character state = null; for (int i = 0; i < length; i++){ state = new Character(compositeState.charAt(i)); System.out.println("factory(" + state + ")"); compositeFly.add(state, this.factory(state)); } return compositeFly; } public Flyweight factory(Character state){ if(files.containsKey(state)){ return (Flyweight) files.get(state); }else{ Flyweight fly = new ConcreteFlyweight(state); files.put(state,fly); return fly; } } public void checkFlyweight(){ Flyweight fly; int i = 0; System.out.println("============checkFlyweight============"); for (Iterator it = files.entrySet().iterator(); it.hasNext(); ){ Map.Entry e = (Map.Entry) it.next(); System.out.println("Item " + (++i) + " : " + e.getKey()); } System.out.println("============checkFlyweight============"); } }
享元工厂在多态的基础上提供两种不同的方法。一个用于提供单纯享元对象,另一个用于提供复合享元对象。
当客户端需要单纯享元对象时调用factory()方法,并传入需要的内蕴状态,这里内蕴状态是character类型。
当客户端需要复合享元对象时调用factory()方法,并传入复合享元对象的所有复合元素(单纯享元对象)的内蕴状态。可以使用一个聚集对象(Vectory)作为复合享元的状态传入。
参考:
《Java与模式》
相关推荐
用享元模式分析并实现一个具体案例。在一家咖啡店中客户每买一杯咖啡,咖啡制做系统就相应地创建该杯咖啡的配料表,并将其发送给店内的咖啡制做机,咖啡制做机接收到系统发送的配料表后便开始制造客户所买的咖啡。...
在享元模式中可以共享的相同内容称为内部状态(Intrinsic State),而那些需要外部环境来设置的不能共享的内容称为外部状态(Extrinsic State),由于区分了内部状态和外部状态,因此可以通过设置不同的外部状态使得相同...
享元模式的分析以及实际应用 1.前言 4 1.1 课题的研究背景 4 1.2 课题主要研究目标 4 2.相关技术简介 4 2.1Java简介 4 3. 享元模式介绍 5 3.1举例分析 5 3.2基本介绍 5 3.3享元模式的具体角色 5 4. 享元模式之借书...
设计模式的享元模式的例子,希望对大家有用~~~~~~~~
设计模式之享元模式 设计模式之享元模式 设计模式之享元模式
设计模式学习笔记--Flyweight享元模式.docx设计模式学习笔记--Flyweight享元模式.docx设计模式学习笔记--Flyweight享元模式.docx设计模式学习笔记--Flyweight享元模式.docx设计模式学习笔记--Flyweight享元模式.docx
设计模式之享元模式的两种实现方式——单纯享元模式和复合享元模式,已经各种的UML类设计图
享元模式的示例代码和文档,学习享元模式的参考资料。
享元模式Demo
享元模式运用共享技术有效地支持大量细粒度对象的复用。系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用。
享元模式最适合于解决因创建大量类似对象而累及性能的问题,本文将来总结JavaScript设计模式编程中的享元模式使用,包括在DOM操作时的利用示例:
设计模式-享元模式(讲解及其实现代码)
Android享元模式Demo,同步文章地址:http://blog.csdn.net/qq_28690547/article/details/51144424
设计模式(C#)之享元模式(Flyweight Pattern),运用共享技术有效地支持大量细粒度的对象。
C#面向对象设计模式纵横谈(12):Flyweight 享元模式(结构型模式) (Level 300)
设计模式面面观(14):享元模式(Facade Pattern)-结构型模式 http://blog.csdn.net/fanweiwei/archive/2008/04/25/2326692.aspx
java设计模式【之】享元模式【源码】【场景:多缓存可选模式】 /** * 享元模式(预加载单例) * “元” 理解为 “同一地址对象” * 运用共享技术,减少对象的创建,降低对象的数量,降低内存消耗,提高性能 * ...
设计模式中的享原模式技术入门,可用于各种说明场合,一看就会哦
享元模式(Flyweight),运用共享技术有效地支持大量细粒度的对象。 享元模式可以避免大量非常相似类的开销。在程序设计中,有时需要生成大量细粒度的类实例来表示数据。如果能发现这些实例除了几个参数外基本上都是...