模型应该在MV *中有一个保存方法吗?
我经常在Knockout,Ember和有时甚至是Angular之间来回跳转,但我常常遇到的问题之一就是模型在它的类或原型上有一个保存方法,它知道如何保存更改以减少应用程序周围的依赖关系服务(也就是说模型有一个服务,用于保存所有其他视图模型/控制器通过了解模型继承)或者是否应该有一个服务,每个视图模型/控制器依赖于具有保存更改的特定方法对象?
示例JavaScript伪代码
var person = new Model.Person(); person.name = 'Bill'; person.save();
VS
var personService = require('services/person.service'); var person = new Model.Person(); person.name = 'Bill'; personService.save(person);
两者都实现了保存人员的相同目的,但在示例1中,视图模型/控制器不了解服务或如何实现服务,只有当您想要更改某个人时,才能保存它.在示例二中,我们不仅要了解保存方法,还要了解如何实现保存.
请在回答前阅读 –
我意识到这是一个基于意见的问题,但如果你能用事实来支持你的意见,那将是事实,所以请提及备份任何索赔,以便不会因为’主要基于意见’而关闭
解决方法
>您的第一个示例:具有.save方法的域对象称为ActiveRecord(另请参见here).
>您的第二个示例:数据映射和域图层之间的映射器称为Repository(另请参见here)
活动记录模式
引用福勒:
An object that wraps a row in a database table or view,encapsulates the database access,and adds domain logic on that data.
ActiveRecord模式通常在原型设计方面表现优异,并且有时在非常小的应用程序中是一个好主意,在这些应用程序中,对象和数据库行之间存在1-1映射.通常,您希望将持久化对象的逻辑与实际域对象的逻辑分开,因为它们本质上是不同的职责.
这是逻辑上处理数据持久性的最简单方法之一.
例如,Backbone模型和集合使用它们的sync()方法.这导致它们持久存储到服务器.这通常是你看到较大的Backbone应用程序不使用sync()而完全支持实现自己的适配器的原因.毕竟,在Backbone世界中,它强制在您的REST API和您的域对象之间进行1-1映射,从而有效地使您的域对象和数据传输对象相同,随着应用程序的增长,这些对象会变得难以维护.
存储库模式
再次引用福勒:
Mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects.
对于较大的应用程序,存储库通常是更好的设计模式,因为它从域对象中删除了持久性逻辑,因此它做得更好separation of concerns.
实现明智,存储库通常如下所示:
但是,对于其用户,存储库可能如下所示:
作为任何抽象,另一个责任对象有一些开销,但是随着应用程序的增长,它开始得到回报.如果使用Angular创建$资源并将其包装在将这些对象从db查询映射到域对象(数据映射器)的服务中,然后像集合一样查询该服务 – 这就是您的存储库.