开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 5 天,点击查看活动详情
定义:
享元模式(Flyweight Pattern)使用共享物件,来尽可能减少内存使用量以及分享资讯给尽可能多的相似物件。它强调内部状态和外部状态:内部状态是可以共享的。外部状态则是动态的。即是把共享的提出来封装使用即可。
案例:
商品秒杀:商品信息是不变的,库存是一直在变的。此时把基本信息提取为一个工厂类,每次提供一个不变的单例。变化的信息单独实现。
简单实现
直接一把返回,每次都走同样的逻辑。调用一次,查询一次返回。
public class ActivityTest {
public static void main(String[] args) {
Activity activity = new Activity();
activity.setId("123");
activity.setName("Java 设计模式");
activity.setDesc("经典图书");
activity.setStartTime("2023-02-08");
activity.setEndTime("2023-02-09");
activity.setStock(new Stock(100,1));//每次动态变化的
System.out.println(activity);
}
}
模式实现
将不变的基本信息放到 Map ,直接返回。将变化的部分单独运算,再一起返回。
这里一般是建立一个享元工厂,用于创建和管理 flyweight 对象。当请求时,这个工厂会提供一个实例(一般都是已存在的)。
public class FlyweightFactory {
static Map<String, Activity> activityMap = new HashMap<String, Activity>();
public static Activity getActivity(String id) {
Activity activity = activityMap.get(id);
if (null == activity) {
// 模拟从实际业务应⽤用从接⼝口中获取活动信息
activity = new Activity();
activity.setId("123");
activity.setName("Java 设计模式");
activity.setDesc("经典图书");
activity.setStartTime("2023-02-08");
activity.setEndTime("2023-02-09");
activityMap.put(id, activity);
}
return activity;
}
}
public class ApiTest {
public static void main(String[] args) {
//商品基本信息不会变
Activity activity = FlyweightFactory.getActivity("123");
Stock stock = get(10);
activity.setStock(stock);
System.out.println(activity);
}
/**
* 模拟库存的处理
*/
public static Stock get(int i) {
Stock stock = new Stock(100, 0);
stock.setUsed(stock.getUsed()+i);
return stock;
}
}
总结
感觉看下来有点类似于 原型模式:克隆一个对象复用。
- 一般是服务端减少接口调用,客户端减少内存占用
- 工厂类中使用 map 缓存数据,很多模式都使用到了,可以有效的减少 if-else