абстрактный java enum - PullRequest
       9

абстрактный java enum

9 голосов
/ 12 февраля 2010

Я пишу библиотеку, которая должна полагаться на перечисления, но фактическое перечисление должно быть определено пользователем моей библиотеки.

В следующем примере для метода authorize требуются параметры типа enum Permission.

acl.authorize(userX, Permission.READ, Permission.WRITE)

Моя библиотека должна иметь возможность обрабатывать произвольные разрешения, определенные пользователем библиотеки. Но я не могу скомпилировать свою библиотеку без перечисления Permission. Поэтому мне нужно что-то вроде

abstract enum Permission

в моей библиотеке. Есть ли обходной путь для этого?

Ответы [ 2 ]

21 голосов
/ 12 февраля 2010

Я бы использовал интерфейс, который затем реализовал бы enum. Что-то вроде

public interface PermissionType{}

, который будет использоваться, например, клиент для определения перечисления, например

public enum Permission implements PermissionType
[...]

Тогда ваш API будет принимать параметры, используя тип PermissionType

1 голос
/ 12 февраля 2010

Вот шаги, которые я бы предложил.

  1. написать аннотацию - public @interface Permission
  2. заставляет пользователя аннотировать каждое из перечисленных им разрешений этой аннотацией:

    @Permission
    public enum ConcretePermissionEnum {..}
    
  3. Сделайте ваш authorize метод похожим на:

    public boolean authorize(User user, Enum... permissions) {
        for (Enum permission : permissions) {
           if (permission.getClass().isAnnotationPresent(Permission.class)){
              // handle the permission
           }
        }
    }
    

Если вы хотите, чтобы в перечислениях Permission были какие-то определенные методы, или просто нужен маркер, то вы можете сделать так, чтобы перечисления пользователей реализовывали ваш интерфейс (вместо того, чтобы аннотироваться):

interface PermissionInterface {..}
enum ConcretePermission implements PermissionInterface

Это позволит включить проверку во время компиляции, а не проверку во время выполнения, как в случае подхода с аннотациями, при этом сигнатура метода authorize выглядит следующим образом:

public boolean authorize(User user, PermissionInterface... permissions)
...