【问题标题】:PHP OOP design: an object can have several 'modes'. How do I define them?PHP OOP 设计:一个对象可以有多种“模式”。我如何定义它们?
【发布时间】:2012-12-06 04:06:17
【问题描述】:

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

所以,mode 有一个name 和一些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:给出的答案让我问another question,关于整个设计,这也提供了这个设计的背景。

【问题讨论】:

    标签: php oop properties


    【解决方案1】:

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

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

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


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

    这被称为 loose coupling

    【讨论】:

    • 您能详细说明一下吗?我对此很陌生。此外,Display_Mode 没有任何实际功能,它只有一个名称和参数(例如postID = 223)。 Display 然后查找模式的名称和与之相关的参数,然后根据它们生成输出。
    • 开设一个全能的Display 课程听起来是个坏主意。如果有许多不同类型的输出,它们可能都应该有自己的类。不过,如果不详细说明您的要求,就很难详细说明。
    【解决方案2】:

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

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

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

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

    【讨论】:

      【解决方案3】:

      @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();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-05-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-19
        相关资源
        最近更新 更多