Node.js 应用程序中的领域驱动设计
Domain Driven Design in Node.js Application
TL;博士;
我正在寻找 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/01/13]
我已经在 TypeScript 中创建了示例应用程序。目前没有存储库,也没有太多服务。欢迎提出问题和请求请求。
https://github.com/dawiddominiak/ddd-typescript-bin-packing-problem-solution
许多人会争辩说 JavaScript 不适合将复杂问题建模为领域模型,然后再转换为代码。如果域名属于商业、工业和商业领域,而不是计算机或数据科学领域,情况尤其如此。
我并不是说不能在 JavaScript 中创建领域模型。就像可以在 C 中创建一个一样。但这是否意味着应该这样做?
您给出的示例使用了领域驱动设计中的一些术语,但没有理解应用它的全部目的和精神。
我是 Node.js 世界的新手。
但我相信如果您使用 TypeScript 和 Node 来完成您的工作,您可以强制使用大部分 DDD 原则。
node.js 中的问题 "and advantage in the same time" 没有像 C# 或 Java 这样的 OOP 语言那样的限制。 Java脚本的这种自由 "and messy" 使得创建强大的复杂域模型和业务逻辑变得非常困难
我现在正想做同样的事情,我来自 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 是一个单例,它知道不同的实体以及如何持久化它们。在许多情况下,这无疑会在每个实体的基础上委托给不同的存储库对象。然而,这可能并不总是正确的。一个简单的内存存储库,每个实体都可以有一个对象数组。
剩下 Services/Interactors - functions/classes 确实有效。这些很简单——它们是获取域对象、执行一些业务逻辑以及在 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 尝试。所以我正在考虑这样写。
无论如何,考虑到您 post 已经一年了,您可能已经离开了。希望这对您/社区有所帮助!
TL;博士; 我正在寻找 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/01/13]
我已经在 TypeScript 中创建了示例应用程序。目前没有存储库,也没有太多服务。欢迎提出问题和请求请求。 https://github.com/dawiddominiak/ddd-typescript-bin-packing-problem-solution
许多人会争辩说 JavaScript 不适合将复杂问题建模为领域模型,然后再转换为代码。如果域名属于商业、工业和商业领域,而不是计算机或数据科学领域,情况尤其如此。
我并不是说不能在 JavaScript 中创建领域模型。就像可以在 C 中创建一个一样。但这是否意味着应该这样做?
您给出的示例使用了领域驱动设计中的一些术语,但没有理解应用它的全部目的和精神。
我是 Node.js 世界的新手。
但我相信如果您使用 TypeScript 和 Node 来完成您的工作,您可以强制使用大部分 DDD 原则。
node.js 中的问题 "and advantage in the same time" 没有像 C# 或 Java 这样的 OOP 语言那样的限制。 Java脚本的这种自由 "and messy" 使得创建强大的复杂域模型和业务逻辑变得非常困难
我现在正想做同样的事情,我来自 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 是一个单例,它知道不同的实体以及如何持久化它们。在许多情况下,这无疑会在每个实体的基础上委托给不同的存储库对象。然而,这可能并不总是正确的。一个简单的内存存储库,每个实体都可以有一个对象数组。
剩下 Services/Interactors - functions/classes 确实有效。这些很简单——它们是获取域对象、执行一些业务逻辑以及在 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 尝试。所以我正在考虑这样写。
无论如何,考虑到您 post 已经一年了,您可能已经离开了。希望这对您/社区有所帮助!