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


One method retrieves all the data or few smaller methods retrieve each part?

我对我正在创建的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(),但是你明白了)。

那么,有什么区别吗?第一个方法与第二个方法编码类的优点和缺点是什么?在第一种情况下,内存使用应该稍微小一点,但我认为在这种情况下,与可读性相比,这不会是一个问题。

编辑:只是用一种别人能理解的方式来写这个问题,这让我从另一个角度来思考。第一种方法看起来也更容易测试。

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

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

这不是一件容易的事。所以我只能关注其中的一小部分。为了不重复代码,我要说你给出的第一个例子有相当多的重复代码:

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兼容,您只需要更改这里的一行。