1

我有一个Display处理脚本的 HTML 输出的对象。它有一个mode属性,它定义了如何生成输出的许多方面。有几种模式,我以后可能会添加更多。每种模式都暗示着它自己的参数。例如,一个author模式意味着一个authorID. search模式意味着将对象Search作为参数,其中将包含查询信息。一个comment模式意味着一个postIDcommentID参数。

因此, amode有 aname和一定数量的parameters,具体取决于name

我决定创建一个Display_Mode对象,它有两个属性:nameparameters. 但是我该如何parameters分配names?所以,如果我有一个comment模式,它必然意味着有postIDcommentID参数?

我目前的解决方案是这样的:

class display_mode{
    public $name;
    public $params;

    public function __construct($name)
        {
        $this->name = $name;
        switch ($this->name){
            case 'comment':
                $this->params = array('postID', `commentID`);
                break;
            case 'author':
                $this->params = array('authorID');
            }
            //etc..
        }
    }

这似乎有点乱。有没有更好的办法?

UPD:给定的答案让我问了另一个关于整个设计的问题,这也为这个设计提供了背景。

4

3 回答 3

4

您最好将Display_Mode类的通用功能抽象为抽象基类或接口,然后将每个单独的模式定义为从基类继承(或实现接口)的类。

然后,这些专用模式类将在其构造函数和/或方法中显式定义它们所需的参数,并负责生成每个“模式”所需的输出。

但是,如果不确切知道您的Display_Mode班级应该做什么,就很难给出比这更具体的建议。


这里的想法是,您应该避免 OOP 中的全能类,而更喜欢小型的、自包含的类,每个类都有一个单一的目的。通过为每种模式提供可以独立呈现其内容的类,您可以轻松更改显示模式的工作方式或添加新模式。您所要做的就是添加一个新类。

这称为松耦合

于 2012-12-18T21:18:47.133 回答
1

描述有点令人困惑,但我会为每个可能的“参数”创建一个适配器Display。该适配器可以提供单一接口,独立于您要显示的资源。

$parameter = new UnknownPrameter;

$adapterFactory = new AdapterFactory;
$parameter = $adapterFactory->build( $parameter );

$display->present( $parameter );

在哪里AdapterFactory::build()为您提供的特定类型的参数创建包装器。返回的实例是该参数的容器。

这种方法还可以防止计算在构造函数中累积,这会使代码更难测试/扩展。

于 2012-12-18T21:25:44.617 回答
0

@Will Vousden 已经给了你答案。这是一个如何解决您的问题的快速示例。

abstract class DisplayMode {
    protected $_params = array();

    public function __construct(array $params) {
        $this->_params = $params;
    }

    public function hasParameter($key) {
        if (array_key_exists($key, $this->_params)) {
            return true;
        }
        return false;
    }

    public function setParameters(array $params) {
        $this->_params = $params;
        return $this;
    }

    public function getParameters() {
        return $this->_params;
    }
}

class CommentMode extends DisplayMode {
    public function getCommentId() {
        if ($this->hasParameter('comment_id')) {
            return $this->_params['comment_id'];
        }    
        return null;
    }

    public function getPostId() {
        if ($this->hasParameter('post_id')) {
            return $this->_params['post_id'];
        }    
        return null;
    }
}

class AuthorMode extends DisplayMode {
    public function getAuthorId() {
        if ($this->hasParameter('author_id')) {
            return $this->_params['author_id'];
        }    
        return null;
    }
}

$comment = new CommentMode(array('post_id' => 4, 'comment_id' => 2));
$author = new AuthorMode(array('author_id' => 3));

// example

print $comment->getCommentId() . ' -  ' . $comment->getPostId() . '  - ' . $author->getAuthorId();
于 2012-12-18T21:50:03.537 回答