是否存在可以帮助我对逻辑条件建模的设计模式或好方法,例如((a> b OR c == d)AND e< f)。特别是,我对如何使用对象编程以灵活的方式定义括号和OR / AND感兴趣。
答案 0 :(得分:0)
您的表达式构成一个树,因此直接表示将定义一个抽象表达式类来表示树的节点,并为每个操作定义具体的子类,例如。
public abstract class Expr<T>
{
public abstract T Eval();
}
public class Eq : Expr<bool>
{
private Expr<int> left;
private Expr<int> right;
public Eq(Expr<int> left, Expr<int> right)
{
this.left = left;
this.right = right;
}
public override bool Eval()
{
return this.left.Eval() == this.right.Eval();
}
}
这将评估的逻辑放在节点中。这使得添加新节点类型变得简单,因为您可以简单地定义Expr<T>
的新子类。
另一种方法是使用Visitor Pattern将用于解释节点的逻辑放入外部访问者,该访问者可以打开节点类型。
答案 1 :(得分:0)
了解更多关于如何使用它的信息会有所帮助,但我会试一试:您可以通过分离叶节点和复合节点来表示复杂的逻辑条件。叶节点将表示可以基于非递归处理评估为真/假的事物,而复合节点将评估委托给他们的子项,然后应用一些函数来得出最终值。
作为一个例子考虑这个设计:
abstract class Node
{
public abstract function eval();
}
class EqualNode extends Node
{
protected $aValue;
protected $bValue;
public function __construct($a, $b)
{
$this->aValue = $a;
$this->bValue = $b;
}
public function eval()
{
return $this->aValue == $this->bValue;
}
}
public class AndNode extends Node
{
protected $leftNode;
protected $rightNode;
public function __construct($left, $right)
{
$this->leftNode = $left;
$this->rightNode = $right;
}
public function eval()
{
return $this->leftNode->eval() && $this->rightNode->eval();
}
}
然后您可以创建一个新的逻辑表达式:
$exp1 = new EqualNode(2,2);
$exp2 = new EqualNode('Hi','Bye');
$exp3 = new And($exp1, $exp2);
$exp3->eval();
值得注意的一些事情:
Node
类可以是一个接口,因此您可以避免强制新节点成为特定层次结构的兄弟节点。HTH