0

我有以下示例类:

public class MyPermission implements Permission {
    public static final String READ = "read";
    public static final String UPDATE = "update";
    public static final String DELETE = "delete";

    @Override
    public boolean isGranted(String permission) {
        switch(permission) {
        case READ: return read;
        case UPDATE: return update;
        case DELETE: return delete;
        default: return false;
        }
    }

    private boolean read;
    public boolean isRead() { return read; }
    public void setRead(boolean read) { this.read = read; }

    private boolean update;
    public boolean isUpdate() { return update; }
    public void setUpdate(boolean update) { this.update = update; }

    private boolean delete;
    public boolean isDelete() { return delete; }
    public void setDelete(boolean delete) { this.delete = delete; }
}

我想稍微简化一下,因为会创建更多这些类。架构始终相同:

  • 一些public final static String权限(必须在注释中可访问)
  • 这些权限中的每一个都有一个相应的布尔字段
  • 方法isGranted返回相应的布尔字段的值

正如您在示例代码中看到的那样:我已经编写了很多代码来实现这一点,但我不知道如何简化事情。

我可以想象两件事:

  1. 在构造函数内部调用super(READ, UPDATE, DELETE);,让超类isGranted(...)通过反射处理方法。

  2. 只需super();在构造函数内部调用,该类将public static final String自行查找字段并动态创建字段和 getter/setter,因为我的代码中不需要它们 - 它们只需要在运行时存在。

或者 Java 8 中是否有任何很酷的新功能,所以我可以这样做:

public MyPermission() {
  super(new HashMap<String, GetterMethod>() {{
    put(READ, this::isRead);
    put(UPDATE, this::isUpdate);
    put(DELETE, this::isDelete);
  }});
}

所以我可以动态调用相应的getter方法,比如:

public boolean isGranted(String permission) {
  return permissionMap.get(permission).execute();
}

(甚至使用字段,而不是 getter 方法)

如果有一个简单而好的解决方案,那就太酷了:)

提前致谢!

4

2 回答 2

0

我会不理会Java8,而是直接使用设计模式,确切地说是策略。

您可以为每种情况派生一个子类,也可以引入一个枚举。两者都是类型安全的、可测试的,并且您不会构建另一个以字符串为中心的应用程序。

所以你要么最终得到像这样的课程

WritePermission extends BasePermission...
ReadPermission extends BasePermission...
BasePermission implements Permission...

或类似的东西

public enum Permissions implements Permission {
  WRITE {public boolean isWrite{return true;}},
  READ {...}, 
  ...
  public boolean isWrite{return false;}
}

或者,当您使用枚举时,您可以完全放弃布尔方法,因为您可以开始将权限与枚举进行比较(但如果您要进行权限层次结构(例如 ReadWrite),则不能很好地扩展。在这种情况下,课程会更好

于 2014-07-14T18:17:09.497 回答
0

如何使用 Java 8@FunctionalInterface Supplier@FunctionalInterface Consumer

public abstract class Permission {
    Map<String, Supplier<Boolean>> permissionGetterMap = new HashMap<>();
    Map<String, Consumer<Boolean>> permissionSetterMap = new HashMap<>();

    public void put(String permission, Supplier<Boolean> getter, Consumer<Boolean> setter) {
        permissionGetterMap.put(permission, getter);
        permissionSetterMap.put(permission, setter);
    }

    public boolean isGranted(String permission) {
        return permissionGetterMap.get(permission).get();
    }

    public void setPermission(String permission, boolean granted) {
        permissionSetterMap.get(permission).accept(granted);
    }
}



public class MyPermission extends Permission {
    public static final String READ = "read";
    public static final String UPDATE = "update";
    public static final String DELETE = "delete";

    public MyPermission() {
        put(READ, this::isRead, this::setRead);
        put(UPDATE, this::isUpdate, this::setUpdate);
        put(DELETE, this::isDelete, this::setDelete);
    }

    private boolean read;
    public boolean isRead() { return read; }
    public void setRead(boolean read) { this.read = read; }

    private boolean update;
    public boolean isUpdate() { return update; }
    public void setUpdate(boolean update) { this.update = update; }

    private boolean delete;
    public boolean isDelete() { return delete; }
    public void setDelete(boolean delete) { this.delete = delete; }
}

这至少可以节省一些代码,但是:

  1. 它并不比上面的版本短多少,并且
  2. 那些 2Map秒会产生一些开销。(可能很重要,因为Permission当应用程序运行时,这些对象每秒会创建大约 100-1000 次)
于 2014-07-14T02:22:30.140 回答