J'essaie de suivre le principe DRY dans ma programmation aussi fort que possible. Récemment, j'ai appris des modèles de conception en POO et j'ai fini par me répéter beaucoup.
J'ai créé un modèle de référentiel avec des modèles d'usine et de passerelle pour gérer ma persistance. J'utilise une base de données dans mon application, mais cela ne devrait pas avoir d'importance car je devrais pouvoir échanger la passerelle et passer à un autre type de persistance si je le souhaitais.
Le problème que j'ai fini par me créer est que je crée les mêmes objets pour le nombre de tables que j'ai. Par exemple, ce seront les objets dont j'ai besoin pour gérer une table 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);
}
}
Ensuite, mon contrôleur ressemble
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));
}
}
J'ai donc pensé utiliser correctement les modèles de conception et conserver les bonnes pratiques, mais le problème avec cette chose est que lorsque j'ajoute une nouvelle table, je dois créer les mêmes classes uniquement avec d'autres noms. Cela me fait soupçonner que je fais peut-être quelque chose de mal.
J'ai pensé à une solution où, au lieu d'interfaces, j'avais des classes abstraites qui, à l'aide du nom de classe, définissaient le tableau qu'elles devaient manipuler, mais cela ne semblait pas être la bonne chose à faire, si je décidais de passer à un stockage de fichiers ou memcache où il n'y a pas de tables.
Suis-je en train de l'aborder correctement ou y a-t-il une perspective différente que je devrais envisager?