首页 > 编程语言 >重学Java设计模式-结构型模式-享元模式

重学Java设计模式-结构型模式-享元模式

时间:2023-03-31 16:46:28浏览次数:49  
标签:享元 重学 10001 1592130919931 模式 分享 设计模式 id stock

重学Java设计模式-结构型模式-享元模式

内容摘自:https://bugstack.cn/md/develop/design-pattern/2020-06-14-重学 Java 设计模式《实战享元模式》.html#重学-java-设计模式-实战享元模式「基于redis秒杀-提供活动与库存信息查询场景」

享元模式介绍

享元模式,图片来自 refactoringguru.cn

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

另外享元模式可以分为在服务端和客户端,一般互联网H5和Web场景下大部分数据都需要服务端进行处理,比如数据库连接池的使用、多线程线程池的使用,除了这些功能外,还有些需要服务端进行包装后的处理下发给客户端,因为服务端需要做享元处理。但在一些游戏场景下,很多都是客户端需要进行渲染地图效果,比如;树木、花草、鱼虫,通过设置不同元素描述使用享元公用对象,减少内存的占用,让客户端的游戏更加流畅。

在享元模型的实现中需要使用到享元工厂来进行管理这部分独立的对象和共享的对象,避免出现线程安全的问题。

案例场景模拟

场景模拟;秒杀场景下商品查询

在这个案例中我们模拟在商品秒杀场景下使用享元模式查询优化

你是否经历过一个商品下单的项目从最初的日均十几单到一个月后每个时段秒杀量破十万的项目。一般在最初如果没有经验的情况下可能会使用数据库行级锁的方式下保证商品库存的扣减操作,但是随着业务的快速发展秒杀的用户越来越多,这个时候数据库已经扛不住了,一般都会使用redis的分布式锁来控制商品库存。

同时在查询的时候也不需要每一次对不同的活动查询都从库中获取,因为这里除了库存以外其他的活动商品信息都是固定不变的,以此这里一般大家会缓存到内存中。

这里我们模拟使用享元模式工厂结构,提供活动商品的查询。活动商品相当于不变的信息,而库存部分属于变化的信息。

享元模式重构代码

接下来使用享元模式来进行代码优化,也算是一次很小的重构。

享元模式一般情况下使用此结构在平时的开发中并不太多,除了一些线程池、数据库连接池外,再就是游戏场景下的场景渲染。另外这个设计的模式思想是减少内存的使用提升效率,与我们之前使用的原型模式通过克隆对象的方式生成复杂对象,减少rpc的调用,都是此类思想。

1. 工程结构

itstack-demo-design-11-02
└── src
    ├── main
    │   └── java
    │       └── org.itstack.demo.design
    │           ├── util
    │           │	└── RedisUtils.java	
    │           ├── Activity.java
    │           ├── ActivityController.java
    │           ├── ActivityFactory.java
    │           └── Stock.java
    └── test
        └── java
            └── org.itstack.demo.test
                └── ApiTest.java

享元模式模型结构

享元模式模型结构

  • 以上是我们模拟查询活动场景的类图结构,左侧构建的是享元工厂,提供固定活动数据的查询,右侧是Redis存放的库存数据。
  • 最终交给活动控制类来处理查询操作,并提供活动的所有信息和库存。因为库存是变化的,所以我们模拟的RedisUtils中设置了定时任务使用库存。

2. 代码实现

2.1 活动信息

/**
 * 博客:https://bugstack.cn - 沉淀、分享、成长,让自己和他人都能有所收获!
 * 公众号:bugstack虫洞栈
 * Create by 小傅哥(fustack) @2020
 */
public class Activity {

    private Long id;        // 活动ID
    private String name;    // 活动名称
    private String desc;    // 活动描述
    private Date startTime; // 开始时间
    private Date stopTime;  // 结束时间
    private Stock stock;    // 活动库存
    
    // ...get/set
}
  • 这里的对象类比较简单,只是一个活动的基础信息;id、名称、描述、时间和库存。

2.2 库存信息

public class Stock {

    private int total; // 库存总量
    private int used;  // 库存已用
    
    // ...get/set
}
  • 这里是库存数据我们单独提供了一个类进行保存数据。

2.3 享元工厂

