Re: DDD vs canned data model
Rickard Öberg <rickardoberg <at> gmail.com>
2009-01-02 10:19:58 GMT
Peter Morris wrote:
> Hi Rickard
>
> > This looks similar to what you can do with Qi4j today in Java. The above
> > would be as follows in Qi4j:
> > interface PersonEntity
> > extends Customer, Supplier, Nameable, ..., EntityComposite
> > {}
>
> I don't really understand your example
Let me reillustrate what I mean
> and then if it is the same thing maybe a different example from you will
> clear up what you meant?
>
> [aspect:StockHolder]
> public class Person
> {
> }
>
> [aspect:StockHolder]
> public class StoreRoom
> {
> }
>
> I could now write code like this (even within the Person/StoreRoom classes)
>
> StockTransfer st = new StockTransfer(bensonAndHedges20, person1,
> storeroom2,
> 100);
>
> This is because the aspect actually alters the compilers understanding of
> the class during the compilation process, so you can typecast to an aspect
> introduced interface for example without a compiler error, or see aspect
> introduced members (methods / properties / etc) in code-insight.
>
> Although I don't write in Java I'd still be interested in knowing if it
> does
> the same kind of thing, or if it is a post-compile operation (as it is in
> PostSharp).
Right, what we have done is to simply say that ALL functionality in an
object comes from aspects, meaning, in your example Person and StoreRoom
would have no state and no methods. They're only there as something to
put the "aspects" on top of. The assembly of fragments, which we call a
Composite.
The syntax I used is plain Java. Like so:
interface PersonEntity
extends Customer, Supplier, Nameable, ..., EntityComposite
{}
This is just a regular interface, which extends other regular
interfaces. Because of this, if you have a reference to a PersonEntity
you can in your IDE do code completion on all the methods that are
included as "aspects". This not only gives you typesafety, but also IDE
convenience.
The "magic" in Qi4j comes when those regular interfaces (which you would
NEVER implement using just plain Java, because typically you would have
10-15 interfaces as "aspects" and you would then have to implement all
of them in ONE class) are to be mapped to implementation methods. You
then write a mixin with the actual implementation. Like so:
interface Nameable
{
String getName();
void setName(String name);
}
is the "aspect", and then the implementation is:
public class NameableMixin implements Nameable
{
String name;
String getName() { return name; }
void setName(String name) { this.name = name; }
}
which is matched to the interface through an annotation on the PersonEntity:
@Mixins({NameableMixin.class,...})
interface PersonEntity
extends Nameable, ...
{}
The ability to instantiate the "huge" interface PersonEntity with a
proxy that delegates to NameableMixin on calls to Nameable is the basis
for Qi4j (and then a whole lot more). This allows for the creation of
"nice to have" aspects, as you said, and then put them together using
the "super interfaces" (or Composite declarations as we call them). I
have built a large commercial CMS/portal product using this technique,
and it is very nice IMO.
I hope this makes it clear!
/Rickard
------------------------------------