我遇到了实现策略模式的问题,这是我遇到的特定问题。依赖嵌套切换重构策略模式的方法
我基本上有一种方法进行值之间的比较。除了这两个值之外,这个方法依赖于两个额外的参数来确定我应该做哪个比较:一个运算符(等于,不等于,...)和一个类型(字符串,双精度)。它基本上是一个开关,它依赖于另一个交换机的结果。
让我用一个例子阐明:
public enum Type {
STRING,
BOOLEAN,
DOUBLE;
}
public enum Operator {
EQUALS(new Type[] { Type.STRING, Type.BOOLEAN}),
NOT_EQUALS(new Type[] { Type.STRING, Type.BOOLEAN});
private Type[] allowedTypes;
Operator(Type[] allowedTypes) {
this.allowedTypes = allowedTypes;
}
public List<Type> getAllowedTypes() {
return Arrays.asList(allowedTypes);
}
}
public class Evaluator {
public Boolean evaluate(String value1, String value2, Operator operator, Type type) {
switch(operator) {
case EQUALS:
return doEqualComparison(value1, value2, type);
}
return null;
}
private Boolean doEqualComparison(String value1, String value2, Type type) {
//code here to check if the params are correct (not null, etc)
switch(type) {
case STRING:
return value1.equals(value2);
case DOUBLE:
return Double.parseDouble(value1) == Double.parseDouble(value2);
}
return null;
}
}
而且测试
public class EvaluatorTest {
@Test
public void testEvaluate() {
Evaluator evaluator = new Evaluator();
// check STRING
Assert.assertTrue(evaluator.evaluate("100", "100", Operator.EQUALS, Type.STRING));
Assert.assertFalse(evaluator.evaluate("100.00", "100", Operator.EQUALS, Type.STRING));
// check DOUBLE
Assert.assertTrue(evaluator.evaluate("100", "100", Operator.EQUALS, Type.DOUBLE));
Assert.assertTrue(evaluator.evaluate("100.00", "100", Operator.EQUALS, Type.DOUBLE));
}
}
这工作得很好,但有两个(主要是嵌套的)switch语句似乎并不像一个非常干净和未来的证明解决方案,如果我们添加了很多类型和操作符,事情会变得很讨厌,很快,所以我的第一个事实是环是第一开关(操作员)更改为战略
public class EqualComparisonStrategy implements ComparisonStrategy {
@Override
public Boolean compare(String value1, String value2, Type Type) {
//HERE IS MY PROBLEM
switch (conditionType) {
case STRING:
return value1.equals(conditionValue);
case DOUBLE:
return Double.parseDouble(value1) == Double.parseDouble(value2);
}
return null;
}
@Override
public boolean accept(Operator operator) {
return operator == Operator.EQUAL;
}
}
尽管该解决方案是不是“太”坏我猜我想外部化第二开关(在我的评论是)太多,问题是,它的实施依赖于第一个(操作员)。 我想到了在accept方法
//snippet of the accept methode (instead of a factory)
@Override
public boolean accept(Operator operator, Type type) {
return operator == Operator.EQUAL && type == Type.STRING;
}
像StringEqualComparisonStrategy通过任何工厂或只是做一些更多的东西制成,但是这将创建M * N个战略和失控的真正快的(我有大约8运营商,与3种类型结果在24策略) 看到我希望这是一个未来证明尽可能这不是最好的解决方案恕我直言。
我确定必须有一个模式来解决这个问题,但我没有看到它。 (我不是模式英雄)
有人可以帮忙吗?
如果您的'评估'方法总是以'字符串'作为输入,那么您为什么需要以不同的方式进行比较?我在想的是''3.1415“.equals(”3.1415“)'应该与'((Double)3.1415).equals((Double)3.1415)相同' – chancea
因为我的示例代码演示了”40.0“吨等于“40”,而将其转换为双打将会。 字符串的考虑是因为它存储在数据库中 – Sem