/**
 * 博客:https://bugstack.cn - 沉淀、分享、成长,让自己和他人都能有所收获!
 * 公众号:bugstack虫洞栈
 * Create by 小傅哥(fustack) @2020
 */
public class ActivityFactory {

    static Map<Long, Activity> activityMap = new HashMap<Long, Activity>();

    public static Activity getActivity(Long id) {
        Activity activity = activityMap.get(id);
        if (null == activity) {
            // 模拟从实际业务应用从接口中获取活动信息
            activity = new Activity();
            activity.setId(10001L);
            activity.setName("图书嗨乐");
            activity.setDesc("图书优惠券分享激励分享活动第二期");
            activity.setStartTime(new Date());
            activity.setStopTime(new Date());
            activityMap.put(id, activity);
        }
        return activity;
    }

}

相关文章

  • 大端模式和小端模式
    1.定义这是个老生常谈的问题,定义大家都懂:大端模式:数据低位存放在内存高位小端模式:数据高位存放在内存高位 2.数据高低位VS地址高低位比如一个十进制数字:12345678数据低位就是数据的右边,数据高位就是数据的左边;地址低位就是地址的左边,地址高位就是地址的右边。假如一......
  • 深入探讨:LBS是一种工具而非一种模式
    移动互联网的快速发展,带动着移动互联网应用的不断创新。从2010起,LBS的概念就在中国迅速兴起,但到了2011年底提供LBS服务的企业从最多50家已经降至仅剩15家。投行在看好移动互联网的同时又对LBS模式产生了质疑,最后很多业内人士纷纷表示LBS+O2O会更有发展潜力。在经过2011年在LBS领域......
  • 消费者和生产者模式
    classProductFactory{//定义库存最大privateintstock=10;privateLinkedList<String>products;publicProductFactory(){this.products=newLinkedList<>();}publicsynchronizedvoidproductsStock(Stringprodu......
  • 观察者模式(Observer)
    1,观察者模式  观察者模式是一种行为设计模式,允许你定义一种订阅机制,可在对象事件发生时通知多个“观察”该对象的其他对象。  又被称为发布-订阅(Publish/Subscribe)模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态变化时,会......
  • Spine在Unity 的URP模式下,描边的坑。
    在urp模式下,spine描边需要特殊处理,首先去。官网下载他们的urp拓展包,然后通过packagemanager导入到项目。打开包里outlineshadersurp场景。发现他们实现这个场景的时候,是在spine动画下面套了一个outline对象,这个outline对象有一个脚本叫做renderexistingmesh。将这个脚本......
  • 责任链模式
    概述《设计模式》一书中对于“责任链模式”的意图描述如下:使多个对象有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止一般的UML结构图如下所示:其中,Handler将会包含直接后继处理类succ......
  • 设计模式(三十)----综合应用-自定义Spring框架-自定义Spring IOC-定义bean、注册表相
    现要对下面的配置文件进行解析,并自定义Spring框架的IOC对涉及到的对象进行管理。<?xmlversion="1.0"encoding="UTF-8"?><beans>  <beanid="userService"class="com.itheima.service.impl.UserServiceImpl">    <propertyname=&qu......
  • IOS中KVO模式的解析与应用
    最近老翁在项目中多处用到了KVO,深感这种模式的好处。现总结如下:一、概述KVO,即:Key-ValueObserving,它提供一种机制,当指定的对象的属性被修改后,则对象就会接受到通知。简单的说就是每次指定的被观察的对象的属性被修改后,KVO就会自动通知相应的观察者了。KVO其实也是“观察者”设计模......
  • (二十六)访问者模式
    1.概述访问者模式(Visitor),表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。2.示例Visitor类,为该对象结构中ConcreteElement的每一个类声明一个Visit操作。Visitor.javapublicabstractclassVisitor{......
  • 直线模组常用的驱动模式有哪些?
    直线模组是工业生产中经常用到的直线运动单元,其驱动方式有很多种,但常用的驱动方式通常有两种,一种是滚珠丝杆传动,另一种是同步带传动。滚珠丝杆传动方式的特点是重复定位精度较高,最高精度可达±0.005mm,并且负载一般也比较大,在工业生产中通常被应用于对精度有一定要求的生产过程中。......