TL; DR; 我正在寻找DDD node.js应用程序的典型示例。
您好,
我要创建节点应用程序。我想知道我找不到任何在域中分离业务逻辑的应用程序示例。
好的,有一些例子: https://github.com/adrai/node-cqrs-domain - 但这是整个CQRS与事件采购实施。
我的想法是这样做:
//domain/book.js
function Book(title, author)
{
this._title = title;
this._author = author;
}
// domain methods ...
//infrastructure/persistance/repository/book-repository.js
function BookRepository()
{}
BookRepository.prototype.save(book)
{
var bookModel = mappers.mapToOrm(book);
return bookModel.save();
}
// [...] get, getAll, getNextId
//infrastructure/persistance/orm/book.js
//using http://bookshelfjs.org/
var Book = bookshelf.Model.extend({
tableName: 'books'
});
//infrastructure/mappers/book-mapper.js
function mapToOrm(book) {
//mapping [...]
return new persistance.Book();
}
function mapToDomain(domain) {
//mapping [...]
return new domain.Book();
}
但另一方面,我从未见过任何类似的解决方案(使用域模型,orm模型,存储库和映射器)。我是以正确的方式思考的吗?也许没有理由在node.js应用程序中分离域中的业务逻辑。如果是这样,为什么?如果没有,你能给我发一个DDD实现的例子或改进我的代码吗?
[2017年1月13日]
我在TypeScript中创建了示例应用程序。目前没有存储库,没有太多服务。欢迎提出问题和拉取请求。 https://github.com/dawiddominiak/ddd-typescript-bin-packing-problem-solution
答案 0 :(得分:5)
我对Node.js世界很新。
但我相信如果你使用 TypeScript with Node 进行工作,你可以强制使用大多数DDD原则。
问题"以及同时的优势"在node.js中,没有像C#或Java这样的OOP语言中的限制。而这种自由"和凌乱" JavaScript 非常难以创建健壮的复杂DomainModel和业务逻辑
答案 1 :(得分:4)
我现在想要做同样的事情,而且我来自Ruby世界。所以,让我做两件事:
指出我所见过的最好的Ruby实现,我已经发现,我发现了Hanami:http://hanamirb.org/guides/models/overview/你可以作为参考。
讨论我在尝试在Node中找到类似物的过程中发现的(现在字面意思,正如我输入的那样)。
我找到了这个页面:https://github.com/sindresorhus/awesome-nodejs
编制了大量高质量/高人气的Node软件包。
首先,我们需要为我们的域模型进行验证和模式构建。只看数据验证部分的第一个条目,Joi似乎是一个不错的选择:
对于域对象的持久性,我只是设置一个存根对象,借用Hanami的界面:
var repo = {
find: function(entity_name, id) {
// - Fetch an entity from the collection by its ID
},
create: function(entity_name, data) {
// – Create a record for the given data and return an entity
},
update: function(entity_name, id, data) {
// – Update the record corresponding to the id and return the updated entity
},
delete: function(entity_name, id) {
// – Delete the record corresponding to the given entity
},
all: function(entity_name) {
// - Fetch all the entities from the collection
},
query: function(entity_name, query_object) {
},
first: function(entity_name) {
// - Fetch the first entity from the collection
},
last: function(entity_name) {
// - Fetch the last entity from the collection
},
clear: function(entity_name) {
// - Delete all the records from the collection
}
}
module.exports = repo
无论您选择使用Bookshelf
,Sequelize
,还是LoopBack
框架,您都可以编写一个符合上述界面的对象,然后执行以下操作:与这些框架相结合。
如果我尝试不同的ORM,我会为上面的每一个创建一个不同的repo对象。请注意,正如我已经写过的那样,回购是一个知道不同实体以及如何持久化它们的单例。在许多情况下,毫无疑问,这将基于每个实体委托给不同的存储库对象。但是,这可能并非总是如此。一个简单的内存中的repo,可以为每个实体提供一个对象数组。
离开服务/交互者 - 实际工作的函数/类。这些很容易 - 它们是采用域对象,执行某些业务逻辑的,并且在CRUD情况下,调用存储库。一个可能是语法错误的例子:
const repository = require('./myFileRepository')
function createBook(bookEntity) {
if(bookEntity.valid?) {
repository.create('book', bookEntity)
return true
}
else {
return { error: 'book not valid' }
}
}
module.exports = createBook
对于服务功能,我今天才了解节点机器,它们看起来非常聪明:http://node-machine.org
他们似乎是对monads +文档的JS尝试。所以我考虑把它们写成那样。
无论如何,鉴于你的帖子已经过了一年,你可能会继续前进。希望这有助于你/社区!
答案 2 :(得分:0)
许多人认为JavaScript不适合将复杂问题建模为域模型,然后编写代码。如果域名是商业,工业和商业,而不是计算机或数据科学,则尤其如此。
我不是说不能在JavaScript中创建域模型。就像一个人可以在C中创建一个。但这是否意味着应该??
您提供的示例在域驱动设计中使用了一些术语,但忽略了应用它的整个目的和理念。