ฉันพยายามทำตามหลักการ DRY ในการเขียนโปรแกรมของฉันอย่างหนักที่สุดเท่าที่จะทำได้ เมื่อไม่นานมานี้ฉันได้เรียนรู้รูปแบบการออกแบบใน OOP แล้วและฉันก็ทำซ้ำตัวเองค่อนข้างมาก
ฉันสร้างรูปแบบ 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 ที่ไม่มีตาราง
ฉันเข้าใกล้สิ่งนี้อย่างถูกต้องหรือมีมุมมองที่ต่างออกไป