Ich versuche, das DRY-Prinzip in meiner Programmierung so genau wie möglich zu befolgen. Vor kurzem habe ich Designmuster in OOP gelernt und mich am Ende ziemlich oft wiederholt.
Ich habe ein Repository-Muster zusammen mit einem Factory- und einem Gateway-Muster erstellt, um meine Persistenz zu gewährleisten. Ich verwende eine Datenbank in meiner Anwendung, aber das sollte keine Rolle spielen, da ich das Gateway austauschen und auf Wunsch zu einer anderen Art von Persistenz wechseln kann.
Das Problem, das ich letztendlich für mich selbst erstellt habe, ist, dass ich dieselben Objekte für die Anzahl der Tabellen erstelle, die ich habe. Zum Beispiel sind dies die Objekte, die ich brauche, um eine Tabelle zu behandeln 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);
}
}
Dann sieht mein Controller aus wie
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));
}
}
Also dachte ich, ich würde Designmuster richtig verwenden und bewährte Methoden beibehalten, aber das Problem bei dieser Sache ist, dass ich beim Hinzufügen einer neuen Tabelle dieselben Klassen nur mit anderen Namen erstellen muss. Dies lässt den Verdacht aufkommen, dass ich etwas falsch mache.
Ich dachte an eine Lösung, bei der ich anstelle von Schnittstellen abstrakte Klassen hatte, die unter Verwendung des Klassennamens die Tabelle ermitteln, die sie bearbeiten müssen, aber das scheint nicht das Richtige zu sein. Was ist, wenn ich mich entscheide, zu einem Dateispeicher zu wechseln oder Memcache, in dem keine Tabellen vorhanden sind.
Nähere ich mich dem richtig oder gibt es eine andere Perspektive, die ich betrachten sollte?