简体   繁体   English

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

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

I have several doubts about OOP PHP code I'm creating. 我对正在创建的OOP PHP代码有一些疑问。 It is (so far) for retrieving a title and several chapters in different languages stored online. (到目前为止)用于检索在线存储的标题和不同语言的几个章节。 But first I will show the code as my doubts refer to this. 但是首先,我将显示代码,因为我对此表示怀疑。 This is the class I'm currently working with: 这是我目前正在使用的课程:

<?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);
    }
?>

Then I do something similar to this to display the page: 然后,我做类似的事情来显示页面:

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

First concern. 首先关注。 I'm not sure if this is the proper way to handle this kind of data. 我不确定这是否是处理此类数据的正确方法。 I tried to separate the methods and make them as small as possible, trying also not to repeat much code. 我试图分离这些方法并使它们尽可能的小,也尝试不重复太多代码。 And this is the way that feels right. 这就是感觉正确的方式。 But I cannot see why this other code, similar to the previous one, is less desirable. 但是我不明白为什么与上一个类似的其他代码不太可取。 Note: This class has SURELY some typos and has not been tested, it's only here to ilustrate the difference, so please don't use it (at least not literaly): 注意:此类肯定有一些错别字,并且尚未经过测试,它只是在这里说明差异,因此请不要使用它(至少不是字面上的意思):

<?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];
      }
    }
  }
?>

And then access the properties directly (or even build some get() in the middle, but you get the idea). 然后直接访问属性(甚至在中间构建一些get(),但您知道了)。

So, is there any difference? 那么,有什么区别吗? What are the benefits and pitfalls of the first method vs the second to code the class? 第一种方法与第二种方法对类进行编码的优点和陷阱是什么? Memory usage should be slightly smaller in the first one, but I think that won't be a deal breaker in comparison to readability in this case. 在第一个中,内存使用量应该稍小一些,但是与这种情况下的可读性相比,我认为这不会造成任何问题。

EDIT: Just writing the question in a way for others to understand has lead me to think about it in other ways. 编辑:只是以一种让其他人理解的方式写问题,已经导致我以其他方式思考它。 The first way also looks easier to test. 第一种方法看起来也更容易测试。

Second concern. 第二关注。 If I want to make a/some methods for saving data, should I put it in the same class or in a different one? 如果我想使用一种/某些方法来保存数据,应该将其放在同一类中还是在另一类中? Because if I put it in one it bundles all the subject related methods in one pretty independent class, if I separate it I have more specialized classes with separated roles. 因为如果将它放在一个实例中,它将所有与主题相关的方法捆绑在一个相当独立的类中,所以如果我将其分离,则我将拥有角色更分离的更专业的类。

Any further advice, specifically about coding best practices [that I might not be following], is also welcome! 也欢迎任何进一步的建议,特别是关于编码最佳实践的建议[我可能不会遵循]。

This is not easy to answer in a good way. 这很难以很好的方式回答。 So I can only focus on some minor parts of it. 因此,我只能专注于其中的一小部分。 For not repeating code, I'd say the first example you give has quite some repeated code: 对于不重复的代码,我想说您给出的第一个示例中有很多重复的代码:

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];
    }
}

And btw, to make this PHP 5.3 compatible, you would only need to change a single line here. 顺便说一句,要使此PHP 5.3兼容,您只需要在此处更改一行即可。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM