Я стараюсь следовать принципу СУХОЙ в своем программировании изо всех сил. Недавно я изучал шаблоны проектирования в ООП и закончил тем, что повторял себя довольно много.
Я создал шаблон Repository вместе с шаблонами 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, где нет таблиц.
Правильно ли я подхожу к этому или есть другой взгляд на меня?