【问题标题】:logic in object oriented面向对象的逻辑
【发布时间】:2012-12-04 21:55:19
【问题描述】:

是否有设计模式或好的方法可以帮助我对逻辑条件进行建模,例如 ((a > b OR c == d) AND e

【问题讨论】:

标签: oop design-patterns uml logic


【解决方案1】:

您的表达式形成一棵树,因此直接表示将是定义一个抽象表达式类来表示树的节点,并为每个操作定义具体的子类,例如

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&lt;T&gt; 的新子类。

另一种方法是使用Visitor Pattern 将解释节点的逻辑放入打开节点类型的外部访问者中。

【讨论】:

    【解决方案2】:

    更多地了解您打算如何使用它会有所帮助,但我会试一试:您可以通过分离叶节点和复合节点来表示复杂的逻辑条件。叶节点将表示可以基于非递归处理评估为真/假的事物,而复合节点会将评估委托给它们的子节点,然后应用一些函数来得出最终值。

    以这种设计为例:

    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-ary
    • 抽象的Node 类可以是一个接口,因此您可以避免强制新节点成为特定层次结构的兄弟节点。
    • 我不知道您使用它的上下文,但Command 模式也可能会给您一些有趣的想法。

    HTH

    【讨论】:

      猜你喜欢
      • 2011-06-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-20
      • 1970-01-01
      • 1970-01-01
      • 2018-07-03
      • 1970-01-01
      相关资源
      最近更新 更多