我有一个属性文件(键/值)对,我从当前读取一个键的值,并显示该值在UI中。
复杂性增加了,现在基于某些公式,值更具动态性。该公式包含一个变量参数,其值I将在运行时获得。
是否有任何java设计模式来设计此场景。
我正在考虑在属性文件中针对密钥设置方法名称。
现在我将读取密钥并获取方法名称。此方法将计算该特定键的值。
请告诉我你的建议
答案 0 :(得分:1)
是否有任何java设计模式来设计此场景。
我不知道是否有模式。
如果我理解你的问题,我可以解释我通常做的事情。
#number#
小例子:
<强> messages.properties 强>
name.of.key = sum of #0# + #1# = #2#
然后我从中读取值并将#num#
替换为适当的值( 注意: 此处的短路方法与此相同,但是我使用外部replace
方法):
public void printSum(int n1, int n2) {
String myString = messageSource("name.of.key", Locale.getDefault(), null, null));
myString.replace("#0#", String.valueOf(n1));
myString.replace("#1#", String.valueOf(n2));
myString.replace("#2#", String.valueOf(n1+n2));
System.out.println(myString);
}
输出printSum(1,2);
sum of 1 + 2 = 3
答案 1 :(得分:1)
使用Java内置JavaScript engine来计算表达式。为了更精确地匹配精神,您可以将JSON用于属性。
如果安全性很重要,则需要提供class filter。它可以非常简单和限制,因为您只需要评估琐碎的表达式。可以在here找到关于类过滤器的示例。
答案 2 :(得分:1)
ANTLR看起来非常合适。
它是一个解析器生成器。你把语法作为输入,作为回报,它为你提供了一个解析器。
您可以使用解析器将文本公式转换为已解析的树表示。之后,您可以运行访问者来评估每个节点。您只需编写一些简单的函数来实现该行为,例如:
public Double visitAdd(AntlrNode left, AntlrNode right) {
Double left = visit(left);
Double right = viist(right);
return left + right;
}
语法非常接近熟悉的BNF表示法。您只需描述公式字符串的方式。例如:
formula : left '+' right;
left: Number;
right: Number;
Number: [0-9]+;
答案 3 :(得分:0)
您可以使用策略模式将方法/算法名称放在属性文件中:
public interface IFormula{
public int formula(int a, int b);
}
public class Sum implements IFormula{
public int formula(int a, int b){
return a+b;
}
}
然后您可以选择从属性文件中获取名称的方法:
public static Strategy getStrategy(Name name) {
switch (name) {
case SUM:
return new Sum();
...
}
}
答案 4 :(得分:0)
另一个解决方案是重构地图,以便值类型是一个功能接口,其方法接受任意参数。例如:
@FunctionalInterface
interface ValueType<R> {
R eval(Object param);
}
此解决方案(或其变体)将使您能够将lambda与键相关联,而不是固定值。 lambda的性能应该比运行时解析器好得多,同时仍然能够灵活地使关联值依赖于运行时参数。
与基于运行时解析的解决方案相比,此解决方案也应该更容易受到注入攻击。
答案 5 :(得分:0)
由于您似乎需要模式的名称...模式称为: Domain Specific Language 。
如果你想继续留在抽象模式和设计的领域,你可以仔细阅读Martin Fowlers discussion on the topic at length。
毋庸置疑,他们是解决上述模式的公吨工具(包括此处的一些答案)。
我强烈建议你 NOT 做的另一种模式是使用具有评估者的通用语言(即Javascript,EL,Groovy等)。这通常有安全问题和性能问题(当然也有例外)。