简化字段访问.我应该使用反射还是有Java 8的解决方案



我有下面的例子类:

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方法)

如果有一个简单而好的解决方案,那将是很酷的,:)

提前感谢!

如何使用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. 这2个Map将产生一些开销。(可能很重要,因为当应用程序处于活动状态时,这些Permission对象将每秒创建100-1000次)

我不会去管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;}
}

或者当你使用枚举时,你可以完全放弃布尔方法,因为你可以开始比较enum的权限(但如果你要做权限的层次结构(例如读写),那就不能很好地扩展)。在这种情况下,类是更好的

相关内容

  • 没有找到相关文章

最新更新