上周代码评审,看到同事使用了“享元模式”。想起自己也不懂,着手学习之。
参考的优秀的文章:
Java的享元模式
这篇博文为学习之理解、感悟,如理解不真确,请慷慨指出。
本文只讨论单纯享元模式。
Flyweight,是享元模式的意思。同时,其亦是最轻量级摔跤手、轻量级的意思。我想应该是“最轻量级摔跤手 > 轻量级 > 享元模式”慢慢拓展的吧。
将相同的对象共享、缓存,有以下好处,一、避免重复创建相同的对象,二、避免相同的对象存放在内存以消耗内存。
但是,这么做的可行性有一个大前提,就是该对象的不可以改变的:比如A、B两个线程(或代码)都共享C对象,而在B线程工作中,如果可以变更C对象,而C对象在A线程的设计中是不应该如此变更的,这样,不就发生冲突了吗?
最简单的代码实现:


package com.nicchagil.study;public interface Flyweight {}


package com.nicchagil.study;public class User implements Flyweight {private String id;public User(String id) {super();this.id = id;}public String getId() {return id;}@Overridepublic String toString() {StringBuilder builder = new StringBuilder();builder.append("User [id=").append(id).append("]");return builder.toString();}/* 注意,不应该有此方法,及类似的可改变对象内容的逻辑,因为不允许对象的内容发生变更 *//*public void setId(String id) {this.id = id;}*/}


package com.nicchagil.study;import java.util.HashMap; import java.util.Map;public class UserFlyweightFactory {private static Map<String, Flyweight> flyweights = new HashMap<String, Flyweight>();public static Flyweight getInstance(String key) {/* 简易写法 */synchronized (flyweights) {if (flyweights.get(key) == null) {flyweights.put(key, new User(key));}}/* 双重判断写法 *//*if (flyweights.get(key) == null) {synchronized (flyweights) {if (flyweights.get(key) == null) {flyweights.put(key, new User(key));}}}*/return flyweights.get(key);}}


package com.nicchagil.study;public class HowToUse {public static void main(String[] args) {Flyweight flyweight1 = UserFlyweightFactory.getInstance("1");Flyweight flyweight2 = UserFlyweightFactory.getInstance("2");Flyweight flyweight3 = UserFlyweightFactory.getInstance("1");System.out.println("flyweight1 == flyweight2 -> " + (flyweight1 == flyweight2));System.out.println("flyweight1 == flyweight3 -> " + (flyweight1 == flyweight3));}}