cubiche / visitor
访客库
dev-master
2017-03-16 11:29 UTC
Requires
- php: ^5.5.9|^7.0
Requires (Dev)
- cubiche/tests: dev-master
This package is auto-updated.
Last update: 2024-09-04 23:15:10 UTC
README
安装
通过Composer
$ composer require cubiche/visitor:dev-master
基本用法
算术表达式计算器
use Cubiche\Core\Visitor\Visitee; use Cubiche\Core\Visitor\Visitor; abstract class Expression extends Visitee {} abstract class Operator extends Expression { protected $operator; protected $firstOperand; protected $secondOperand; public function __construct($operator, Expression $firstOperand, Expression $secondOperand) { $this->operator = $operator; $this->firstOperand = $firstOperand; $this->secondOperand = $secondOperand; } public function operator() { return $this->operator; } public function firstOperand() { return $this->firstOperand; } public function secondOperand() { return $this->secondOperand; } } class Sum extends Operator { public function __construct(Expression $firstOperand, Expression $secondOperand) { parent::__construct('+', $firstOperand, $secondOperand); } } class Mult extends Operator { public function __construct(Expression $firstOperand, Expression $secondOperand) { parent::__construct('*', $firstOperand, $secondOperand); } } class Value extends Expression { protected $value; public function __construct($value) { $this->value = $value; } public function value() { return $this->value; } } class Variable extends Expression { protected $name; public function __construct($name) { $this->name = $name; } public function name() { return $this->name; } } class Calculator extends Visitor { public function visitSum(Sum $sum) { return $sum->firstOperand()->accept($this) + $sum->secondOperand()->accept($this); } public function visitMult(Mult $mult) { return $mult->firstOperand()->accept($this) * $mult->secondOperand()->accept($this); } public function visitValue(Value $value) { return $value->value(); } } $expression = new Sum( new Value(5), new Mult( new Value(3), new Value(2) ) ); $calculator = new Calculator(); $result = $expression->accept($calculator);
访问父类
use Cubiche\Core\Visitor\Visitor; class ExpressionToStringConverter extends Visitor { public function visitOperator(Operator $op) { return '('.$op->firstOperand()->accept($this).$op->operator().$op->secondOperand()->accept($this).')'; } public function visitValue(Value $value) { return (string) $value->value(); } public function visitVariable(Variable $variable) { return $variable->name(); } } $expression = new Sum( new Value(5), new Mult( new Value(3), new Value(2) ) ); $converter = new ExpressionToStringConverter(); echo $expression->accept($converter);
注意当访问操作符(Sum
或Mult
)时将调用visitOperator
方法。
向访问方法传递参数
class SmartExpressionToStringConverter extends ExpressionToStringConverter { public function visitOperator(Operator $op, $parentOperator = null) { $currentOperator = $op->operator(); $expression = $op->firstOperand()->accept($this, $currentOperator). $currentOperator.$op->secondOperand()->accept($this, $currentOperator); return $this->requireParentheses($currentOperator, $parentOperator) ? '('.$expression.')' : $expression; } protected function requireParentheses($currentOperator, $parentOperator) { return $currentOperator === '+' && $parentOperator === '*'; } } $expression = new Sum( new Value(5), new Mult( new Value(3), new Value(2) ) ); $converter = new SmartExpressionToStringConverter(); echo $expression->accept($converter);
在不使用继承的情况下扩展另一个访问者
use Cubiche\Core\Visitor\LinkedVisitor; class Evaluator extends LinkedVisitor { protected $variables; public function __construct(Calculator $calculator, $variables = array()) { parent::__construct($calculator); $this->variables = $variables; } public function visitVariable(Variable $variable) { if (isset($this->variables[$variable->name()])) { return $this->variables[$variable->name()]; } throw new \Exception(\sprintf("Unknown variable '%s'", $variable->name())); } } $expression = new Mult( new Variable('x'), new Sum( new Value(5), new Mult( new Variable('y'), new Value(2) ) ) ); $variables = array('x' => 10, 'y' => -7); $evaluator = new Evaluator(new Calculator(), $variables); $converter = new SmartExpressionToStringConverter(); echo $expression->accept($converter).' = '.$expression->accept($evaluator).PHP_EOL;
注意Evaluator
只能访问Variable
实例,并将其他表达式委托给Calculator
。