Holder模式(Holder Pattern):公司员工权限管理系统实战案例分析

417 阅读15分钟

image.png

肖哥弹架构 跟大家“弹弹” 业务中设计模式的使用,需要代码关注

欢迎 点赞,点赞,点赞。

关注公号Solomon肖哥弹架构获取更多精彩内容

在一个大型公司中,员工根据其职位和部门被赋予不同的权限。这些权限可能包括访问敏感数据、审批财务报告、提交报销等。随着公司规模的增长和组织结构的复杂化,管理员工权限变得越来越重要。

2. 为什么要使用Holder设计模式

Holder模式允许我们将所有员工的权限信息集中存储和管理,确保权限数据的一致性和安全性,同时简化权限的维护和更新。

3. 标准Holder设计模式图

4. 业务Holder设计模式图

5. 业务代码参考

    import java.util.Collections;
    import java.util.HashMap;
    import java.util.HashSet;
    import java.util.Map;
    import java.util.Set;

    // 员工权限持有者
    class EmployeePermissionHolder {
        private static EmployeePermissionHolder instance;
        private Map<String, Set<String>> permissionsMap;

        private EmployeePermissionHolder() {
            permissionsMap = new HashMap<>();
            // 模拟从数据库加载权限数据
            loadPermissions();
        }

        public static EmployeePermissionHolder getInstance() {
            if (instance == null) {
                instance = new EmployeePermissionHolder();
            }
            return instance;
        }

        private void loadPermissions() {
            // 模拟加载权限
            permissionsMap.put("Manager_Finance", new HashSet<>(Set.of("create_invoice", "approve_expense")));
            permissionsMap.put("Employee_Marketing", new HashSet<>(Set.of("submit_expense", "view_report")));
            // 可以继续添加更多职位和权限
        }

        public Set<String> getPermissionsByPosition(String positionKey) {
            return permissionsMap.getOrDefault(positionKey, Collections.emptySet());
        }
    }

    // 员工类
    class Employee {
        private String name;
        private String positionKey;

        public Employee(String name, String positionKey) {
            this.name = name;
            this.positionKey = positionKey;
        }

        public String getName() {
            return name;
        }

        public String getPositionKey() {
            return positionKey;
        }

        public Set<String> getPermissions() {
            return EmployeePermissionHolder.getInstance().getPermissionsByPosition(positionKey);
        }
    }

    // 客户端使用示例
    public class CompanyApplication {
        public static void main(String[] args) {
            Employee manager = new Employee("张三", "Manager_Finance");
            Employee marketingEmployee = new Employee("李四", "Employee_Marketing");

            System.out.println("员工 " + manager.getName() + " 的权限包括: " + manager.getPermissions());
            System.out.println("员工 " + marketingEmployee.getName() + " 的权限包括: " + marketingEmployee.getPermissions());
        }
    }

6. 使用Holder设计模式的好处

  • 集中管理:所有员工的权限信息都在EmployeePermissionHolder中集中管理,便于维护和更新。
  • 权限一致性:确保所有员工的权限信息是一致的,避免权限管理上的混乱。
  • 易于扩展:新增职位或部门的权限时,只需在EmployeePermissionHolder中更新。

7. 其他使用Holder设计模式场景参考

  • 多角色权限系统:如网站或应用程序中的用户角色权限管理。
  • 资源分配:如云服务环境中对不同用户或组的资源分配。

8. 可参考开源框架

  • Spring Security:虽然主要用于安全框架,但其权限管理部分可以作为如何实现灵活权限管理的参考。

9. 使用与不使用Holder的区别

以下案例的情况下,如果只是简单地需要一个全局访问点来获取配置信息,使用单例模式可能就足够了。然而,引入Holder模式(或称为Holder Pattern、Holder Singleton Pattern)提供了一些额外的优势,特别是在处理延迟加载(Lazy Loading)和隐藏实现细节方面。

  • 纯单例模式
    public class LoggerConfig {
        private static LoggerConfig instance;
        private String logLevel;

        private LoggerConfig() {
            logLevel = loadLogLevel(); // 立即加载
        }

        public static LoggerConfig getInstance() {
            if (instance == null) {
                instance = new LoggerConfig();
            }
            return instance;
        }

        private String loadLogLevel() {
            // 加载日志级别
            return "INFO";
        }

        public String getLogLevel() {
            return logLevel;
        }
    }
  • 使用Holder模式
    public class LoggerConfigHolder {
        private static class Holder {
            private static final LoggerConfig INSTANCE = new LoggerConfig();
        }

        public static LoggerConfig getInstance() {
            return Holder.INSTANCE;
        }
    }

    private class LoggerConfig {
        private String logLevel;

        private LoggerConfig() {
            // 构造函数私有,外部无法直接创建实例
            logLevel = loadLogLevel();
        }

        private String loadLogLevel() {
            // 加载逻辑可以在这里实现延迟加载
            return "INFO";
        }
    }
  • 使用Holder模式有如下场景
  1. 延迟加载
    • Holder模式:可以实现延迟加载,即只有在真正需要配置时才进行加载。这可以提高应用程序的启动速度,尤其是当配置加载成本较高时(例如,需要从远程服务器加载配置)。
  2. 隐藏实现细节
    • Holder模式:通过引入一个持有者类,可以将配置对象的创建和初始化逻辑隐藏起来。这样,其他部分的代码只需要与持有者交互,而不需要知道具体的配置类是如何实现的。
  3. 分离关注点
    • Holder模式:将配置的获取逻辑和配置对象本身的逻辑分离。这有助于进一步降低系统的耦合度,使得配置对象的变化不会影响到获取配置的逻辑。
  4. 灵活性和扩展性
    • Holder模式:如果未来需要支持多种类型的配置或者需要根据不同条件加载不同的配置,Holder模式可以更容易地进行扩展。

总结

Holder模式在公司员工权限管理系统中的应用,提供了一种集中和一致的方式来管理员工权限,增强了系统的灵活性和可维护性。

历史热点文章