【发布时间】:2012-12-04 21:55:19
【问题描述】:
是否有设计模式或好的方法可以帮助我对逻辑条件进行建模,例如 ((a > b OR c == d) AND e
【问题讨论】:
-
它和OOP有什么关系?
标签: oop design-patterns uml logic
是否有设计模式或好的方法可以帮助我对逻辑条件进行建模,例如 ((a > b OR c == d) AND e
【问题讨论】:
标签: oop design-patterns uml logic
您的表达式形成一棵树,因此直接表示将是定义一个抽象表达式类来表示树的节点,并为每个操作定义具体的子类,例如
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 将解释节点的逻辑放入打开节点类型的外部访问者中。
【讨论】:
更多地了解您打算如何使用它会有所帮助,但我会试一试:您可以通过分离叶节点和复合节点来表示复杂的逻辑条件。叶节点将表示可以基于非递归处理评估为真/假的事物,而复合节点会将评估委托给它们的子节点,然后应用一些函数来得出最终值。
以这种设计为例:
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
【讨论】: