面向对象中的用户权限设计:嵌入式方法与程序执行控制



我对这个问题很困惑。

比如说,我必须设计一个面向对象系统,其中管理员是唯一可以在学院注册新生的用户。现在,系统(显然)有了其他用户。如何控制这些特权仅在用户是管理员时才适用?

我想到了两种可能性:将这些角色作为函数嵌入到与Student类通信的Admin类中,或者只是在程序执行中控制新学生的注册,例如:

if(user_type() == 'a') register_student(); // a type means an admin user
else cout << "Access denied";
...

有几种方法可以做到这一点:

if( user->has_permission( REGISTER_STUDENT ) ) {
  register_student();
}

询问用户实例是否有注册学生的权限。另一种方式:

 if( user->in_role( ROLE_ADMIN ) ) {
   register_student();
 }

我对代码的问题是,它暴露了如何确定管理员角色的内部细节。对于新的维护者来说,字母a最终会失去上下文,变得毫无意义;然而,ROLE_ADMIN/REGISTER_STUDENT常量明确了代码的意图,而不需要额外的注释。

执行注册并不是User类或Admin类的真正责任。Student注册自己是有意义的:

 if( user->in_role( ROLE_ADMIN ) ) {
   student->register();
 }

我希望在Controller类中看到这段代码。Controller类将能够检查用户界面对象以确定:

  • 当前哪个学生被选中
  • 用户从界面中选择了什么选项
  • 用户在
  • 中的角色

您可以实现以下内容:

if( user->is_admin() ) {
  student->register();
}

虽然代码非常清晰,但它不太灵活,因为您可能希望保留以下可能性:

if( controller->can_execute( user, action ) ) {
  action->execute();
}
else {
  controller->execute_error( user, action );
}

这提供了一个更加灵活的系统,可以动态地将角色分配给操作。例如,您可以将方法student->register()映射到ROLE_ADMIN。这使得整个应用程序中的所有安全约束都集中在一个位置,大大简化了维护。

还可以进一步简化为:

controller->execute( user, action );

那么execute方法将类似于:

void execute( User user, Action action ) {
  if( can_execute( user, action ) ) {
    action->execute();
  }
  else {
    error( user, action );
  }
}
bool can_execute( User user, Action action ) {
  return user->is_in_role( action->get_role() );
}

权限错误如何显示的实现细节(对话框与cout)现在被抽象。此外,错误消息可以更全面,例如:

"User registration is restricted to the administrator role."

编码为以下字符串:

"%s is restricted to the %s role."

控制器类可以自动替换%s

相关内容

最新更新