面向对象的逻辑

时间:2012-12-04 13:23:24

标签: oop design-patterns uml logic

是否存在可以帮助我对逻辑条件建模的设计模式或好方法,例如((a> b OR c == d)AND e< f)。特别是,我对如何使用对象编程以灵活的方式定义括号和OR / AND感兴趣。

2 个答案:

答案 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();

值得注意的一些事情:

  • 这只是Composite模式的实现。看看它是为了更好地理解它是如何工作的。
  • 这个设计只是一个例子。您可以通过使用子节点集合(例如,通用AND)来使其具有一元运算符(例如NOT),更多二元(AND,OR)或N元素
  • 抽象Node类可以是一个接口,因此您可以避免强制新节点成为特定层次结构的兄弟节点。
  • 我不知道你使用它的上下文,但Command模式也可能会给你一些有趣的想法。

HTH