Изучение ООП — распределение логики и разделение ответственности

Пытаясь перейти от глобального процедурного кодирования к более ООП-ориентированному стилю, я реорганизую веб-сайт для журнала.

Одно из условий проверки на сервере — передан ли идентификатор статьи или комбинация года / выпуска. В первом случае пользователю должна быть предоставлена ​​конкретная статья, во втором — оглавление и изображение. обложка для выбранного номера. Мне также нужно получить год и выпустить для отображения во втором случае.

Моим первым инстинктом было поместить всю логику в конструктор:

class Magazine {
public $year;
public $issue;
public function __construct($year, $issue, $articleId = 0) {
if($articleId > 0) {
// Get article from database
$this->year = // get year from search results;
$this->issue = // get number from search results;
} else {
// Get table of contents and cover image
}
}
}

// Create an instance either like this:
$magazine = new Magazine(1985, 3);
// Or like this:
$magazine = new Magazine(0, 0, 172);

Но потом я понял, что, вероятно, не стоит «перегружать» конструктор таким образом (чтобы компенсировать невозможность его перегрузить в обычном смысле?).

Итак, я создаю метод для извлечения статьи, например так:

class Magazine {
public $year;
public $issue;
private $articleId;
public function __construct($year, $issue, $articleId = 0) {
$this->year = $year;
$this->issue = $issue;
$this->articleId = $articleId;
}
public function getArticle() {
// Use $this->articleId to retrieve data from database
// Set $this->year and $this->issue to appropriate values
}
}

Или без конструктора:

class Magazine {
public $year;
public $issue;
public function getArticle($articleId) {
// Use $articleId to retrieve data from database
// Set $this->year and $this->issue to appropriate values
}
}

Нет, присвоение значений году и свойствам выпуска не является частью получения статьи. Поэтому я создаю другой метод для этого:

public function getYearAndIssue($articleId) {
// Use $articleId to retrieve data from database
}

Но теперь мне нужно подключиться к базе данных дважды. Нехорошо. Кажется, мне нужно собрать все данные, которые мне нужны при первом подключении к БД. И где мне это сделать? В конструкторе? Нет, это просто вернет меня на круги своя. Или минус один.

Так куда мне идти отсюда? Два метода, как getArticleAndEverythingElseINeedForThat() { // ... } а также getCoverAndEverythingElseINeedForThat() { ... }?

РЕДАКТИРОВАТЬ: Благодаря комментарию Даана я поэкспериментировал еще немного и придумал следующее:

class Magazine {
private $db;
public function __construct($db) {
$this->db = $db;
}
public function getArticle($articleId) {
$sql = "SELECT article FROM table WHERE id = :id";
$ph = array(':id' => $articleId);
$ps = $this->db -> prepare($sql);
$ps -> execute($ph);
// Do some more stuff
return $article;
}
public function getYearAndIssue($articleId) {
$sql = "SELECT year, issue FROM table WHERE id = :id";
$ph = array(':id' => $articleId);
...
return array($year, $issue);
}
}

class Database {
public static function getConnection() {
$db = new PDO(...);
$db->setAttribute(...);
...
return $db;
}
}

$db = Database::getConnetion();
$magazine = new Magazine($db);
$article = $magazine->getArticle(59);
list($year, $issue) = $magazine->getYearAndIssue(59);

Новые вопросы:

Кажется ли я близко, чтобы понять инъекции?

В некоторых описаниях я видел, что объект PDO создается как частная переменная в конструкторе и передается в качестве аргумента вспомогательным функциям, то есть, как если бы я написал свой код следующим образом:

class Magazine {
private $db;
public function __construct($db) {
$this->db = $db;
}
public function getArticle($db, $articleId) {
// ...
}
}
$db = Database::getConnetion();
$magazine = new Magazine($db);
$article = $magazine->getArticle($db, 59);

Должен ли я сделать это тоже? Если так, то почему?

Даже если я использую одно и то же соединение с БД дважды (или чаще в реальном сценарии), мне все равно придется получать данные из БД несколько раз. Разве не было бы лучше / быстрее получить все, что мне нужно, от БД сразу (если это было бы возможно, не испортив логику снова / дальше)? Как это:

$sql = "SELECT article, year, issue FROM table WHERE id = :id";

1

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector