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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34027990/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 17:08:29  来源:igfitidea点击:

Domain Driven Design in Node.js Application

javascriptnode.jsdomain-driven-design

提问by Dawid Dominiak

TL; DR; I'm looking for trite example of DDD node.js application.

TL; 博士;我正在寻找 DDD node.js 应用程序的陈腐示例。



Hi,

你好,

I'm going to create node application. I wonder that I can not find any example of application with business logic separated in domain.

我将创建节点应用程序。我想知道我找不到任何在域中分离业务逻辑的应用程序示例。

OK, there are some examples like: https://github.com/adrai/node-cqrs-domain- but this is whole CQRS with event sourcing implementation.

好的,有一些示例,例如:https: //github.com/adrai/node-cqrs-domain- 但这是带有事件源实现的整个 CQRS。

My idea is to do that like that:

我的想法是这样做:

//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();
}

but on the other hand I've never seen any similar solution (with domain model, orm model, repository and mappers). Am I thinking in the right way? Maybe there is no reason to separate business logic in domain in node.js applications. If so, why? If not, can you send me an example of DDD implementation or improve my code?

但另一方面,我从未见过任何类似的解决方案(使用域模型、orm 模型、存储库和映射器)。我的思考方式正确吗?也许没有理由在 node.js 应用程序中将域中的业务逻辑分开。如果是这样,为什么?如果没有,您能否向我发送 DDD 实现示例或改进我的代码?

[2017/01/13]

[2017/01/13]

I've created sample application in TypeScript. For now without repositories and not much services. Issues and pull requests are welcome. https://github.com/dawiddominiak/ddd-typescript-bin-packing-problem-solution

我已经在 TypeScript 中创建了示例应用程序。目前没有存储库,也没有太多服务。欢迎提出问题和请求请求。 https://github.com/dawiddominiak/ddd-typescript-bin-packing-problem-solution

采纳答案by Wahid Bitar

I'm very new to Node.js world.

我对 Node.js 世界很陌生。

But I believe if you do your work using TypeScript with Nodeyou can force most of DDD principles to be used.

但我相信,如果你使用TypeScript 和 Node完成你的工作你可以强制使用大部分 DDD 原则。

The problem "and advantage in the same time" in node.js that there aren't so restrictions like we have in OOP languages like C# or Java. and this freedom "and messy" of JavaScript making create robust complex DomainModel and Business logic very hard

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

回答by MissingHandle

I'm looking to do the same thing at the moment, and I'm coming from the Ruby world. So, let me do 2 things:

我目前正在做同样的事情,而且我来自 Ruby 世界。所以,让我做两件事:

  1. Point you to the best Ruby implementation I've seen of Domain-Driven Design I have found, Hanami: http://hanamirb.org/guides/models/overview/which you could use as a reference.

  2. Discuss what I'm finding (literally right now, as I type) to attempt to find the analogs in Node.

  1. 向您指出我发现的领域驱动设计的最佳 Ruby 实现,Hanami:http://hanamirb.org/guides/models/overview/ ,您可以将其用作参考。

  2. 讨论我的发现(字面意思是现在,当我输入时)以尝试在 Node.js 中找到类似物。

I've found this page: https://github.com/sindresorhus/awesome-nodejs

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

which catalogs a ton of high-quality / high-popularity Node packages.

其中列出了大量高质量/高人气的 Node 包。

The first thing is, we need something that is going to do validation and schema construction for our Domain Models. Just looking at the first entry in the data validation section, Joi seems to be a decent choice for that:

第一件事是,我们需要一些东西来为我们的领域模型进行验证和模式构建。看看数据验证部分的第一个条目,Joi 似乎是一个不错的选择:

https://github.com/hapijs/joi

https://github.com/hapijs/joi

For Persistence of the domain objects, I'm just setting up a stub object, borrowing from Hanami's interface:

对于域对象的持久性,我只是设置了一个存根对象,借用 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

whether you choose to use Bookshelf, Sequelize, or even the LoopBackframework, you can code an object that is going to fit the above interface that then does the dirty work of integrating with those frameworks.

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

If I were to try different ORM's, I would create a different repo object for each of the above. Notice that as I've written it, the repo is a singleton that is aware of different entities and how to persist them. In many cases, this will no doubt delegate to different repository objects on a per-entity basis. However, that might not always be true. a simple in-memory repo, could just have an array of objects for each entity.

如果我要尝试不同的 ORM,我会为上述每个对象创建一个不同的 repo 对象。请注意,正如我所写的,repo 是一个单例,它知道不同的实体以及如何持久化它们。在许多情况下,这无疑会在每个实体的基础上委托给不同的存储库对象。然而,这可能并不总是正确的。一个简单的内存存储库,每个实体可能只有一个对象数组。

That leaves Services/Interactors - The functions/classes that actually do work. These are easy - they are the ones that take a domain object, perform some business logic, and in the CRUD cases, make a call out to the Repository. A probably-syntactically-wrong example:

剩下的服务/交互器 - 实际工作的函数/类。这些很简单——它们是接受域对象,执行一些业务逻辑,并且在 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

for the Service functions, I just today learned about Node Machines, and they seem like a really smart idea: http://node-machine.org

对于服务功能,我今天刚刚了解了节点机器,它们似乎是一个非常聪明的想法:http: //node-machine.org

they seem to be a JS-attempt at monads + documentation. so I'm considering writing them up like that.

他们似乎是对 monads + 文档的 JS 尝试。所以我正在考虑这样写。

anyway, given it's been a year since your post, you've probably moved on. hope this helps you / the community!

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

回答by aryeh

Many would argue that JavaScript is NOT well suited to modeling a complex problem into a domain model and then into code. That's especially the case if the domain is in business, industry and commerce, rather than in computer or data science.

许多人会争辩说,JavaScript 不太适合将复杂问题建模为域模型,然后再将其建模为代码。如果该领域属于商业、工业和商业领域,而不是计算机或数据科学领域,则情况尤其如此。

I'm not saying one can't create a domain model in JavaScript. Just like one could create one in C. But does that mean one should?

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

The example you give uses some terminology in domain-driven design, but misses the whole purpose and ethos of applying it.

您给出的示例在域驱动设计中使用了一些术语,但没有理解应用它的整个目的和精神。