我有下面的例子类:
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
返回对应的布尔字段的值
正如你在示例代码中看到的:我已经写了很多代码,为了实现这个目标,我不知道如何简化事情。
我能想到两件事:
在构造函数内部调用
super(READ, UPDATE, DELETE);
,并让超类通过反射处理isGranted(...)
方法。只要在构造函数中调用
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; }
}
这至少节省了一些代码,但是:
- 比上面的版本短不了多少,
- 这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的权限(但如果你要做权限的层次结构(例如读写),那就不能很好地扩展)。在这种情况下,类是更好的