web-dev-qa-db-fra.com

Conception pilotée par domaine dans l'application Node.js

TL; DR; Je cherche un exemple banal d'application DDD node.js.


Salut,

Je vais créer une application de nœud. Je me demande que je ne trouve aucun exemple d'application avec une logique métier séparée dans le domaine.

OK, il y a quelques exemples comme: https://github.com/adrai/node-cqrs-domain - mais il s'agit de CQRS entier avec implémentation de sourcing d'événements.

Mon idée est de faire ça comme ça:

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

mais d'un autre côté, je n'ai jamais vu de solution similaire (avec le modèle de domaine, le modèle orm, le référentiel et les mappeurs). Suis-je en train de penser dans le bon sens? Il n'y a peut-être aucune raison de séparer la logique métier dans le domaine dans les applications node.js. Si oui, pourquoi? Sinon, pouvez-vous m'envoyer un exemple d'implémentation DDD ou améliorer mon code?

[13/01/2017]

J'ai créé un exemple d'application dans TypeScript. Pour l'instant sans référentiels et pas beaucoup de services. Les problèmes et les demandes de tirage sont les bienvenus. https://github.com/dawiddominiak/ddd-TypeScript-bin-packing-problem-solution

32
Dawid Dominiak

Je suis très nouveau dans le monde Node.js.

Mais je crois que si vous faites votre travail en utilisant TypeScript with Node vous pouvez forcer la plupart des principes DDD à être utilisés.

Le problème "et l'avantage en même temps" dans node.js qu'il n'y a pas autant de restrictions que nous avons dans OOP langages comme C # ou Java. Et cette liberté "et désordonnée" de JavaScript rendant très difficile la création de robustes complexes DomainModel et Business Logic

6
Wahid Bitar

Je cherche à faire la même chose en ce moment, et je viens du monde Ruby. Alors, laissez-moi faire 2 choses:

  1. Pointez-vous vers la meilleure Ruby implémentation que j'ai vue de la conception pilotée par domaine que j'ai trouvée, Hanami: http://hanamirb.org/guides/models/overview/ que vous pourriez utiliser comme référence.

  2. Discutez de ce que je trouve (littéralement en ce moment, pendant que je tape) pour essayer de trouver les analogues dans Node.

J'ai trouvé cette page: https://github.com/sindresorhus/awesome-nodejs

qui catalogue une tonne de packages de haute qualité/haute popularité Node packages.

La première chose est que nous avons besoin de quelque chose qui va faire la validation et la construction de schéma pour nos modèles de domaine. En regardant la première entrée de la section de validation des données, Joi semble être un choix décent pour cela:

https://github.com/hapijs/joi

Pour la persistance des objets de domaine, je configure simplement un objet stub, empruntant à l'interface de 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

que vous choisissiez d'utiliser Bookshelf, Sequelize, ou même le cadre LoopBack, vous pouvez coder un objet qui va s'adapter à l'interface ci-dessus qui fait ensuite le sale boulot de l'intégration à ces cadres.

Si je devais essayer différents ORM, je créerais un objet de dépôt différent pour chacun des éléments ci-dessus. Notez que comme je l'ai écrit, le dépôt est un singleton qui connaît différentes entités et comment les conserver. Dans de nombreux cas, cela se déléguera sans doute à différents objets de référentiel sur une base par entité. Cependant, cela pourrait ne pas toujours être vrai. un simple dépôt en mémoire, pourrait simplement avoir un tableau d'objets pour chaque entité.

Cela laisse Services/Interacteurs - Les fonctions/classes qui fonctionnent réellement. Ce sont faciles - ce sont ceux qui prennent un objet de domaine, exécutent une logique métier et, dans les cas CRUD, appellent le référentiel. Un exemple probablement syntaxiquement incorrect:

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

pour les fonctions de service, je viens d'apprendre aujourd'hui sur Node Machines, et elles semblent être une idée vraiment intelligente: http://node-machine.org

ils semblent être une tentative JS de monades + documentation. donc j'envisage de les écrire comme ça.

de toute façon, étant donné que cela fait un an que vous avez posté, vous êtes probablement passé à autre chose. j'espère que cela vous aide/aide la communauté!

4
MissingHandle

Beaucoup diront que JavaScript n'est PAS bien adapté à la modélisation d'un problème complexe dans un modèle de domaine, puis dans du code. C'est particulièrement le cas si le domaine est dans les affaires, l'industrie et le commerce plutôt que dans l'informatique ou la science des données.

Je ne dis pas que l'on ne peut pas créer un modèle de domaine en JavaScript. Tout comme on pourrait en créer un en C. Mais cela signifie-t-il qu'on devrait?

L'exemple que vous donnez utilise une terminologie dans la conception pilotée par domaine, mais manque tout le but et l'éthique de son application.

0
aryeh