Hi Rickard,

Thank you very much for your thorough answer and reflections on the subject!!!

It has helped me a lot, and I will look carefully into the Streamflow code as you suggest. That will take me a while ;) and I will probably get back with some more questions once I start to understand the implementations. I think I will also then better be able to reflect on your examples and explanations. A lot of good stuff to digest!

Thank you for confirming my suspicions about the POJO -> Qi4j paradigm shift. I'm definitely on the right bandwagon ;)

Keep up the excellent work - very much appreciated!

Cheers,
Marc

On 08/03/2010, at 08.17, Rickard Öberg wrote:

Hi Marc,

On 2010-03-07 23.19, Marc Grue wrote:
Qi4j beautifully makes it possible to separate state and behaviour.
And even generic behavior like an Assignable; "assign GenericA to
GenericB" (as shown in Rickards excellent presentation
http://oredev.org/prod/oredev/site.nsf/docsbycodename/session?opendocument&sid=88EF79931A074A1AC125759A003AB0ED&track=24116556E47101EAC12575A50049A141&day=5) .

Doesn't this rock the DDD boat some (in a great way!) in the sense
that the "classical" BC/Module/AR/Entity boundaries would have the
behavior dimension extracted into "Cross cutting (domain?)
behavior"?!

I'm happy that you have noticed this. As you note, the DDD mailing list are quite a lot "stuck" in the POJO world, where everything is difficult. Since we don't have that limitation we focus on more interesting things, and creating cross-cutting domains in one such thing.

I have found that what is traditionally thought of as "Bounded Context" can usually coexist in entities quite happily, since the code is not mangled together. As long as the entity identities have the same structure, it works quite well.

As for aggregates, I'm more and more thinking that such rules can actually quite well be handled by DCI. Since an interaction has access to a number of entities at once, through a context map, it becomes trivial to handle many aggregate rules without having to create a new method for it.

Let's say that you, for example, have an Order with Lineitems. In a traditional aggregate implementation, when the Lineitem quantity changes that would have to be a method on Order, since the total price has to be recalculated: order.changeQuantity(lineItem,newQuantity). But this leads to a lot of duplication of methods.

With DCI, where each method in a context represents a usecase interaction, this can be captured differently:
public class LineitemContext
 extends Context
{
 public void changeQuantity(int newQuantity)
 {
   context.role(Lineitem.class).changeQuantity(newQuantity);
   context.role(Order.class).calculateTotal();
 }
}
---
This quite simply captures the "algorithm" that happens when a lineitem quantity is updated, and also handles the aggregate rule from Order to Lineitem. I think this is better than to put the changeQuantity(LineItem,int) method into the Order interface.

When it comes to entity structure, that's another interesting part. Due to how you can structure mixin dependencies, and use private mixins to specify what is your public API from an entity, I have found that entities typically have 5 internal layers: data, structural roles, interaction roles, query roles, and glue roles. It is layered in the same sense as in layered archiectures, i.e. query roles may refer to interaction roles, but not the other way round.

So there's a whole lot of interesting things that become possible, and the code (especially when DCI is used for the application layer) is just super-pretty. :-)

I'm trying to dive into the new paradigm and to practically organize
my folder/package structure accordingly. I have read heated
discussions about bounded contexts etc in the DDD Yahoo group, and I
wonder if/how you qi4j folks are physically/conceptually organizing
the behavioral part (used across domain contexts) in larger
applications (with several BC's)? Or, simply put: where does generic
behavior belong?

Please look at the StreamFlow code for one extensive example of this. In short, I have the following package structure:
/domain
 /entity
/<domain-package> : contains EntityComposite interfaces, query mixins, and glue mixins
 /interaction
/<domain-package> : contains mixins for a specific interaction context (like /gtd in my case), including data mixins
 /structure
/<domain-package> : contains structural mixins for a specific context (like users, organization, projects and tasks in my case), including data mixins

If you do this, then it becomes really easy to verify if you are following the dependency rules, by using Structure101. Entity should depend on interaction and structure. Preferably interaction and structure should not depend on each other, so that they can be used and composed independently.

What differences are there in organizing a project namespace in DCI
and in DDD (if you can put them up against each other). Any directory
structure examples would be much appreciated.

The way I use DCI is for creating a REST API. The REST API then matches the UI layout. My client has a "workspace" so I have a / workspace REST URI, which then maps to a .workspace package. Very straightforward. The goal is to have the users mental model map directly to the code.

Note that this is VERY different from many other REST approach where the domain model is exposed directly as URL's (which I think is basically nuts). When you do the above, it really enforces that API means Application Programmer Interface, whereas the typical "expose your domain using URL's" is a DPI: Domain Programmer Interface. Which, to me, is the wrong level to expose.

I was originally planning to post this in the Yahoo DDD group, but I
find that they are a little slow to pick up on the powers of qi4j :)
so I imagined the subject would fit better here...

Probably a good call...

/Rickard

_______________________________________________
qi4j-dev mailing list
[email protected]
http://lists.ops4j.org/mailman/listinfo/qi4j-dev


_______________________________________________
qi4j-dev mailing list
[email protected]
http://lists.ops4j.org/mailman/listinfo/qi4j-dev

Reply via email to