首页 > 其他分享 >软件设计模式白话文系列(十一)享元模式

软件设计模式白话文系列(十一)享元模式

时间:2022-11-16 14:44:47浏览次数:47  
标签:享元 admin RoleFactory 软件设计 private 对象 模式 public

1、描述

以共享的方法高效地支持大量细粒度对象的复用。在 Java 中,通过提前初始化对象或者首次使用后记录对象,后续使用就可以复用对象来实现享元模式。类似缓存技术。

2、模式结构

  • 享元对象:可复用对象。

  • 享元工厂类:享元对象的工厂类,负责创建、储存享元对象。客户端从工厂类请求对象有则返回,没有则创建

    一个放入工厂类。例如 String 类的缓存池和数据库的连接池。

3、实现逻辑

享元模式实现的关键是需要区分对象的内蕴状态和外蕴状态。简单点解释就是,内蕴状态就是可被共享的部分;外蕴状态就是不可共享的部分,需要客户端提供的部分。Java 中实现享元模式,就是把内蕴部分剥离出来静态化,客户端调用时提供外蕴状态(当然对象可以没有外蕴部分)。

4、实战代码

RBAC 模型基于角色的权限控制。通过角色关联用户,角色关联权限的方式间接赋予用户权限。

我们知道对于用户来讲,每个用户都有自己的 编号、姓名,但是会存在多个用户都是同一个角色。在这里编号、姓名就属于外蕴状态,而角色就属于内蕴状态。

/**
 * 享元对象
 *
 * @author Eajur.Wen
 * @version 1.0
 * @date 2022-11-15 19:01:20
 */
@Data
public class Role {
    private String name;

    private List<String> permissions;
}

/**
 * 业务对象
 *
 * @author Eajur.Wen
 * @version 1.0
 * @date 2022-11-15 19:00:57
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Member {

    private Long id;
    private String name;

    private Role role;
}

/**
 * 享元工厂类
 * 这里结合静态内部类单例模式实现 RoleFactory
 *
 * @author Eajur.Wen
 * @version 1.0
 * @date 2022-11-15 19:04:47
 */
public class RoleFactory {
    private static Map<String, Role> roleMap = new HashMap<>();

    public RoleFactory() {
        Role admin = new Role();
        admin.setName("admin");
        admin.setPermissions(List.of("add", "update", "select", "delete"));

        Role user = new Role();
        user.setName("user");
        user.setPermissions(List.of("select"));

        roleMap.put("admin", admin);
        roleMap.put("user", user);
    }

    public Role getRole(String name) {
        return roleMap.get(name);
    }

    public static final RoleFactory getInstance() {
        return SingletonHolder.INSTANCE;
    }

    private static class SingletonHolder {
        private static final RoleFactory INSTANCE = new RoleFactory();
    }
}

/**
 * 测试类
 *
 * @author Eajur.Wen
 * @version 1.0
 * @date 2022-11-15 19:13:48
 */
public class Client {
    public static void main(String[] args) {
        // 创建 10 个 Admin 用户
        for (int i = 0; i < 10; i++) {
            Member member = new Member((long) i,
                    "admin" + i,
                    RoleFactory.getInstance().getRole("admin"));
            System.out.println(member);
        }
        System.out.println("------------------");
        // 创建 100 个 User 用户
        for (int i = 0; i < 100; i++) {
            Member member = new Member((long) i,
                    "user" + i,
                    RoleFactory.getInstance().getRole("user"));
            System.out.println(member);
        }
    }
}

这样我们通过提前创建 role 对象,使得频繁创建 member 对象时复用 role 对象,减少了 role 对象的频繁创建与销毁,大大节约了内存占用。

5、适用场景

相同对象或者相似对象需要频繁创建时,适合使用享元模式。

6、享元模式与单例模式的区别

单例模式的目的是为了确保一个类只存在一个对象,需要自行实例化并提供全局访问方法。

享元模式的目的是为了对对象内蕴部分的复用,无需保证一个类只存在一个对象。

标签:享元,admin,RoleFactory,软件设计,private,对象,模式,public
From: https://www.cnblogs.com/eajur/p/16895857.html

相关文章

  • HeadFirst设计模式-观察者模式
    观察者模式:定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,他的所有依赖者都会收到通知并自动更新。   Java代码 c++代码#pragmaonce#include"......
  • 05.原型模式
    原型模式PrototypePattern用于创建重复的对象,同时又能保证性能。当需要创建一个与已有对象类似的对象,或者当创建对象的成本比克隆更高时,使用原型模式通过实现Clone方......
  • js闭包问题、js事件循环机制、async与defer、同步与异步模式
    js闭包问题定义:闭包就是有权访问其他函数作用域内的其他变量的函数。实现机制:在访问变量的函数中return一个匿名函数,这时匿名函数的作用域链将指向该函数的作用域。!!!由于......
  • (七)原型模式
    1概述原型模式(Prototype),用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。原型模式其实就是从一个对象再创建另外一个可定制的对象,而且不需知道任何......
  • 软件设计复习一统一建模语言基础知识(1)
    一、UML(UnifiedModelLanguage)统一建模语言是用图形、符号表达的语言,它的结构由视图、图、模型元素和通用机制四部分组成。首先视图(View)有逻辑视图、开发视图......
  • rabbitmq集群部署-镜像模式
    一、环境RabbitMQ与Erlang的兼容关系详见:https://www.rabbitmq.com/which-erlang.htmlrabbitmq集群最好是奇数节点,所以一般需要3台设备以上。操作系统:CentOS7Erlang:erl......
  • (五)工厂方法模式
    工厂方法模式(FactoryMethod),定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。与简单工厂模式的区别:简单工厂模式的最大......
  • js异步编程的三种模式
    写在前面javascript语言的执行环境是"单线程"(singlethread),就是指一次只能完成一件任务。如果有多个任务,就必须排队,等前面一个任务完成,再执行后面一个任务,以此类推。......
  • RabbitMq简单模式
    RabbitMq简单模式定义一个生产者,负责发送消息到队列中/***@authorzjh*生产者发信息*/publicclassProducer{/***队列名称*/public......
  • Qt音视频开发02-海康sdk解码(支持句柄/回调/gpu模式/支持win/linux)
    一、前言为何还要选用使用海康sdk,之前不是ffmpeg已经牛皮吹上天了吗?这个问题问得好,那是因为无论ffmpeg也好还是vlc/mpv之类的,都是实现的播放相关,不同的监控硬件厂家对应设......