Я намагаюся слідувати принципу DRY в моєму програмуванні так сильно, як можу. Нещодавно я вивчав шаблони дизайну в OOP, і в кінцевому підсумку повторював себе досить багато.
Я створив шаблон репозиторію разом із візерунками Factory і Gateway, щоб вирішити свою стійкість. Я використовую базу даних у своїй програмі, але це не має значення, оскільки я маю змогу поміняти шлюз і перейти на інший вигляд, якщо хочу.
Проблема, яку я створив для себе, полягає в тому, що я створюю ті самі об’єкти для кількості таблиць, які я маю. Наприклад, це будуть об'єкти, які мені потрібні для обробки таблиці comments.
class Comment extends Model {
protected $id;
protected $author;
protected $text;
protected $date;
}
class CommentFactory implements iFactory {
public function createFrom(array $data) {
return new Comment($data);
}
}
class CommentGateway implements iGateway {
protected $db;
public function __construct(\Database $db) {
$this->db = $db;
}
public function persist($data) {
if(isset($data['id'])) {
$sql = 'UPDATE comments SET author = ?, text = ?, date = ? WHERE id = ?';
$this->db->prepare($sql)->execute($data['author'], $data['text'], $data['date'], $data['id']);
} else {
$sql = 'INSERT INTO comments (author, text, date) VALUES (?, ?, ?)';
$this->db->prepare($sql)->execute($data['author'], $data['text'], $data['date']);
}
}
public function retrieve($id) {
$sql = 'SELECT * FROM comments WHERE id = ?';
return $this->db->prepare($sql)->execute($id)->fetch();
}
public function delete($id) {
$sql = 'DELETE FROM comments WHERE id = ?';
return $this->db->prepare($sql)->execute($id)->fetch();
}
}
class CommentRepository {
protected $gateway;
protected $factory;
public function __construct(iFactory $f, iGateway $g) {
$this->gateway = $g;
$this->factory = $f;
}
public function get($id) {
$data = $this->gateway->retrieve($id);
return $this->factory->createFrom($data);
}
public function add(Comment $comment) {
$data = $comment->toArray();
return $this->gateway->persist($data);
}
}
Тоді виглядає мій контролер
class Comment {
public function view($id) {
$gateway = new CommentGateway(Database::connection());
$factory = new CommentFactory();
$repo = new CommentRepository($factory, $gateway);
return Response::view('comment/view', $repo->get($id));
}
}
Тому я подумав, що я правильно використовую шаблони дизайну і дотримуюся належних практик, але проблема в цьому полягає в тому, що коли я додаю нову таблицю, я повинен створювати ті самі класи просто з іншими іменами. Це викликає у мене підозру, що я можу робити щось не так.
Я подумав про рішення, де замість інтерфейсів у мене були абстрактні класи, які за допомогою імені класу визначають таблицю, з якою їм потрібно маніпулювати, але це не здається правильним робити, що робити, якщо я вирішу перейти на сховище файлів або memcache там, де немає таблиць.
Чи правильно я підходжу до цього, чи є інша перспектива, на яку я повинен дивитися?