组合与继承依赖注入

问题描述 投票:0回答:1

我有一个包含三类对象的解析器:解析器本身、

Token
State
。解析器从词法分析器生成标记。一切都是黑盒的,因此令牌对解析器状态或解析器一无所知,并且状态对令牌一无所知。一个相当简单的安排版本:

class Parser {
   public function parse() {
      $this->state = new StEmpty;
      while ($token = $this->lexer->get()) {
         $this->state = $this->token->expect($this);
      }
   }
   public function stateStart() {
      return $this->state->stateStart();
   }
}
class StartToken {
   public function expect(Parser $parser) {
      return $parser->stateStart();
   }
}
class StEmpty {
   public function stateStart() {
      return new StStart;
   }
}

我遇到的问题是,有时当状态发生变化时,解析器需要采取一些操作(例如,当到达结束规则标记时向树添加规则)。只有

State
知道这一点,因此由状态来告诉解析器要做什么。问题是将
Parser
移至
State
。我可以在状态构造函数中注入
Parser
,但并不是每个
State
都需要解析器,这会导致大量重复代码(除非我有
State
Parser
的基类)是受保护的成员,但我想避免扩展任何内容)。我还可以将
Parser
注入需要它的
state
方法中,但我有一个类似的问题:这会是大量重复,并且并非所有
State
实现都需要给定方法的解析器。

所以我的问题是如何让

State
在需要时了解
Parser
而无需不必要的继承或代码重复?如果我需要另一门课程,这是完全可以接受的。


如果这很难理解,这里有一个“未解开”的版本:

class Parser {
   public function parse() {
      $this->state = 'StEmpty';

      while ($token = $this->lexer->get()) {
         switch ($token) {
            case 'StartToken':
               switch ($this->state) {
                  case 'StEmpty':
                     $this->state = 'StStart';
                     break;
               }
               break;
         }
      }
   }
}

这个问题的答案也适用于其他语言,但我知道在允许重载的语言中这会更容易做到。 PHP 没有。

php language-agnostic
1个回答
1
投票

PHP 5.4 引入了特征:http://php.net/manual/en/language.oop5.traits.php

也许您可以使用特征作为继承和注入之间的中间方式。

© www.soinside.com 2019 - 2024. All rights reserved.