У меня есть ситуация, когда я определяю роли безопасности для организации. Выбор представляет собой набор известных перечисленных значений по умолчанию и возможность любого количества пользовательской роли. Роли определяют разрешения, которые имеют сотрудники в организации. Например, пользователь может быть;
public enum Role
{
Owner, Administrator, User, Guest;
}
Тем не менее, организации также могут потребоваться собственные пользовательские роли (например, PowerUser). Я ищу лучший способ объявить объект, который имеет известный перечислимый список значений (это перечисление), но с возможностью предоставления любого количества пользовательских значений (это класс).
Наивный подход будет заключаться в следующем (добавление пользовательского значения перечисления):
public enum Role
{
Owner, Administrator, User, Guest, Custom;
public BaseRole asRole()
{
//switch statement returning the BaseRole depending on the enum value.
}
}
public class BaseRole
{
Set<Permission> permissions;
}
Проблема с этой опцией заключается в том, что код клея станет очень многословным, если выбрано значение enum value custom. Поскольку пользовательское значение, которое содержит всю возможную настраиваемую роль, будет вести себя по-другому, что для других значений каждой функции, принимающей роль, потребуется специальный клей для обработки пользовательских.
В идеале, что-то вроде этого, вероятно, будет лучшим:
public enum Role
{
Owner, Administrator, User, Guest, Set<Custom>;
}
редактировать:
для справки, класс пользователя будет
public class User
{
Set<Role> roles;
}
Это решение, с которым я пошел.
public interface Role
{
String getName();
}
public enum StandardRole implements Role
{
Owner, Administrator, User, Guest;
@Override
public String getName()
{
return this.name();
}
}
public class CustomRole implements Role
{
private String name;
public CustomRole(String name)
{
this.name = name;
}
@Override
public String getName()
{
return this.name;
}
}
public class User
{
Set<Role> roles;
}
Возможным решением было бы оглянуться назад в реализациях псевдо-enum в версиях Java pre- enum
. Например:
public class Role {
public static final Role OWNER = new Role("OWNER");
public static final Role ADMIN = new Role("ADMIN");
public static final Role USER = new Role("USER");
public static final Role GUEST = new Role("GUEST");
private String name;
// getter, setter, constructor, toString(), hashCode(), equals()
}
Поэтому всякий раз, когда требуется Role
, вы можете использовать конечные поля:
Role r = Role.OWNER;
И все же определите пользовательские:
Role r = new Role("Cook");
С некоторой осторожностью, он может даже позволить ==
равенства проверки между переменным и предопределенными значениями, но я бы посоветовал против него (использование equals()
всегда).
Возможно, что вы ищете EnumSet?
http://docs.oracle.com/javase/7/docs/api/java/util/EnumSet.html