2013-01-05 4 views
0

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

을 그리고 직접 속성에 액세스 :이 클래스는 반드시 오타를 가지고 테스트되지 않았습니다, 그것은 차이를 ilustrate 만 여기에, 그래서 (적어도 literaly)를 사용하지 마십시오 또는 중간에 get()을 빌드 할 수도 있지만 아이디어는 얻을 수 있습니다.)

그래서 차이가 있습니까? 클래스의 첫 번째 메소드와 두 번째 클래스의 이점과 함정은 무엇입니까? 처음에는 메모리 사용량이 약간 작아야하지만,이 경우 가독성과 비교하여 거래 차단기가되지는 않을 것이라고 생각합니다.

편집 : 다른 사람들이 이해할 수있는 방식으로 질문을 작성하면 다른 방식으로 생각하게됩니다. 첫 번째 방법은 테스트하기가 더 쉬워 보입니다.

두 번째 우려 사항. 데이터를 저장하는 메소드를 만들려면 동일한 클래스 또는 다른 클래스에 저장해야합니까? 왜냐하면 내가 하나의 꽤 독립적 인 클래스에서 모든 주제 관련 메소드를 번들로 묶어 놓기 때문에, 그것을 분리하면 분리 된 역할을 가진보다 특수화 된 클래스가 생기기 때문입니다.

[내가 따르지 않을 수도있는] 베스트 프랙티스 코딩에 대한 추가 조언도 환영합니다!

답변

1

좋은 방법으로 대답하는 것은 쉽지 않습니다. 그래서 나는 그것의 사소한 부분에만 집중할 수 있습니다. 코드를 반복하지, 난 당신이주는 첫 번째 예는 꽤 반복 코드가 말하고 싶지만 : BTW

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

및 5.3 호환, 당신은 여기에 한 줄을 변경해야 할 경우에만 것이 PHP 만들어보세요.

+0

실제로 코드 반복을 피하기 위해 원래 코드를 편집했습니다. 그러나 코드가 얼마나 오래되었는지 실제로는 놀랍고 실제로 작동하는 방법을 이해하는 데 실제로 시간이 걸립니다. 지금은 그렇지만 왜 그런지 모르겠습니다. 코드를 사용하면 훨씬 더 길다는 것을 증명할 수있는 이점에 대해 궁금합니다. 그렇다면이 코드는 무엇입니까? BTW, 정교한 답변을 주셔서 감사합니다! –

+0

코드에서 데이터베이스의 데이터에 인터페이스를 제공하는 쉘 클래스 내에서 실행되는 매개 변수화 된 1000 개의 매개 변수가있는 경우 해당 사례에 대한 작업을 수행하는 무언가를 추가하는 것이 좋습니다. 클래스 내에서 매개 변수화되고 부분적으로 미리 구성된 쿼리를 실행하는 것과 같습니다. 그게 다야. 물론 두 함수가 너무 장황하다면 public 함수에서도 private function query()에 코드를 넣을 수 있습니다. 그것은 첫 걸음이었습니다. – hakre

관련 문제