一种方法检索所有数据或几个较小的方法检索每个部分?

时间:2013-01-05 22:17:28

标签: php class methods pdo

我对我正在创建的OOP PHP代码有几个疑问。到目前为止,它是用于检索标题和在线存储的不同语言的几个章节。但首先我将展示代码,因为我的怀疑是指这个。这是我目前正在上课的课程:

<?php
// Requires PHP 5.4+
class Subject
  {
  private $DB;
  private $Language;
  private $Keyword;

  public function __construct($DB, $Keyword, $Language)
    {
    $this->DB=$DB;
    $this->Keyword=$Keyword;
    $this->Language=$Language;
    }

  private function query($query, $arg)
    {
    $STH = $this->DB->prepare($query);
    $STH->execute(array_merge((array)$this->Keyword, (array)$arg));
    return $STH->fetch()[$this->Language];  // PHP 5.4+
    }

  public function retrieveTitle ()
    {
    return $this->query("SELECT * FROM subject WHERE keyword = ? ORDER BY date DESC LIMIT 1");
    }

  public function retrieveChapter ($arg)
    {
    return $this->query("SELECT * FROM chapters WHERE subject_keyword = ? AND type = ? ORDER BY date DESC LIMIT 1", $arg);
    }
?>

然后我做了类似的事情来显示页面:

if (isset($_GET['a']))
  {
  $Subject=new Subject($DB, $_GET['a'], $User->get('language'));

  if ($Subject->retrieveTitle())
    {
    echo '<h1 id="Title">'.$Subject->retrieveTitle().'</h1>';

    // Index
    if ($Subject->retrieveTitle())
      // ... code for the index

    // Introduction
    if ($Subject->retrieveChapter('Introduction'))
      echo '<h2 id="Introduction">' . $_('Introduction') . '</h2>' . $Subject->retrieveChapter('Introduction');

    // ... more non-relevant code.
    }
  }
else
  // ... whatever

首先关注。我不确定这是否是处理此类数据的正确方法。我试图将方法分开并使它们尽可能小,同时也不要重复很多代码。这就是感觉正确的方式。但我不明白为什么这个与前一代码类似的其他代码不太可取。注意:这个类有一些错字并且没有经过测试,它只是为了说明差异,所以请不要使用它(至少不是文字):

<?php
// Requires PHP 5.4+
class Subject
  {
  public $Title;
  public $Chapters = array ();

  public function __construct($DB, $Keyword, $Language)
    {
    // Retrieve all
    $STH = $DB->prepare("SELECT * FROM subject WHERE keyword = ? ORDER BY date DESC LIMIT 1");
    $STH->execute(array($Keyword));
    $this->Title = $STH->fetch()[$Language];  // PHP 5.4+

    // Retrieve chapters
    $ToForeach = ('Introduction','History','1');
    $STH = $DB->prepare("SELECT * FROM chapters WHERE subject_keyword = ? AND type = ? ORDER BY date DESC LIMIT 1");
    foreach ($ToForeach as $part)
      {
      $STH->execute(array($Keyword, $part));
      $this->Chapters = $STH->fetch()[$Language];
      }
    }
  }
?>

然后直接访问属性(甚至在中间构建一些get(),但是你明白了。)

那么,有什么区别吗?第一种方法与第二种方法的优点和缺陷是什么?在第一个内存使用量应该略小,但我认为与这种情况下的可读性相比,这不会是一个交易破坏者。

编辑:只是以某种方式写出问题让别人理解,这让我以其他方式思考问题。第一种方式也更容易测试。

第二个问题。如果我想制作一些保存数据的方法,我应该把它放在同一个类还是另一个类中?因为如果我把它放在一个中它将所有与主题相关的方法捆绑在一个非常独立的类中,如果我将它分开,我会有更多专门的类,它们具有不同的角色。

任何进一步的建议,特别是关于编码最佳实践[我可能不会遵循],也是受欢迎的!

1 个答案:

答案 0 :(得分:1)

这不容易以一种好的方式回答。所以我只能关注它的一些小部分。为了不重复代码,我会说你给出的第一个例子有很多重复的代码:

class Subject
{
    /**
     * @var ParametrizedQueryFetchQueryFactory
     */
    private $queryFactory;

    public function __construct($DB, $Keyword, $Language) {

        $this->queryFactory = new ParametrizedQueryFetchQueryFactory($DB, $Language, [$Keyword]);
    }

    private function query($query, array $args = array()) {
        return $this->queryFactory->query($query, $args);
    }

    public function retrieveTitle() {

        return $this->query("SELECT * FROM subject WHERE keyword = ? ORDER BY DATE DESC LIMIT 1");
    }

    public function retrieveChapter($part) {
        return $this->query(
            "SELECT * FROM chapters WHERE subject_keyword = ? AND TYPE = ? ORDER BY DATE DESC LIMIT 1",
            [$part]
        );
    }
}

class ParametrizedQueryFetchQueryFactory
{
    private $db, $returnIndex, $defaultArgs;

    public function __construct($db, $returnIndex, array $defaultArgs = array()) {
        $this->db = $db;
        $this->returnIndex = $returnIndex;
        $this->defaultArgs = $defaultArgs;
    }

    public function query($query, array $args = array()) {
        $fetcher = new ParametrizedQueryFetch($this->db,$query, $this->returnIndex, $this->defaultArgs);
        return $fetcher->execute($args);
    }
}

class ParametrizedQueryFetch
{
    private $db, $query, $returnIndex, $defaultArgs;
    public function __construct($db, $query, $returnIndex, array $defaultArgs = array()) {
        $this->db = $db;
        $this->query = $query;
        $this->returnIndex = $returnIndex;
        $this->defaultArgs = $defaultArgs;
    }

    public function execute(array $args) {
        $args = array_merge($this->defaultArgs, $args);
        $stmt = $this->db->prepare($this->query);
        $stmt->excute($args);
        return $stmt->fetch()[$this->returnIndex];
    }
}

顺便说一句,为了使PHP 5.3兼容,你只需要在这里改变一行。