如何更好地表示用户权限?

5

在我的系统中,我有一个单一的类,其中有大量(20?)final booleans,定义了该用户类型拥有的权限。

有没有更好的方法来实现这个功能呢?

我相信有很多关于这方面的例子,但我不知道关键词是什么。


你能否贴上一些代码片段以更好地理解你正在尝试做什么? - Jose Diaz
6个回答

12

你可以利用枚举类型,例如:

public enum Permission {
    READ, WRITE;
}

public class User {

    private final EnumSet<Permission> permissions;

    public User(Permission... permissions) {
       this.permissions = EnumSet.copyOf(Arrays.asList(permissions));
    }

    public boolean hasPermission(Permission permission) {
        return permissions.contains(permission);
    }

    //...
}

User user = new User(Permission.READ, Permission.WRITE);

顺便说一下:这段代码无法编译,因为您创建了一个未初始化的 final 字段。 - Damian Leszczyński - Vash
3
+1,这就是我在给tdammers的回答中所说的意思。@Vash - 这完全没问题,该字段已在构造函数中初始化。 - Andrzej Doyle

8
创建一个名为Permission的类,并给每个User分配一组它们。如果用户的权限集合中包含某个权限,则该用户拥有该权限,否则没有。

他明确要求最终布尔值。 - Tim Büthe
5
@Tim:他明确要求比使用final布尔值更好的方式。 - sepp2k
2
不,他正在寻求比最终布尔值更好的方法。 - Arjan
一个特别好的方法是将Permission类作为枚举类型(除非应用程序在动态创建角色方面做了一些不寻常的事情,否则它在概念上可能已经是这样了)。然后,通过调用类似于EnumSet.contains(Permission.ADMIN)的东西,您可以获得非常清晰的代码。 - Andrzej Doyle
@Andrzej Doyle 当你有20个角色时,你需要检查20次写入EnumSet.Contains(Permission.ADMIN)。代码就不再非常清晰了。基于枚举的角色选项是非常有限的选择。 - Damian Leszczyński - Vash
显示剩余2条评论

5
您可以使用掩码来实现此功能。
public interface IPersmisions {

 public static final int NONE = 1 << 0;
 public static final int LEVEL1 = 1 << 1;
 public static final int LEVEL2 = 1 << 2;
 public static final int LEVEL3 = 1 << 3;
 public static final int LEVEL4 = 1 << 4;
 public static final int LEVEL5 = 1 << 5;
 public static final int LEVEL6 = 1 << 6;
 public static final int LEVEL7 = 1 << 7;
 public static final int LEVEL8 = 1 << 8;
 public static final int LEVEL9 = 1 << 9;
}

in used You add

int permisions = IPersmisions.NONE;

    public boolean checkPermission(int permission) {
        return (permissions & permission) != 0;
    }

    public void addPermission(int permission) {
            permissions = (permissions | permission);
    }

    public void removePermission(int permission) {
        permissions = (permissions & ~permission);
    }

您可以轻松地为用户设置一个组。
public interface IPermisionGroup extends IPermisions {

  public static final int LEVEL1_2_3 = LEVEL1 | LEVEL2 | LEVEL3; 
  public static final int LEVEL4_5_6 = LEVEL4 | LEVEL5 | LEVEL6; 
  public static final int LEVEL7_8_9 = LEVEL7 | LEVEL8 | LEVEL9; 

}

在代码中,您可以使用以下方式:

   user.addPermision(IPermisions.LEVEL1);

或者

   user.addPermision(IPermisions.LEVEL1 | IPermision.LEVEL2);

或者

user.addPermision(IPermisionGroup.LEVEL1_2_3);

1
在2010年的.NET中自己编写位掩码?你一定是在开玩笑吧。 - epochwolf
1
@eopchwolf:这有什么问题吗?顺便说一下,不是在.NET中,而是在Java中。 - Damian Leszczyński - Vash

4

@tdammers提出的完整示例:

class enum Permission {
    WRITE, READ, EXECUTE, GROUP, OWNER
}

public class User {
    protected Set<Permission> permissions;

    public User() {
        permissions = new EnumSet<Permission>();
    }

    public boolean hasPermission(Permission p) {
        return permissions.contains(p);
    }

    public void addPermisssion(Permission p) {
        permissions.add(p);
    }

    public void removePermisssion(Permission p) {
        permissions.remove(p);
    }
}

//usage
User u = new User();
u.addPermission(Permission.READ);
System.out.writeln(u.hasPermission(Permission.WRITE));
u.removePermission(Permission.READ);

0
如果您不了解关键字和语法,建议阅读有关Java的书籍或在线进行一些教程。然而,一个类可能看起来像这样:
public class User {

private final boolean admin, superuser, guest;

public User(boolean admin, boolean superuser, boolean guest) {
    this.admin = admin;
    this.superuser = superuser;
    this.guest = guest;
}

public boolean isAdmin() {
    return admin;
}

public boolean isSuperuser() {
    return superuser;
}

public boolean isGuest() {
    return guest;
}

// and so on
}

-1

多态性,而非条件语句。

class User {
    final Print print;
    User(Print print) {
        this.print = print;
    }
}

interface Print {
    void print();
}

class CanPrint implements Print {
    public void print() { do whatever it takes to print a user }
}

class CannotPrint implements Print {
    public void print() { throw null; }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接