简体   繁体   English

简化现场访问。 我应该使用反射还是Java 8解决方案?

[英]Simplify field access. Should I use reflection or is there a Java 8 solution?

I've got the following example class: 我有以下示例类:

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; }
}

And I want to simplify things a bit, because there will be created much more of these classes. 我想简化一些事情,因为将创建更多此类。 The schema is always the same: 模式始终是相同的:

  • some public final static String Permissions (must be accessible inside Annotations) 一些public final static String权限(必须在Annotations中可以访问)
  • each of those Permissions has a corresponding boolean field 每个权限都有一个对应的布尔字段
  • method isGranted returns the value of the corresponding boolean field 方法isGranted返回相应的布尔字段的值

As you can see in the example code: I've go to write a lot of code, to achieve this and I can't figure out how to simplify things. 正如您在示例代码中所看到的:为了实现这一点,我已经写了很多代码,但我不知道如何简化。

There are 2 things I could imagine: 我可以想象两件事:

  1. call super(READ, UPDATE, DELETE); 调用super(READ, UPDATE, DELETE); inside the constructor and let the super class handle the isGranted(...) method via reflection. 在构造函数中,让超类通过反射处理isGranted(...)方法。

  2. just call super(); 只需调用super(); inside the constructor and the class will find the public static final String fields itself and create the fields and getter/setter dynamically, because I don't need them in my code - they just have to be there at runtime. 在构造函数和类内部,它们将找到public static final String字段本身,并动态创建字段和getter / setter,因为我的代码中不需要它们-它们只需要在运行时就存在。

Or is there any cool new feature in Java 8, so I can do this: 还是Java 8中有任何很棒的新功能,所以我可以这样做:

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

So I could dynamically invoke the corresponding getter method, like: 因此,我可以动态调用相应的getter方法,例如:

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

(or even using the field, instead of the getter method) (甚至使用字段,而不是使用getter方法)

It would be cool, if there's a simple and nice solution for this :) 如果有一个简单而不错的解决方案,那将很酷:)

Thanks in advance! 提前致谢!

How about using Java 8 @FunctionalInterface Supplier and @FunctionalInterface Consumer ? 如何使用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; }
}

This does at least save some code, but: 这至少可以保存一些代码,但是:

  1. it's not much shorter than the version above, and 它比上面的版本短很多,并且
  2. those 2 Map s will generate some overhead. 那两个Map会产生一些开销。 (could be important, since those Permission objects will get created about 100-1000 times per second when the application is live) (这很重要,因为当应用程序处于活动状态时,每秒将创建大约100-1000次这些Permission对象)

I'd leave Java8 alone and just head for design patterns, strategy to be exact. 我将不理会Java8,而只是去设计模式,确切地说就是策略。

Either you can derive a subclass per each case or you can introduce an enum. 您可以为每种情况派生一个子类,也可以引入一个枚举。 Both are type safe, testable and you're not building another String centric application. 两者都是类型安全的,可测试的,并且您没有在构建另一个以String为中心的应用程序。

So you either end up with classes like 所以你要么以类似

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

Or with something like 或类似

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

Or while you're with enums, you could resign from boolean methods at all, as you can just start comparing persmissions with enum (but that does not scale well, if you're going to do a hierarchies of permissions (eg ReadWrite). In that case classes are better 或者,当您使用枚举时,您可以从布尔方法中完全退出,因为您可以开始将权限与枚举进行比较(但是如果您要进行权限层次结构(例如ReadWrite),扩展性就不好。在这种情况下,上课更好

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM