[英]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.