2012-04-24 2 views
3

파서에는 세 가지 클래스의 개체가 있습니다. 파서 자체는 TokenState입니다. 파서는 렉서에서 토큰을 생성합니다. 모든 것은 검정 박스로되어있어 토큰은 파서 상태 나 파서에 대해 아무것도 모릅니다. 따라서 상태는 토큰에 대해 아무 것도 모릅니다. 배열의 매우 간단 버전 :컴포지션 대 상속 종속성 삽입

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; 
    } 
} 

내가 실행 해요 문제는 그 상태 변화는, 파서는 때 ending- 트리에 규칙을 추가 어떤 행동 (예를 취할 필요가 가끔 할 때 규칙 토큰에 도달). State만이이를 알고 있으므로 파서에게 무엇을 해야할지를 알리는 것은 국가의 책임입니다. 문제가 ParserState으로 가져오고 있습니다. 나는 상태 생성자에 Parser을 삽입 할 수는 있지만 모든 State이 파서를 필요로하지는 않으며 중복 코드가 많이 생깁니다. (State에 대한 기본 클래스가없고 Parser이 보호 된 멤버가 아니라면 어떤 것을 확장하는 것을 피하기 위해). 또한 Parserstate 메서드에 삽입 할 수 있지만 유사한 문제가 있습니다. 많은 중복이 될 수 있으며 State 구현의 일부가 주어진 메서드에 대한 파서가 필요하지 않습니다.

그래서 내 질문은 불필요한 상속이나 코드 중복이 필요없는 경우 에 대해 알기 위해 State을 어떻게 얻을 수 있습니까? 완벽하게 받아 들일 수있는 또 다른 수업이 필요하면. 이 수행하기 어려운 경우


, 여기에 "풀리지 않은"버전입니다 :이 질문에 대한 답변뿐만 아니라 다른 언어에 적용 할 수

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는 그렇지 않습니다.

+0

왜 "확장하지 않으려는 이유"를 설명 할 수 있습니까? 그것은 OO 코드와 관련해서는 매우 이상한 것 같습니다. – FtDRbwLXw6

+0

@ drrcknlsn 상속을 너무 싫어하는 사람들의 작은 선구자가있어 모든 경우에 그것을 사용하고 구성을 선호하지 않습니다. 필요하다면 나는 풀려나 겠지만 모든 국가가 파서에 대한 액세스를 필요로하지는 않는다는 것을 명심하십시오. 따라서 이것은 적절하지 않을 수도 있습니다. –

+0

나는 그런 것을 들어 본 적이 없다. OO 디자인의 주요 이점 중 하나는 상속입니다. 액세스가 필요한지 아닌지에 관계없이 여러 수준의 상속이 필요합니다. 액세스가 필요한 사람들은 Parser가 삽입 된 클래스 (기본 클래스를 확장하는 클래스)를 확장합니다. 액세스가 필요하지 않은 사용자는 기본 클래스를 확장합니다. 원하는 경우 구도를 사용하여 문제를 해결할 수도 있지만 ... – FtDRbwLXw6

답변

1

PHP 5.4의 특성을 소개 :

http://php.net/manual/en/language.oop5.traits.php은 아마 당신은 상속 및 사출 사이의 중간으로 특성을 사용할 수 있습니다.

+0

형체가 멋질 것입니다 .. 만약 내가 * 5.4 * PHP를 사용할 수 있습니다. –