经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » 设计模式 » 查看文章
软件设计模式白话文系列(十一)享元模式
来源:cnblogs  作者:Eajur  时间:2022/11/17 9:13:23  对本文有异议

1、描述

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

2、模式结构

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

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

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

3、实现逻辑

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

4、实战代码

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

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

  1. /**
  2. * 享元对象
  3. *
  4. * @author Eajur.Wen
  5. * @version 1.0
  6. * @date 2022-11-15 19:01:20
  7. */
  8. @Data
  9. public class Role {
  10. private String name;
  11. private List<String> permissions;
  12. }
  13. /**
  14. * 业务对象
  15. *
  16. * @author Eajur.Wen
  17. * @version 1.0
  18. * @date 2022-11-15 19:00:57
  19. */
  20. @Data
  21. @NoArgsConstructor
  22. @AllArgsConstructor
  23. public class Member {
  24. private Long id;
  25. private String name;
  26. private Role role;
  27. }
  28. /**
  29. * 享元工厂类
  30. * 这里结合静态内部类单例模式实现 RoleFactory
  31. *
  32. * @author Eajur.Wen
  33. * @version 1.0
  34. * @date 2022-11-15 19:04:47
  35. */
  36. public class RoleFactory {
  37. private static Map<String, Role> roleMap = new HashMap<>();
  38. public RoleFactory() {
  39. Role admin = new Role();
  40. admin.setName("admin");
  41. admin.setPermissions(List.of("add", "update", "select", "delete"));
  42. Role user = new Role();
  43. user.setName("user");
  44. user.setPermissions(List.of("select"));
  45. roleMap.put("admin", admin);
  46. roleMap.put("user", user);
  47. }
  48. public Role getRole(String name) {
  49. return roleMap.get(name);
  50. }
  51. public static final RoleFactory getInstance() {
  52. return SingletonHolder.INSTANCE;
  53. }
  54. private static class SingletonHolder {
  55. private static final RoleFactory INSTANCE = new RoleFactory();
  56. }
  57. }
  58. /**
  59. * 测试类
  60. *
  61. * @author Eajur.Wen
  62. * @version 1.0
  63. * @date 2022-11-15 19:13:48
  64. */
  65. public class Client {
  66. public static void main(String[] args) {
  67. // 创建 10 个 Admin 用户
  68. for (int i = 0; i < 10; i++) {
  69. Member member = new Member((long) i,
  70. "admin" + i,
  71. RoleFactory.getInstance().getRole("admin"));
  72. System.out.println(member);
  73. }
  74. System.out.println("------------------");
  75. // 创建 100 个 User 用户
  76. for (int i = 0; i < 100; i++) {
  77. Member member = new Member((long) i,
  78. "user" + i,
  79. RoleFactory.getInstance().getRole("user"));
  80. System.out.println(member);
  81. }
  82. }
  83. }

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

5、适用场景

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

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

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

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

原文链接:https://www.cnblogs.com/eajur/p/16895857.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号