繁体   English   中英

Node.js应用程序中的域驱动设计

[英]Domain Driven Design in Node.js Application

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

我对Node.js世界很新。

但我相信如果你使用带有Node的TypeScript做你的工作你可以强制使用大多数DDD原则。

node.js中的问题“同时具有优势”,就像我们在C#或Java等OOP语言中没有那样的限制。 JavaScript的这种自由“和混乱” 使得创建强大的复杂DomainModel和业务逻辑非常困难

我现在想要做同样的事情,我来自Ruby世界。 所以,让我做两件事:

  1. 请指出我所见过的最好的Ruby实现,我发现了Domain-Driven Design,Hanami: http ://hanamirb.org/guides/models/overview/您可以将其作为参考。

  2. 讨论我正在寻找的东西(字面意思是现在,正如我输入的那样)试图在Node中找到类似物。

我找到了这个页面: https//github.com/sindresorhus/awesome-nodejs

它编制了大量高质量/高人气的Node包。

首先,我们需要为我们的域模型进行验证和模式构建。 只看数据验证部分的第一个条目,Joi似乎是一个不错的选择:

https://github.com/hapijs/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

无论您选择使用BookshelfSequelize还是LoopBack框架,您都可以编写一个适合上述接口的对象,然后执行与这些框架集成的脏工作。

如果我尝试不同的ORM,我会为上面的每一个创建一个不同的repo对象。 请注意,正如我所写,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尝试。 所以我正在考虑这样写它们。

无论如何,鉴于你的帖子已经过了一年,你可能已经继续前进了。 希望这有助于您/社区!

许多人认为JavaScript不适合将复杂问题建模为域模型,然后编写代码。 如果域名是商业,工业和商业,而不是计算机或数据科学,则尤其如此。

我不是说不能在JavaScript中创建域模型。 就像一个人可以在C中创建一个。但这是否意味着应该?

您提供的示例在域驱动设计中使用了一些术语,但忽略了应用它的整个目的和精神。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM