Это плохой объектно-ориентированный PHP? - PullRequest
0 голосов
/ 30 июля 2009

Я создал экранный объект, который содержит верхний и нижний колонтитулы:

class Display {
    protected $framework;
    public $mysql;
    public function __construct() {
        $this->mysql = new MySQL();
        $this->framework .= $this->header();
        $this->framework .= $this->body();
        $this->framework .= $this->sidebar();
        $this->framework .= $this->footer();
    }
    private function header (){ /* blah */ }
    private function body (){  }
    private function sidebar (){ /* blah */ }
    private function footer (){ /* blah */ }
    public function displayPage(){
        print $this->framework;
    }
}

На каждой странице я создал объект, расширяющий объект Display, с кодом для тела:

class IndexPHP extends Display {
    public function body(){
        $this->user = new User();
        return '<div class="body">Hello ' . $this->user->getName() . '</div>';
    }
}
$page = new IndexPHP();
$page->displayPage();

Я создал проблему, вложив слишком много объектов? Например, как получить доступ к уже инициированному объекту MySQL в объекте User?

class User {
    protected $name;
    public function __construct() {
        $this->id = /* MySQL object query here */
    }
}

Ответы [ 3 ]

7 голосов
/ 30 июля 2009

Проблема с подходом, который вы дали, заключается в том, что вы не следуете каким-либо принципам «разделения властей». Ваш экранный объект имеет базу данных, а также логику того, как к нему подключиться; это, вероятно, не лучший подход («объект Бога»). Может быть, лучше следовать принципам MVC (модель-представление-контроллер), когда у вас есть один класс, который знает что-то о вашей модели (базе данных), другой, который знает, как преобразовать модель в объекты, которые будут представлены (контроллер) и третий, который на самом деле показывает данные со всеми их достоинствами CSS (вид, часто просто файл шаблона PHP).

Я бы порекомендовал вам взглянуть на существующую инфраструктуру MVC - я использую QCubed (http://qcu.be),, есть другие - Symfony, Zend, CakePHP. Все они предлагают вам отличный способ аккуратно разделить ваш код, что в конечном итоге приводит к ремонтопригодности.

1 голос
/ 30 июля 2009

Например, как получить доступ к уже инициированному объекту MySQL в объекте User?

Вы передаете это в конструкторе:

class User {
  protected $name;
  public function __construct($mysql) {
    $this->id = $mysql->something();
  }
}
0 голосов
/ 30 июля 2009

Если вы переопределяете функции в дочерних классах (например, ваш класс IndexPHP переопределяет body()), вы должны сделать их protected вместо private.

Кроме того, хорошей практикой является использование в конструкторе только простых вещей, таких как присвоение значений. Ваш конструктор Display выполняет всю работу в классе, возможно, было бы лучше перенести строительные работы на displayPage:

public function __construct(MySQL $mysql) {
    $this->mysql = $mysql;
}

public function displayPage($rebuild=false) {

    if(empty($this->framework) || $rebuild) {
        $this->framework = $this->header();
        $this->framework .= $this->body();
        $this->framework .= $this->sidebar();
        $this->framework .= $this->footer();
    }
    print $this->framework;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...