Đối với tôi, các kho lưu trữ, kết hợp với ORM hoặc các lớp lưu giữ DB khác, có những nhược điểm sau:
- Bao gồm các đơn vị công việc. UoW phải được lập trình viên mã hóa và hiếm khi có thể được triển khai như một loại phép thuật trong nền, nơi người dùng chỉ cần thực hiện các truy vấn và sửa đổi, mà không xác định ranh giới UoW và có thể là điểm cam kết. Đôi khi, UoW bị bỏ qua bằng cách giảm chúng thành micro UoW (ví dụ: phiên NHibernate) trong mỗi phương thức truy cập Kho lưu trữ.
- Che đậy, hoặc, trong trường hợp xấu nhất, tiêu diệt Sự thiếu hiểu biết dai dẳng: Các phương thức như "Tải ()", "Nhận ()", "Lưu ()" hoặc "Cập nhật ()" đề xuất các thao tác đối tượng đơn lẻ, ngay lập tức, như thể gửi từng cá nhân SQL / DML hoặc như thể làm việc với các tệp. Trong thực tế, ví dụ, các phương thức NHibernate, với các tên gây hiểu lầm này, thường không tạo quyền truy cập riêng lẻ, nhưng hãy sử dụng tải lười biếng hoặc chèn / cập nhật hàng loạt (Sự thiếu hiểu biết dai dẳng). Đôi khi, các lập trình viên tự hỏi tại sao họ không nhận được các hoạt động DB ngay lập tức và buộc phải phá vỡ sự thiếu hiểu biết dai dẳng, do đó giết chết hiệu suất và sử dụng các nỗ lực lớn để thực sự làm cho hệ thống trở nên tồi tệ hơn.
- Tăng trưởng không kiểm soát. Một kho lưu trữ đơn giản có thể tích lũy ngày càng nhiều phương thức để phù hợp với nhu cầu cụ thể.
Nhu la:
public interface ICarsRepository /* initial */
{
ICar CreateNewCar();
ICar LoadCar(int id); // bad, should be for multiple IDs.
void SaveCar(ICar carToSave); // bad, no individual saves, use UoW commit!
}
public interface ICarsRepository /* a few years later */
{
ICar CreateNewCar();
ICar LoadCar(int id);
IList<ICar> GetBlueCars();
IList<ICar> GetRedYellowGreenCars();
IList<ICar> GetCarsByColor(Color colorOfCars); // a bit better
IList<ICar> GetCarsByColor(IEnumerable<Color> colorsOfCars); // better!
IList<ICar> GetCarsWithPowerBetween(int hpFrom, int hpTo);
IList<ICar> GetCarsWithPowerKwBetween(int kwFrom, int kwTo);
IList<ICar> GetCarsBuiltBetween(int yearFrom, int yearTo);
IList<ICar> GetCarsBuiltBetween(DateTime from, DateTime to); // some also need month and day
IList<ICar> GetHybridCarsBuiltBetween(DateTime from, DateTime to);
IList<ICar> GetElectricCarsBuiltBetween(DateTime from, DateTime to);
IList<ICar> GetCarsFromManufacturer(IManufacturer carManufacturer);
bool HasCarMeanwhileBeenChangedBySomebodyElseInDb(ICar car); // persistence ignorance broken
void SaveCar(ICar carToSave);
}
4. Đối tượng nguy hiểm của Chúa: bạn có thể bị cám dỗ tạo một lớp thần, bao trùm tất cả mô hình hoặc lớp truy cập dữ liệu của bạn. Lớp kho lưu trữ không chỉ chứa các phương thức Car mà còn các phương thức cho tất cả các thực thể.
Theo tôi, tốt hơn là cung cấp ít nhất một số cơ hội truy vấn, để tránh sự lộn xộn lớn của nhiều phương pháp mục đích duy nhất. Bất kể đó là LINQ, ngôn ngữ truy vấn riêng hay thậm chí là thứ được lấy trực tiếp từ ORM (OK, loại vấn đề ghép nối ...).