〇、小故事
小王所在公司又接到了一个大单子,就是需要他们开发一个用于给百姓们申请打疫苗的疫苗管理平台系统,在系统中需要填报自己的个人信息用于疫苗检测数据采集。采集表里包含:姓名
、居住地址
、要去哪个疫苗检测医院网点
、注射什么品牌的疫苗
……。
小王作为公司的研发主力,自告奋勇的接手了开发任务。“不就是一个疫苗申请信息表吗?so easy~
”,小王利用一个周末的时间,就把这个系统做出来了。周一上班,小王给老板演示了一下,老板非常满意。这个系统正是老板心中想到的模样。
周二系统正式上线,但是!没想到才经过了10分钟,系统就崩溃了!为什么啊?小王一查数据,才突然发现,在这短短10分钟,就是有100万人要填报自己的个人信息用于疫苗检测数据采集。系统的内存被打满了,内存溢出导致了系统崩溃。小王将所有用户需要填的信息都设计成了输入框,每个人都需要输入采集表中所有的个人信息,如果一份个人信息是1KB
,那么100万用户
就是将近1T
的内存空间消耗了。
有什么好的解决办法吗?那么针对于这些信息,如果我们每个人填一份这样的信息,其实是对空间的浪费。因为,我们可以看出来,姓名和居住地址是个性化的,但是疫苗检测的医院或网点,以及疫苗的品牌这些都是固定的。那么我们就可以采取将这些通用实例池化,然后直接去池里获取即可。这个解决方式就是我们今天要介绍的设计模——享元模式/蝇量模式。
一、模式定义
享元模式/蝇量模式(flyweight Pattern
)
享元模式是池技术的重要实现方式,其定义如下:使用共享对象可以有效地支持大量的细粒度的对象。
二、模式类图
根据上面的小故事,我们来绘制出相关模式的类图。首先,我们需要抽取原有疫苗信息中可以共享的部分,将这些信息池化起来NucleicInfoClient.java
,然后,当我们需要展示用户信息的时候,其实分为了两个部分,一个是共享信息(池化信息)NucleicInfo.java
,一个是个性化信息(非池化信息)PersonInfo.java
,具体如下所示:
三、代码实现
人员信息实体类:PersonInfo.java
@Data @NoArgsConstructor @AllArgsConstructor public class PersonInfo { // 姓名 private String name; // 居住的详细地址 private String address; // 疫苗医院或网点唯一标识 private Integer nucleicId; }
疫苗医院网点信息信息:NucleicInfo.java
@Data @AllArgsConstructor @NoArgsConstructor public class NucleicInfo { // 唯一标识 private Integer id; // 疫苗医院网点名称 private String name; }
疫苗医院网点信息客户端类:NucleicInfoClient.java
public class NucleicInfoClient { // 存储疫苗医院和网点的pool private HashMap<Integer, NucleicInfo> pool = Maps.newHashMap(); // 构造函数中初始化池中数据 public NucleicInfoClient() { NucleicInfo nucleicInfo; for (int i = 1; i <=10; i++) { nucleicInfo = new NucleicInfo(i, "北京市第" + i + "医院疫苗网点"); pool.put(nucleicInfo.getId(), nucleicInfo); } } public NucleicInfo getNucleicInfo(Integer key) { if (key == null || !pool.containsKey(key)) return null; return pool.get(key); } }
蝇量模式测试类:FlyweightTest.java
public class FlyweightTest { private static NucleicInfoClient client = new NucleicInfoClient(); public static void main(String[] args) { PersonInfo bob = new PersonInfo("bob", "北京市海淀区xx大街xx小区x号楼x号", 2); PersonInfo muse = new PersonInfo("muse", "北京市朝阳区yy大街yy小区y号楼y号", 7); PersonInfo john = new PersonInfo("john", "上海市市徐汇区zz大街zz小区z号楼z号", 4); printPersonInfo(bob); printPersonInfo(muse); printPersonInfo(john); } public static void printPersonInfo(PersonInfo personInfo) { NucleicInfo nucleicInfo = client.getNucleicInfo(personInfo.getNucleicId()); System.out.println(String.format("姓名=%s 居住地址=%s 疫苗网点=%s", personInfo.getName(), personInfo.getAddress(), nucleicInfo.getName())); } }
今天的文章内容就这些了:
写作不易,笔者几个小时甚至数天完成的一篇文章,只愿换来您几秒钟的 点赞 & 分享 。
更多技术干货,欢迎大家关注公众号“爪哇缪斯” ~ \(^o^)/ ~ 「干货分享,每天更新」