对我而言,存储库与ORM或其他DB持久性层结合在一起具有以下缺点:
- 掩盖工作单位。UoW必须由程序员进行编码,并且很少能在后台实现,就像用户在不定义UoW边界以及可能的提交点的情况下简单地进行查询和修改一样。有时,通过在每种存储库访问方法中将其简化为微型UoW(例如NHibernate会话)而放弃了UoW。
- 掩盖,或者在最坏的情况下,破坏持久性无知:诸如“ Load()”,“ Get()”,“ Save()”或“ Update()”之类的方法建议立即执行单个对象操作,就像发送单个对象一样SQL / DML,或者就像处理文件一样。实际上,例如,具有这些具有误导性的名称的NHibernate方法通常不进行单独访问,而是排队进行延迟加载或插入/更新批处理(Persistence Ignorance)。有时,程序员想知道为什么他们不立即执行数据库操作,而强行破坏了对持久性的无知,从而导致性能下降,并花了很大的力气使系统(很多!)变得更糟。
- 不受控制的增长。一个简单的存储库可能会积累越来越多的方法来满足特定需求。
如:
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.上帝的危险对象:您可能很想创建一个上帝类,覆盖所有模型或数据访问层。存储库类不仅包含Car方法,而且还包含所有实体的方法。
我认为,最好至少提供一些查询机会,以避免许多单一目的方法造成的混乱。无论是LINQ,自己的查询语言,还是直接取自ORM的东西(好的,都是耦合问题……)。