簡體   English   中英

組合與繼承依賴注入

[英]Composition vs. Inheritance dependency injection

我有一個包含三類對象的Parser:解析器本身, Token s和State s。 解析器從詞法分析器生成令牌。 一切都是黑盒子,因此令牌對解析器狀態或解析器一無所知,並且狀態對令牌一無所知。 一個相當簡單的安排版本:

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是受保護的成員,但我想要避免擴展任何東西)。 我也可以在需要它的state方法中注入Parser ,但是我有一個類似的問題:這將是很多重復,並不是所有的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 5.4引入了特征: http//php.net/manual/en/language.oop5.traits.php

也許你可以在繼承和注入之間使用特征。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM