Tôi đang cố gắng tuân theo nguyên tắc DRY trong lập trình của mình hết sức có thể. Gần đây tôi đã học các mẫu thiết kế trong OOP và cuối cùng tôi đã lặp lại khá nhiều.
Tôi đã tạo một mẫu Kho lưu trữ cùng với các mẫu Factory và Gateway để xử lý sự kiên trì của tôi. Tôi đang sử dụng cơ sở dữ liệu trong ứng dụng của mình nhưng điều đó không thành vấn đề vì tôi có thể trao đổi Gateway và chuyển sang một loại kiên trì khác nếu tôi muốn.
Vấn đề tôi đã tự tạo ra cho mình là tôi tạo cùng một đối tượng cho số lượng bảng tôi có. Ví dụ, đây sẽ là các đối tượng tôi cần để xử lý một bảng 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);
}
}
Sau đó, bộ điều khiển của tôi trông giống như
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));
}
}
Vì vậy, tôi nghĩ rằng tôi đã sử dụng các mẫu thiết kế một cách chính xác và giữ các thông lệ tốt, nhưng vấn đề với điều này là khi tôi thêm một bảng mới, tôi phải tạo cùng một lớp chỉ với các tên khác. Điều này làm tăng sự nghi ngờ trong tôi rằng tôi có thể đang làm gì đó sai.
Tôi đã nghĩ đến một giải pháp thay vì các giao diện, tôi có các lớp trừu tượng sử dụng tên lớp để tìm ra bảng mà họ cần thao tác nhưng dường như đó không phải là điều đúng, nếu tôi quyết định chuyển sang lưu trữ tệp hoặc memcache nơi không có bảng.
Tôi đang tiếp cận điều này một cách chính xác, hay có một quan điểm khác mà tôi nên xem xét?