我正在重构我们的BI层,以使我们的代码更"松散耦合",我有兴趣听到你们认为可能有意义的改进吗?
目前,我们的API类似于以下内容: -
// Fetch a collection of objects ProductCollection prods = Product.GetProducts(); // Load an individual object, make change and save it back Product p = new Product(); if(p.Load(productID)) { p.Name = "New Name"; p.Save(); }
如您所见,我们获取对象集合/加载单个对象和保存更改的方法都内置在"Model"类中.我们的每个Model类都继承自ObjectBase基类,该基类包括数据库访问函数和更改跟踪,因此当有人通过属性更改值时,对象会自动标记为脏,并且会向任何订阅这些事件的对象(UI)触发通知.
我想要做的是使用"存储库模式",以便我们可以从模型中抽象出数据库实现.但是,我一直在研究的大部分代码似乎都暗示"模型"类不应该包含任何智能,而应该只是数据的容器.相反,应该通过使用服务来应用逻辑.这是否意味着完成上述我需要做的事情
Listprods = ProductService.GetProducts(); Product p = ProductService.GetSingleProduct(productID); p.Name = "New Name"; ProductService.SaveProduct(p);
这似乎是一种更复杂的方式,并且使得在业务对象中封装功能变得更加困难.
有人可以解释为什么这是一个更好的方式,或者我可能误解了这些概念?
谢谢
詹姆士
您当前的API是Active Record Pattern的实现.当代码中使用的对象模型与数据库模型一对一匹配时,此模式可以正常工作.另一个优点是存在工具来生成这些类,包括持久性代码和数据库表.
您建议的替代方案是存储库模式.正如您已经提到的,实现这一点有点复杂,但有几个优点.由于您可以实现任何类型的ORM工具,因此您不仅限于一对一映射,而是可以实现更复杂的映射,其中对象模型可以与数据库模型不同.因此,您不必在数据库中强制使用对象模型,反之亦然.然而,除了一对一之外,更复杂的映射不能生成并且需要一些
另一个优点是您可以更轻松地创建测试,因为您可以创建甚至不需要数据库的Mock存储库.
使用存储库模式,您还可以将模型与持久性逻辑分开.
在这两种情况下,都可以以泛型方式编写持久性方法,以便持久性代码是通用的,不需要知道需要持久化的特定对象.这对于Active Record Pattern来说是显而易见的,因为所有这些对象都实现了保存,删除,更新等.对于Repository Pattern,您还可以使用适用于任何对象的ORM工具,以便像这样的代码:
Repository.Save(ObjectOfAnyType);
只要ORM工具为对象类型定义/实现了一些映射,ObjectOfAnyType就可以是任何东西.
所以你选择,你想要或需要这些优势,但代价是增加一点复杂性.或者Active Record Pattern的简单性是否足够.
我总是倾向于使用存储库模式,但有时使用Active Record Pattern,主要用于快速原型设计.