Я пишу библиотеку, которая должна полагаться на перечисления, но фактическое перечисление должно быть определено пользователем моей библиотеки.
В следующем примере authorize
метод требует параметров перечислимого типа Permission
.
acl.authorize(userX, Permission.READ, Permission.WRITE)
Моя библиотека должна смочь обработать произвольные полномочия, определенные пользователем библиотеки. Но я не могу скомпилировать свою библиотеку без a Permission
перечисление. Таким образом, мне было бы нужно что-то как
abstract enum Permission
в моей библиотеке. Существует ли обходное решение, чтобы сделать это?
Я бы использовал интерфейс, который затем реализовал бы перечисление. Что-то вроде
public interface PermissionType{}
который будет использоваться, например, клиентом для определения перечисления, такого как
public enum Permission implements PermissionType
[...]
Тогда ваш API будет принимать параметры, используя тип PermissionType
Вот шаги, которые я бы предложил.
public @interface Permission
заставить пользователя аннотировать каждое из своих перечислений разрешений этой аннотацией:
@Permission
public enum ConcretePermissionEnum {...}
Пусть ваш метод authorize
выглядит так:
public boolean authorize(User user, Enum... permissions) {
for (Enum permission : permissions) {
if (permission.getClass().isAnnotationPresent(Permission.class)){
// обрабатываем разрешение
}
}
}
Если вы хотите, чтобы ваши перечисления Permission имели некоторые специфические методы, или просто хотите "маркер", то вы можете сделать так, чтобы пользовательские перечисления реализовывали ваш интерфейс (вместо аннотации):
interface PermissionInterface {..}
enum ConcretePermission implements PermissionInterface
Это позволит осуществлять проверку во время компиляции, а не во время выполнения, как в случае с аннотацией, при этом сигнатура метода authorize
будет выглядеть так:
public boolean authorize(User user, PermissionInterface... permissions)