2008-10-29 2 views
0
<?php 
/** 
* My codebase is littered with the same conditionals over and over 
* again. I'm trying to refactor using inheritance and the Factory 
* pattern and I've had some success but I'm now stuck. 
* 
* I'm stuck because I want to derive a new class from the one 
* returned by the Factory. But I can't do that, so I'm obviously 
* doing something wrong somewhere else. 
*/ 


/** 
* The old implementation was as follows. There's if statements 
* everywhere throughout both LayoutView and ItemIndexView and 
* SomeOtherView. 
*/ 
class LayoutView { } 
class IndexView extends LayoutView { } 
class SomeOtherView extends LayoutView { } 

/** 
* Below is the new implementation. So far I've managed to tidy 
* up LayoutView (I think I have anyway). But now I'm stuck because 
* the way I've tidied it up has left me not knowing how to extend 
* it. 
* 
* For example's sake, let's say the conditions were relating to a 
* type of fish: salmon or tuna. 
*/ 
abstract class LayoutView { 
    protected function prepareHeader() { echo __METHOD__, "\n"; } 
    protected function prepareLeftHandSide() { echo __METHOD__, "\n"; } 
    protected function prepareFooter() { echo __METHOD__, "\n"; } 
    public function prepare() { 
     $this->prepareHeader(); 
     $this->prepareLeftHandSide(); 
     $this->prepareFooter(); 
    } 
} 

class SalmonLayoutView extends LayoutView 
{ 
    protected function prepareLeftHandSide() { echo __METHOD__, "\n"; } 
} 

class TunaLayoutView extends LayoutView 
{ 
    protected function prepareLeftHandSide() { echo __METHOD__, "\n"; } 
    protected function prepareFooter() { echo __METHOD__, "\n"; } 
} 

class ViewFactory { 
    public static function getLayoutView($fishType) { 
     switch($this->$fishType) { 
     case 'salmon': 
      return new SalmonLayoutView(); 
      break; 
     case 'tuna': 
      return new TunaLayoutView(); 
      break; 
     } 
    } 
} 

/** 
* Now LayoutView has been cleaned up and the condition that was once 
* scattered through every LayoutView method is now in one place. 
*/ 
$view = ViewFactory::getLayoutView(Config::getOption('fishtype')); 
$view->prepare(); 

/** 
* Now here's where I'm stuck. I want to effectively extend whatever 
* class $view is an instance of. 
* 
* The reason being, I wish to derive a view to show an index of 
* articles within the appropriate *LayoutView. The IndexView code is 
* the same for Salmon and Tuna. 
* 
* I can do something like this: 
*/ 

class SalmonIndexView extends SalmonLayoutView { } 
class TunaIndexView extends TunaLayoutView { } 

/** 
* But then I'll be writing the same IndexView code twice. What I'd 
* like to do is something like this: 
*/ 

$view = ViewFactory::getLayoutView(Config::getOption('fishtype')); 
class IndexView extends get_class($view) { } 

/** 
* But I'm pretty certain that's not possible, and even if it was 
* it seems very wrong. 
* 
* Can someone more experienced in refactoring and OO please let 
* me know where I've gone wrong and suggest a clean way to solve 
* this? 
*/ 
+0

같은이 마킹 할 수이 경우에 대해 모르고, 만약 비록 아주 유용한 프로그래밍 질문은 커뮤니티 위키는 그저 눈이 적을뿐입니다. –

답변

1

IndexView 코드가 실제로 같으면 상속, 구성이 필요하지 않습니다. 기본 LayoutView 클래스에 각 * LayoutView에서 호출 할 수있는 IndexView의 인스턴스를 추가합니다.

개체 간의 관계가 is-a 인 경우에만 상속이 발생합니다. 나는 IndexView가 LayoutView가 아니라, LayoutView가 IndexView임을 추론한다.

확인이를, 나는 모든 그것이 말하는 동의하지만, 여전히하지 않습니다 http://phpimpact.wordpress.com/2008/09/04/favour-object-composition-over-class-inheritance/

0

그냥 당신이 구성 것이다 파단에 매개 변수로 템플릿을 전달합니다. 나는이 경우에 그것이 악하다고 생각하지 않는다. 당신이 자신의 포럼에 물어 더 좋을 수있는 표준 프레임 워크들이이 기능을 가질 수 있기 때문에 우리가 (이 일반적으로 발생)

당신은

class LayoutView { 
    protected View $subview; //Potentially an array of views 
    public function prepare() { 
     // empty, to be filled out by derived classes 
    } 
    public function setSubView($view) { $this->subview = $view; } 
    public function display() { 
     $this->prepare(); 
     $this->subview->prepare($this->template); 
     $this->template->render(); 
    } 
} 

class IndexView { 
    protected View $subview; //Potentially an array of views 
    public function prepare() { 
     // empty, to be filled out by derived classes 
    } 
    public function prepare($template) { 
     //operate on it, maybe even assigning it to $this->template 
    } 
    public function setSubView($view) { $this->subview = $view; } 
    public function display() { 
     $this->prepare(); 
     $this->subview->prepare($this->template); 
     $this->template->render(); 
    } 
} 
관련 문제