点击这里查看更多设计模式
运用共享技术有效的支持大量细粒度的对象,主要用于减少创建对象,提高资源利用。
1. 系统中有大量相同或类似的对象,创建这些对象需要消耗大量内存资源;
2. 适用于有缓存需求的场景。
如上图,享元模式有两个关键点:1. 享元类中需要维护内部状态,对于同一享元对象,内部状态是一致的;2. 享元工厂中需要维护一个享元对象的容器,客户端可直接通过工厂提供的方法获取享元对象。
/** * 抽象享元对象 */ @Data public abstract class Flyweight { /** * 内部状态,同一享元对象其内部状态相同 */ private String intrinsicState; public Flyweight(String intrinsicState) { this.intrinsicState = intrinsicState; } /** * @param extrinsicState 外部状态,根据外部状态进行具体操作 */ public abstract void operation(String extrinsicState); } /** * 具体Flyweight */ public class ConcreteFlyweight extends Flyweight { public ConcreteFlyweight(String intrinsicState) { super(intrinsicState); } @Override public void operation(String extrinsicState) { System.out.println("具体Flyweight外部状态:" + extrinsicState + ",内部状态:" + getIntrinsicState()); } } /** * 不共享Flyweight */ public class UnSharedFlyweight extends Flyweight { public UnSharedFlyweight(String intrinsicState) { super(intrinsicState); } @Override public void operation(String extrinsicState) { System.out.println("不共享Flyweight外部状态:" + extrinsicState + ",内部状态:" + getIntrinsicState()); } } public class FlyweightFactory { private static final Map<String, Flyweight> FLYWEIGHTS = new HashMap<>(); private FlyweightFactory() { } static { FLYWEIGHTS.put("A", new ConcreteFlyweight("A")); FLYWEIGHTS.put("B", new ConcreteFlyweight("B")); } public static Flyweight getFlyweight(String key) { return FLYWEIGHTS.get(key); } } public class Test { public static void main(String[] args) { Flyweight flyweight = FlyweightFactory.getFlyweight("A"); flyweight.operation("AO"); } }
在一个文件系统中,通过文件MD5(相当于内部状态)来判断文件是否已经存在,若已经存在,则上传时,直接存储一个文件路径即可,不必真实上传文件,提高用户体验。
/** * 文件类,相当于享元类 */ @Data public class File { private String filename; private String content; /** * 文件md5,相当于内部状态 */ private String md5; public File(String filename, String content) { this.filename = filename; this.content = content; this.md5 = calMd5(); } private String calMd5() { // 计算MD5,这里为了方便演示,直接返回文件内容 return content; } } public class FileFactory { private static Map<String, File> FILE_MAP = new HashMap<>(); private static FileFactory fileFactory = new FileFactory(); public static FileFactory getInstance() { return fileFactory; } public void upload(File file) { if (FILE_MAP.containsKey(file.getMd5())) { System.out.println("文件已存在,直接将相关数据和存入数据库"); } else { System.out.println("上传文件,并将相关数据存入数据库"); FILE_MAP.put(file.getMd5(), file); } } } public class Test { public static void main(String[] args) { File file = new File("文件A", "内容A"); FileFactory.getInstance().upload(file); File file2 = new File("文件A", "内容A"); FileFactory.getInstance().upload(file2); } }测试结果如下: