views:

121

answers:

5

For example, we have two domain objects: Cell and Body (as in human cell and body).

The Body class is just a collection of Cells, e.g.

class Body
{
    IList<Cell> cells;
    public void AddCell(Cell c) { ... }
    public void RemoveCell(Cell c) { ... }
}

The Cell has a Split method, which internally creates a clone of itself, e.g.

Class Cell
{
    public Cell Split()
    {
        Cell newCell = new Cell();
        // Copy this cell's properties into the new cell.
        return Cell;
    }
}

Now, in DDD when the cell splits should:

  1. The cell add the newly created cell to the Body (which would mean that each Cell object held a reference to its containing body)?
  2. Or should the service layer which received the intitial user request call Split, collect the returned Cell and add it to the Body? (feels like a more anemic design using controllers rather than domain objects)
  3. Or should the Body contain a SplitCell method?

Thanks in advance.

+1  A: 

In DDD, it often depends on, well, the domain. Here, the example - and thus the domain - seems a bit weird but I think I would go for a SplitCell method on Body.

Although it's not very clear to me what the cell splitting means, and what should trigger this action, I guess the body is responsible for splitting its cells. I would be more comfortable with a Regenerate method, or something like that, on the Body, that splits internal cells by calling the Split method on each ones.

Ok, this example is definitively bizarre...

Romain Verdier
The cell splitting creates an exact copy of the cell with say 1 minor difference. Another actor within the system which is only aware of cells triggers the split. This actor does not really know about the existance of the body.
ng5000
Weird example is easier to explain than the actual domain I'm modelling. I tried to come it with a simple abstract example of the problem I'm dealing with.
ng5000
+2  A: 

I'd think that the Body would simply call the splitCell() on the Cell. Then the Body can do what it wants with the new Cell - add to itself, consume it, throw it away, whatever. The Body contains the Cell anyway.

G Fernandes
+2  A: 

Ok - another approach would be to send out an event to the Body saying "I'm splitting" or whatever. And the Body can then pick up the new Cell - perhaps as a payload of that event.

If your external actor doesn't know about the body, does the Split method need to return a new Cell clone? Is the external actor going to use this somehow? Or can the Split method not return anything (Void) and simply send a message to the Body it lives in?

G Fernandes
+1  A: 

Using events on the Cell class seems like a natural solution, but it's trickier to implement in C#.

You'll need to hook up events when Cells come into scope, and you'll also need to unhook them when they go out of scope - otherwise you'll get memory leaks.

You also need to hook up events whenever a cell is re-associated with a Body, i.e. when cells are retrieved from a persistence store. Using a container to manage the relationships (possibly an ORM interceptor) could make this easier.

The simpler alternative is to hold a reference to the parent Body (cells only belong to a single Body, right?), and let the new Cell add itself to it's Body.

  • Pros: Easy to code, debug, understand.
  • Cons: Cell and Body become tightly coupled, making them trickier to re-use in other contexts (which may be irrelevant)
Vijay Patel
Hi - thanks. I've dealt with event management situations like this before. Not too tricky but always room for error.
ng5000
I'd already decided that the cell would have a link to body (well, to IBody) as an optimisation. I had asked a question in SO about that linkage: http://stackoverflow.com/questions/920158/avoid-circular-reference-in-domain-model
ng5000
A: 

After reading Domain Driven Design (Evans) it would seem that this scenario is best dealt with by using a service.

ng5000