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

IT技术2年前 (2022)更新 IT大王
0

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、享元模式与单例模式的区别

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

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

© 版权声明
好牛新坐标 广告
版权声明:
1、IT大王遵守相关法律法规,由于本站资源全部来源于网络程序/投稿,故资源量太大无法一一准确核实资源侵权的真实性;
2、出于传递信息之目的,故IT大王可能会误刊发损害或影响您的合法权益,请您积极与我们联系处理(所有内容不代表本站观点与立场);
3、因时间、精力有限,我们无法一一核实每一条消息的真实性,但我们会在发布之前尽最大努力来核实这些信息;
4、无论出于何种目的要求本站删除内容,您均需要提供根据国家版权局发布的示范格式
《要求删除或断开链接侵权网络内容的通知》:https://itdw.cn/ziliao/sfgs.pdf,
国家知识产权局《要求删除或断开链接侵权网络内容的通知》填写说明: http://www.ncac.gov.cn/chinacopyright/contents/12227/342400.shtml
未按照国家知识产权局格式通知一律不予处理;请按照此通知格式填写发至本站的邮箱 wl6@163.com

相关文章