栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

设计模式 享元模式

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

设计模式 享元模式

文章目录

享元模式情景享元模式实战

不使用享元模式的写法使用享元模式的写法

享元模式情景

享元模式主要在于共享通用对象,减少内存的使用,提升系统的访问效率。而这部分共享对象通常比较耗费内存或者需要查询大量接口或者使用数据库资源,因此统一抽离作为共享对象使用。

享元模式实战

模拟在商品秒杀场景下使用享元模式查询优化.
商品活动信息是不变的, 变化的是库存信息.

不使用享元模式的写法

模拟活动信息和库存信息都从数据库中查询.
创建tutorials-14.0-0 模块
创建Activity活动类

@Data
public class Activity {
    private Long id;        // 活动ID
    private String name;    // 活动名称
    private String desc;    // 活动描述
    private Date startTime; // 开始时间
    private Date stopTime;  // 结束时间
    private Stock stock;    // 活动库存
}

创建库存类Stock

@Data
public class Stock {
    private int total; // 库存总量
    private int used;  // 库存已用

    public Stock(int total, int used) {
        this.total = total;
        this.used = used;
    }
}

创建ActivityController, 实现活动信息和库存的查询. 此处模拟的是从数据库查询活动和库存信息.

public class ActivityController {
    public Activity queryActivityInfo(Long id) {
        // 模拟从数据库中获取接口信息
        Activity activity = new Activity();
        activity.setId(10001L);
        activity.setName("图书嗨乐");
        activity.setDesc("图书优惠券分享激励分享活动第二期");
        activity.setStartTime(new Date());
        activity.setStopTime(new Date());
        activity.setStock(new Stock(1000,1));
        return activity;
    }
}
使用享元模式的写法

享元模式类图.
ActivityFactory 构建了享元工厂, 用一个map结构来进行缓存活动信息.

ActivityFactory 代码如下

public class ActivityFactory {

    static Map activityMap = new HashMap();

    public static Activity getActivity(Long id) {
        Activity activity = activityMap.get(id);
        if (activity == null) {
            activity = new Activity();
            activity.setId(1000L);
            activity.setName("618");
            activity.setDesc("618 数码电器大促销");
            activity.setStartTime(new Date());
            activity.setStopTime(new Date());
            activityMap.put(id, activity);
        }
        return activity;
    }
}

RedisUtils 模拟了定时任务来增加使用的库存.

public class RedisUtils {
    private ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);

    private AtomicInteger stock = new AtomicInteger(0);

    public RedisUtils() {
        scheduledExecutorService.scheduleAtFixedRate(()->{
            stock.addAndGet(1);
            // 0.1秒库存变化一次
        }, 0, 100000, TimeUnit.MICROSECONDS);
    }

    public int getStockUsed() {
        return stock.get();
    }
}

ActivityController 如下.
从ActivityFactory中获取活动信息.
从RedisUtils 中获取库存信息.

public class ActivityController {
    private RedisUtils redisUtils = new RedisUtils();

    public Activity queryActivityInfo(Long id) {
        Activity activity = ActivityFactory.getActivity(id);
        Stock stock = new Stock(1000, redisUtils.getStockUsed());
        activity.setStock(stock);
        return activity;
    }
}

测试类 (结果)

public class ApiTest {

    private Logger logger = LoggerFactory.getLogger(ApiTest.class);

    private ActivityController activityController = new ActivityController();

    @Test
    public void test_queryActivityInfo() throws InterruptedException {
        for (int i = 0; i < 10; i++) {
            Long req = 10001L;
            Activity activity = activityController.queryActivityInfo(req);
            logger.info("测试结果: {}, {}", req, JSON.toJSONString(activity));
            Thread.sleep(1000);
        }
    }
}

模拟每隔一秒钟获取活动信息.

13:55:41.313 [main] INFO  com.thc.test.ApiTest - 测试结果: 10001, {"desc":"618 数码电器大促销","id":1000,"name":"618","startTime":1648360541243,"stock":{"total":1000,"used":1},"stopTime":1648360541243}
13:55:42.329 [main] INFO  com.thc.test.ApiTest - 测试结果: 10001, {"desc":"618 数码电器大促销","id":1000,"name":"618","startTime":1648360541243,"stock":{"total":1000,"used":11},"stopTime":1648360541243}
13:55:43.332 [main] INFO  com.thc.test.ApiTest - 测试结果: 10001, {"desc":"618 数码电器大促销","id":1000,"name":"618","startTime":1648360541243,"stock":{"total":1000,"used":21},"stopTime":1648360541243}
13:55:44.344 [main] INFO  com.thc.test.ApiTest - 测试结果: 10001, {"desc":"618 数码电器大促销","id":1000,"name":"618","startTime":1648360541243,"stock":{"total":1000,"used":31},"stopTime":1648360541243}
13:55:45.346 [main] INFO  com.thc.test.ApiTest - 测试结果: 10001, {"desc":"618 数码电器大促销","id":1000,"name":"618","startTime":1648360541243,"stock":{"total":1000,"used":41},"stopTime":1648360541243}
13:55:46.356 [main] INFO  com.thc.test.ApiTest - 测试结果: 10001, {"desc":"618 数码电器大促销","id":1000,"name":"618","startTime":1648360541243,"stock":{"total":1000,"used":52},"stopTime":1648360541243}
13:55:47.369 [main] INFO  com.thc.test.ApiTest - 测试结果: 10001, {"desc":"618 数码电器大促销","id":1000,"name":"618","startTime":1648360541243,"stock":{"total":1000,"used":62},"stopTime":1648360541243}
13:55:48.379 [main] INFO  com.thc.test.ApiTest - 测试结果: 10001, {"desc":"618 数码电器大促销","id":1000,"name":"618","startTime":1648360541243,"stock":{"total":1000,"used":72},"stopTime":1648360541243}
13:55:49.383 [main] INFO  com.thc.test.ApiTest - 测试结果: 10001, {"desc":"618 数码电器大促销","id":1000,"name":"618","startTime":1648360541243,"stock":{"total":1000,"used":82},"stopTime":1648360541243}
13:55:50.388 [main] INFO  com.thc.test.ApiTest - 测试结果: 10001, {"desc":"618 数码电器大促销","id":1000,"name":"618","startTime":1648360541243,"stock":{"total":1000,"used":92},"stopTime":1648360541243}

使用的库存在逐渐增加,

通过map结构的使用方式也可以看到,使用一个固定id来存放和获取对象,是非常关键的点。而且不只是在享元模式中使用,一些其他工厂模式、适配器模式、组合模式中都可以通过map结构存放服务供外部获取,减少ifelse的判断使用。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/782233.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号