Java-复杂决策表
目前必须创建一个基于不同对象的决策表,每个对象可以有不同/多个信息 例如:Java-复杂决策表,java,Java,目前必须创建一个基于不同对象的决策表,每个对象可以有不同/多个信息 例如: object A can be: OK / KO object B can be: OK / WARNING / KO object C can be: STARTING / RUNNING / ENDING 根据A、B和C的状态,我们得到不同的输出。我现在做了很多IF语句,感觉这是一个非常新手的编码 像这样: if (C == STARTED) { if (A == OK) { if (B =
object A can be: OK / KO
object B can be: OK / WARNING / KO
object C can be: STARTING / RUNNING / ENDING
根据A、B和C的状态,我们得到不同的输出。我现在做了很多IF语句,感觉这是一个非常新手的编码
像这样:
if (C == STARTED) {
if (A == OK) {
if (B == OK)
return "something";
if (B == WARNING)
return "something else";
else
return "something more";
}
...
}
是否有任何已知的技术(使用hasmaps或Java8中已有的东西)能够以正确的方式处理此类问题
考虑过实现一个决策树,但我当前的if语句大约需要30行,不确定创建一个(一堆)全新类来解决这个问题是否明智。事实上,这里有三种不同的情况:
if (C == STARTED) {
if (A == OK) {
if (B == OK)
return "something";
if (B == WARNING)
return "something else";
else
return "something more";
}
...
}
不同方法中的不同案例或类中的每一个案例都允许对其进行统一测试,以便轻松理解每一条规则并对其进行更改,而不会对其他规则产生副作用。例如:
如果(C==STARTED&&(A==OK)&(B==OK)
是一条规则
如果(C==STARTED&&(A==OK)&&(B==WARNING)
是另一条规则
如果(C==STARTED&&(A==OK)和(B==KO)
是另一条规则
为每个规则创建一个方法,或者创建一个带有处理方法的接口,并使每个规则成为其独特的实现。责任链是一种很好的模式 例如,你可以有这些 规则界面:
public interface IRule {
public void setNextRule(IRule nextRule);
public abstract boolean apply(Data data);
}
public abstract class AbstractRule implements IRule {
protected IRule nextRule;
public void setNextRule(IRule nextRule) {
this.nextRule = nextRule;
}
public boolean applyNextRuleIfExist(Data data) {
if (this.nextRule != null) {
return this.nextRule.apply(data);
}
return false;
}
}
public class RuleXXX extends AbstractRule {
public boolean apply(Data data) {
if (data.C == STARTED && (data.A == OK) && (data.B == OK){
return true;
}
return applyNextRuleIfExist(inputDataForDiscountRules);
}
}
规则接口的抽象公共类:
public interface IRule {
public void setNextRule(IRule nextRule);
public abstract boolean apply(Data data);
}
public abstract class AbstractRule implements IRule {
protected IRule nextRule;
public void setNextRule(IRule nextRule) {
this.nextRule = nextRule;
}
public boolean applyNextRuleIfExist(Data data) {
if (this.nextRule != null) {
return this.nextRule.apply(data);
}
return false;
}
}
public class RuleXXX extends AbstractRule {
public boolean apply(Data data) {
if (data.C == STARTED && (data.A == OK) && (data.B == OK){
return true;
}
return applyNextRuleIfExist(inputDataForDiscountRules);
}
}
具体规则:
public interface IRule {
public void setNextRule(IRule nextRule);
public abstract boolean apply(Data data);
}
public abstract class AbstractRule implements IRule {
protected IRule nextRule;
public void setNextRule(IRule nextRule) {
this.nextRule = nextRule;
}
public boolean applyNextRuleIfExist(Data data) {
if (this.nextRule != null) {
return this.nextRule.apply(data);
}
return false;
}
}
public class RuleXXX extends AbstractRule {
public boolean apply(Data data) {
if (data.C == STARTED && (data.A == OK) && (data.B == OK){
return true;
}
return applyNextRuleIfExist(inputDataForDiscountRules);
}
}
最后,您可以创建规则链并使用它:
IRule firstRule = new RuleXXX();
firstRule.setNextRule(new RuleYYY());
...
// apply the chain
Data data = ...;
firstRule.apply(data);
有很多方法。如果这些状态是枚举值、整数或字符串,则开关看起来比许多嵌套的
If
s要干净一些,尽管它归结为同一件事,并且最终可能会有一些深层嵌套
switch (C) {
case STARTED :
{
// do stuff for this state
}
case RUNNING :
{
// do stuff for this state
}
}
不要忘记必要时使用break;
语句,否则案例可能会失败。不过,在返回语句之后,就不需要使用它了
更进一步的一步是简单地用方法将事情分解
switch (C) {
case STARTED : return handleStartedState(A, B);
case RUNNING : return handleRunningState(A, B);
}
然后,在一个单独的方法中实现每个C
案例的逻辑,该方法反过来也会对其他输入执行相同的操作。这样做的缺点是,对于各种输入组合,您可能会得到许多具有长名称的方法
也许更好的面向对象方法是将如何处理类本身中各种状态组合的责任放在上面。我不知道你的A
、B
和C
是什么,但是如果它们是你控制的类,你可以根据需要在每个委托中创建方法C
类有一个方法句柄(a,B)
,该方法根据自身的状态调用a
上的方法,a
然后对B
执行相同的操作。实现这一点的方法是使用一种将行为与某个对象的状态相耦合的设计模式
这确实意味着您正在创建一些类来处理这个问题,而这可能会使一些根本不需要变得如此复杂的事情变得过于复杂。问问自己以下问题:
- 将来有可能增加更多的案件来处理吗
- 增加更多案例是否经常发生
- 是否有可能以动态的方式扩展功能(可能是通过客户端使用代码)
- 新案例的增加会导致代码长度呈指数增长,而不是线性增长吗
这个问题没有“一刀切”的答案,因为它太依赖于项目、上下文和代码库的其他部分……所以希望以上信息能帮助您找到最有效的方法。查看可能的命令模式副本?或者查看