Pergunta

I am working on a project using DDD, I have some classes and I don't know where to put them.

The domain is about an existing game. This game has basic concepts, like Character, SkillTree. My domain class simply represent those concepts. I did not make this game.

My application/project is about having a software that represents those concepts, with some added values. At the moment, a name, and a description are the only possible added values (example, "Fire mage", and "Mana dependant, be careful !").

Question 1 : does it make sense to have two classes, or should I merge them ? In the former case, where should I put this class "with added value (name and description)" ? In the application layer ?

Question 2 : Am I right in saying that the domain layer represents the sphere of knowledge I am working on, and application layer represents all the things that do not exist in the domain, but I want to provide, as added value ?

(therefore, if my software simply represents the domain, the application layer is thin, and if my software provide a lot of non domain functionalities, the application layer is thick ?)

Additonal informations 1 : my project is about creating a character simulator. Therefore, in order to simulate a character, I have to represent it, as well as all of its dependencies. My domain layer responsability is to represent the game. It contains classes like Character, with some properties (Life, Mana, Attack, Defense, Class), and some enum (like CharacterClass, which lists all the available classes).

Now, I want my own project to provide, to the user, the ability to create a project, that represent a character of the game. The project also allows the user to save additional informations, like a name for the current project, a main (and secondaries) equipment set, a main (and secondaries) skilltree. Annotations are also available for any of the equipment set and skill trees, so the user can simply have a built-in memo/post-it. Secondaries equipment set and skill tree, annotations are not existing concepts in the game (and therefore, do not exist in my domain).

In question 1, the "class with added value" is a character project, that is an aggregate of multiple informations (character equipments, skill tree, annotations, etc). It can be saved on a physical support, opened and edited again later, if the user wants it.

Reformulation of question 1 : I have a Character class, and a CharacterProject class. The CharacterProject class is a composition of multiple informations. But it is specific to my application. Does it make sense to put it in the application layer, or the domain layer, or somewhere else ?

Foi útil?

Solução

For you first question, I want to comment and help you with some humble design guidance. Humble meaning believe it at your own risk :D.

While designing classes for any layer or any type of software I usually approach it with generalization love (abstraction/interface contracting etc), You mentioned you have name and description which are 'values' that are going to be added to your domain models core object such as 'SkillTree' or 'Character', Ask yourself if you can generalize name and description classes as for example IAdditiveInformation interface. If most of what these two classes will do can be shared/contracted under IAdditiveInfromation generalization then you know that this is also in your domain core. If you use this interface in core of your domain model and point all dependencies towards this interface you wont have to answer hard and speculative design questions such as

  • Will I be adding more 'value' classes?
  • Will there be more 'GamePart' classes?
  • How can I design my 'value' and 'GamePart' classes so that I can implement their interaction with minimum effort.

For deciding classes to put at Domain model, Domain service or Application Layer and beyond. I use these as guidelines.

  • If a class is directly related to what your software is on like in a way that a account software is related to invoices, inseparable and crippled without it, then that class is in your domain model layer and at the core of the onion.
  • If a class operate on objects at your core and only on your domain core and they are reusable whenever you use a domain core like the current core. Then they are your domain services.
  • If a class operates on your domain services and/or your domain core and it feels a little bit more specialized for that application. Then it probably belongs into application layer. For something to be in application layer remember that this functionality should be critical for that particular application on domain and not for whole the domain. So you only need this functionality for that application.

Let me give you an example to make it a little easier to understand.

Imagine a gps based tracking system.

  • At it's core there is a class called GPSTrackable (an abstract class hopefully).
  • At the domain service level there is a class which operates/depends on GPSTrackable which is a geo location based query control where you give a GPS box and it returns you GPS trackables in that box. Lets call this class GPSTrackableQuery

Time to see magic of onion/DDD and correct OOD :). I have not told you what the application is and I have not even decided on the application yet. I don't have decide to capture core domain and domain services because they should be application independent(in an idealized architecture way).

Now with these at our onion core,

  • I can make a class in application layer, that calls to GPSTrackableQuery every 10 seconds and checks if there are any object in close proximity to a military base for a security system and you get a location based security system if you run that core at everyone’s phone.
  • I can make a class in application layer, that calls to GPSTrackableQuery when user wants to send mass SMS or e-mails to people near his store. Now I made a advertisement system from the same domain core.

You can add new examples to this. This is a simple thing, I imagine when I doubt my decisions.

One last note: You should also understand that placement of classes in layers have no meaning. We just put them in 'virtual' layers to have a feeling of their responsibilities and functional scope. If in too much doubt just put it somewhere, when you architecture or design or implementation evolves you will feel it's correct placement.

For your second question.

In my opinion, your suggestion is correct. Only thing I can comment is I would not use the term sphere of knowledge for the domain layer(I assume you mean both domain core and domain services). I view domain core as a representation of real world knowledge in computer terms or core idea's behind it.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top