【发布时间】:2021-03-26 18:39:06
【问题描述】:
我有一个不知道如何解决的设计问题。
我创建了一个评估解析表达式的Evaluator 类。表达式的形状为amount > 50。运算符用于了解必须创建哪个谓词。然后,将 LHS 发送到不同的对象以获取其实际值。该值可以是String、Integer、Double 等。
当我尝试创建正确的predicate 并使用正确的值对其进行初始化时,我的问题就开始了。我收到警告说它不是类型安全的,使用原始类型等。如果可以并且不抑制警告,我想解决这个问题。我目前的想法是创建一个容器类,我将其命名为Value,这是通用的。但我坚持继续这种思路。我的代码:
public class Evaluator {
static PredicateFactory predFactory = new PredicateFactory();
public boolean evaluate(String[] expression, Data data){ // currently doesn't actually work, just testing
BiPredicate predicate = predFactory.createPred(expression[1]);
predicate.test(data.getAttribute(expression[0]), 50);
}
}
public class PredicateFactory {
public BiPredicate<?,?> createPred(String operator) {
return switch (operator) {
case "<" -> (BiPredicate<Double, String>) (i, j) -> i < Double.parseDouble(j);
case ">" -> (BiPredicate<Double, String>) (i, j) -> i > Double.parseDouble(j);
case "from domain" -> (BiPredicate<String, String>) (i, j) -> i.endsWith("@" + j);
default -> null;
};
}
public class Value<T>{
private T val;
Value(T val){
this.val = val;
}
public T getVal(){
return this.val;
}
}
public class Data {
private int id;
private int total_price;
private String date;
private String email;
....
Data(int id, int price, String date, String email, ){
this.id = id;
this.total_price = price;
this.date = date;
this.email = email;
.....
}
public Value<?> getAttribute(String attribute){
return switch(attribute){
case "value" -> new Value<>((double) this.total_price);
case "email" -> new Value<>(this.email);
default -> null;
};
}
}
感谢大家的指点
【问题讨论】:
-
如果您确定只会输入正确的类型(作为调用谓词时的参数),那么抑制警告应该完全没问题,您不必担心。否则,您可以使用“Object”作为谓词的类型,然后使用“instanceof”检查 labda(谓词)中对象的类型。这应该会使警告消失,但如果永远不会有错误的输入,那就没有必要了。
-
感谢@IntoVoid 的回复,我很肯定会输入正确的类型。我对此有完全的控制权。但是,抑制警告不是一个不好的编码习惯吗?我想避免长时间切换:instanceofs 的情况,感觉过于复杂和不可扩展
-
这就是为什么我建议使用 Object 作为谓词的类型,然后将 labda 中的对象转换为您需要的任何内容。如果不使用instanceof,那么当输入不正确的参数时,它会抛出一个错误(这很好,因为您将直接知道您的代码是否可以产生输入错误数据类型的状态)(如果您不使用instanceof可能会有另一个警告,但这次是在 labda 内部,而不是你称之为的地方)。我真的想不出另一个不需要包装类的解决方案
-
oop标签似乎放错了位置。在 oop 中,数据和逻辑是结合在一起的。这里数据和逻辑是分开的。也许目标是函数式编程? -
@IntoVoid 然后我会尝试使用 Object,但很想听听您对包装器的意见 - 我不是很有经验,并试图使这个设计尽可能好,所以我如果它是好的设计,我愿意实施我必须做的事情。 @jaco0646,您可能是对的-尽管在这种特定情况下我只是将数据和逻辑分开。你会说
Data类处理布尔评估逻辑更有意义吗?
标签: java oop generics design-patterns wildcard