这个模式也是这本书中没有详细阐明的,其实这个模式多多少少有点单例模式+简单工厂模式的意味。在Java 中,String对象就是用享元模式进行管理的——Java将所有固定的String都放在了一个常量池中,相同的String只保存一份拷贝——这个带来的好处是显而易见的,内存占用和创建对象的开销都随之降低——这个模式适用于常用的细粒度可共享对象的创建。
我们设想一个问题场景:在一个预约程序中用于表达时间的类Time
1: public class Time {2: private byte hour;3: private byte minute;4:5: public Time(byte hour, byte minute) {6: this.hour = hour;7: this.minute = minute;8: }9:10: public byte hour() {11: return hour;12: }13:14: public byte minute() {15: return minute;16: }17:18: public String toString() {19: return hour + ":" + minute;20: }21: }22:在一个程序中可能用到这个类非常多次,而且如果小时和分钟相同的话,其实这个类产生的内存对象是可以共享而不影响功能的。尤其是这个应用场景中,预约的时间往往不是正点就是半点,最多可能是15分、45分这样的时间,如果能共享内存则会明显省去很多的内存对象。
这个共享内存的操作是由一个简单工厂方法提供的,在这个类中维护了一个HashMap,完成了类似内存池的功能,若在hashmap中没有该时间的话就new一个time对象,然后放入其中以便以后维护,若有的话则直接返回那个对象即可:
1: public class TimeFactory {2: private static Map times = new HashMap(); </STRING,TIME></STRING,TIME>3: public static Time create(byte hour, byte minute) {4: String key = hour + ":" + minute;5: Time time = times.get(key);6: if (time == null) {7: time = new Time(hour, minute);8: times.put(key, time);9: }10: return time;11: }12: }最后,我们看一下这个UML图:
在这个UML图中,Flywright做了进一步的抽象,UnsharedConcreteFlyWeight类和ConcreteFlyweight类继承与Flyweight类(定义了抽象方法Operation),这两个类的不同点在于FlyweightFactory只维护了ConcreteFlyweight,而对UnsharedConcreteFlyWeight则不参与。其实UnsharedConcreteFlyWeight并非是享元模式必须的类,放在这里只是一个抽象的需要,它的创建就是使用普通的new操作。
在线视频:http://v.youku.com/v_show/id_XMjU2Njk0NzE2.html
参考文献:http://www.developer.com/tech/article.php/10923_3677501_2/Working-with-Design-Patterns-Flyweight.htm