第二十一周_T-设计模式-结构型-享元模式

67 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 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