Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 使用多态性和工厂模式消除重复条件_Php_Oop_Design Patterns_Inheritance_Refactoring - Fatal编程技术网

Php 使用多态性和工厂模式消除重复条件

Php 使用多态性和工厂模式消除重复条件,php,oop,design-patterns,inheritance,refactoring,Php,Oop,Design Patterns,Inheritance,Refactoring,如果IndexView代码实际上是相同的,那么您不需要继承,而是需要组合。在基本LayoutView类中添加一个IndexView实例,然后可以从每个*LayoutView调用该实例 仅当对象之间的关系为-a时,继承才到期。我推断IndexView不是LayoutView,而是LayoutView有一个IndexView 看看这个,我并不完全同意它所说的一切,但仍然: 只需将模板作为参数传递给要编写的子视图即可。我不认为在这种情况下那是邪恶的。虽然如果这是一个标准框架,你最好在他们的论坛上提问,

如果IndexView代码实际上是相同的,那么您不需要继承,而是需要组合。在基本LayoutView类中添加一个IndexView实例,然后可以从每个*LayoutView调用该实例

仅当对象之间的关系为-a时,继承才到期。我推断IndexView不是LayoutView,而是LayoutView有一个IndexView

看看这个,我并不完全同意它所说的一切,但仍然:

只需将模板作为参数传递给要编写的子视图即可。我不认为在这种情况下那是邪恶的。虽然如果这是一个标准框架,你最好在他们的论坛上提问,因为他们可能有一个我们在这种情况下不知道的功能(通常会发生)

你可以吃点像这样的东西

<?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?
 */

顺便说一句,将这个非常有效的编程问题标记为社区wiki只会让人对它关注较少。
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();
    }
}