Skip to search.

Breaking News Visit Yahoo! News for the latest.

×Close this window

domaindrivendesign · Domain-Driven Design

The Yahoo! Groups Product Blog

Check it out!

Group Information

  • Members: 4082
  • Category: Software
  • Founded: Sep 27, 2002
  • Language: English
? Already a member? Sign in to Yahoo!

Yahoo! Groups Tips

Did you know...
Hear how Yahoo! Groups has changed the lives of others. Take me there.

Messages

Advanced
Messages Help
Messages 5232 - 5264 of 24152   Oldest  |  < Older  |  Newer >  |  Newest
Messages: Show Message Summaries Sort by Date ^  
#5232 From: "colin.jack" <colin.jack@...>
Date: Wed Apr 11, 2007 1:09 pm
Subject: Re: When aggregates become too heavy.
colin.jack
Send Email Send Email
 
This is certainly useful advice but I think its the sort of
issue that would really benefit from an example.

In general I think it would be worth another book being read that
builds on DDD, possibly with more examples and an emphasis on
tackling thorny implementation issues head on.

I was thus wondering if you had any plans to write a follow up work?



--- In domaindrivendesign@yahoogroups.com, "Eric Evans" <eric@...>
wrote:
>
> This is really the point of the aggregate pattern. Systems don't
work
> well with those megalithic models. When your model seems to demand a
> single huge aggregate, it is a sign you need to look for another
model.
>
> Think about what invariants you are applying. Do they really span
all
> those objects? Or are there tighter knots of objects that should be
> the aggregates. Perhaps some of the rules you are enforcing could be
> dealt with asynchronously, and don't require both sides to be in the
> same aggregate.
>
> But usually, in this situation, you have to change the objects
> themselves. You've chosen a model that puts a single object at the
> middle of everything. But there are other ways of looking at the
> problem. Some of them distribute responsibility.
>
> One other point. Don't be too concerned about duplicating data, if
the
> rules of the duplication are very clear. For example, in an
accounting
> app, you might enter a credit in one ledger and a debit in another.
> This allows us to look at either ledger independently during most
> other operations. If you were to "normalize" this, and store the
> credit/debit transaction in only one place, then that superledger
> would tie together all the other ledgers.
>
>
>
> --- In domaindrivendesign@yahoogroups.com, "Dru Sellers" <dru@>
wrote:
> >
> > I have this exact same problem but hadn't put words to it. The
greedy
> > aggregate is indeed something that feels bad, but is it? I look
> forward to
> > the comments from everyone on this. -d
> >
> > On 4/10/07, jupitermoon_beam <jupitermoonbeam@> wrote:
> > >
> > >   Although in the DDD book there are many concpets about
modularizing
> > > the domain itself I am often faced with tackling heavy entities.
> > >
> > > In many domains there is a single core aggregate (much of the
time
> > > Customer) and a large amount of the logic and concepts in the
domain
> > > hang off of this one aggregate. The result is a rather heavy
> > > aggregate which contains a lot of concepts.
> > >
> > > Because the aggregate owns a lot of the domains concepts it is
really
> > > difficult to split it. A lot of the concepts exist outside of
the
> > > core domain but the domain naturally centralizes itself around
this
> > > one object.
> > >
> > > Sometimes I find I can splinter the logic off into services or
turn
> > > simple lists (such as contact histories etc.) into aggregrates
and
> > > give them their own repositories but sometimes there can be a
lot of
> > > domain logic that the central aggregate naturally owns.
> > >
> > > How do people deal with these heavy aggregates? What tricks can
be
> > > used to break our greedy aggregates down into smaller managebal
> entities?
> > >
> > >
> > >
> >
> >
> >
> > --
> > cheers,
> > -d
> >
>

#5233 From: "Joe A. Reddy" <jreddy@...>
Date: Wed Apr 11, 2007 2:15 pm
Subject: RE: Is categorization into entity/value meaningful ? (the real thread subject AFAIU)
joethebigshmoe
Send Email Send Email
 
tomtdd,
 
You are right, I asked if anyone was using naming conventions to differentiate between an entity and value object.
After a little discussion it seemed agreed that there is no benefit to doing so.
End of story.
You misunderstood me if you thought I was arguing "for" it in the first place, I was simply asking a question.
 
As far as immutable objects go, in our little world all our objects are immutable except for what we call candidate objects. Candidate objects are clearly denoted so you know when you are dealing with one. So I agree with you that it is good to know that an object is immutable.
 
Cheers,
Joe
 
-----Original Message-----
From: domaindrivendesign@yahoogroups.com [mailto:domaindrivendesign@yahoogroups.com] On Behalf Of tomtdd
Sent: Tuesday, April 10, 2007 6:44 PM
To: domaindrivendesign@yahoogroups.com
Subject: [domaindrivendesign] Is categorization into entity/value meaningful ? (the real thread subject AFAIU)

--- In domaindrivendesign@yahoogroups.com, "Joe A. Reddy" <jreddy@...>
wrote:

>"there is no need to know when working
>with a class whether or not it is an
>entity class or a value class."

I think your discusion is confusing, since in your first post you were
wondering whether anyone use naming conventions to differentiate
between an entity object and a value object, but now it seems to me
that you claim there is not even any need to know if an object is an
entity or value (and I am tempted to agree with the latter).

So, is it correctly understood that you are skeptic to the concept of
labeling an object as a value object or as an entity object ?
If you actually do think it is meaningful to categorize objects as
entity or value objects, then can you provide an explanation of why
you think such a categorization is meaningful (without contradicting
your own words "no need to know") ?

I myself am not very convinced about the general usefulness about
categorizing objects into entity and value objects.
On the other hand, I do indeed think that the mutability information
is relevant, since if I know it is immutable I know it is safe to share.
However, I think it would also usually be safe to share an immutable
entity object or unsafe to share a mutable value object, even though
these cases are probably a lot less common than immutable value objects.

If I actually would think it is meaningful to know if an object is an
entity or value object, then I can imagine some possible ways to
define these things:
(1) Only define it in my brain (i.e. remember/think about whether an
object is entity or value)
(2) Write a source code comment that defines whether a class is entity
or value.
(3) Use metadata information (such as C# attributes or Java
annotations) to label a class as entity or value.
(4) Use some kind of prefix/suffix or other naming convention to label
the class as entity or value.
(4) Use some kind of prefix/suffix or other naming convention to label
the objects as entities or values.

I would probably like to choose option 3 above for labeling an object
as an "Immutable value object", or in fact, until I have realized the
actual usefulness of the "Value object" information I would probably
be tempted to drop the value object information and only keep the word
"Immutable" as the metadata information which I think can be useful.
By using metadata (instead of e.g. simple source code comments) I
might use it to get the chance to detect/enforce that an object
labeled as immutable are not actually changing anything.

Regarding the difference between entity and value objects, I think
that the difference can not always be clear. Generally speaking, I
would like to think about it in terms of how I would implement the
Equals method. With an entity object, I would implement it by
comparing some kind of identity value, such as an autogenerated (e.g.
from the database) identity number, or maybe some more natural
identity value such as a social security number for a person class.
On the other hand, if I would consider a person class as a value
object, then I would implement the Equals method by trying to compare
a bunch of attribute values (such as birthday, name, address, phone
number and so on).
Naturally, it would be preferable to use a simple identity than trying
to match a big bunch of attributes, but in some applications you might
want to pull out person instances from different systems, and there
might not be a natural common identity between all systems.

For example, maybe you need to compare two person objects (to
determine if it is the same person) coming from different systems,
where the person objects originate from different databases with
different autogenerated ID's and they do not all have a common SSN
neither (some countries maybe do not). Therefore I might be forced to
consider a person object as being more similar to a definition of a
value object, i.e. I would try to compare a big bunch of attributes to
determine if two persons from different computer systems are actually
equal.

My question here is: Would it actually be meaningful to label my
person class as being more similar to some common
description/definition of a typical entity object rather than labeling
my person class as being more similar to a typical value object ???
If the answer is yes (which I assume it will be from most people here)
then can you please explain why/when these words "Entity" and "Value"
will be relevant to see (in metadata or in code comment or in naming
convention...) ?

Regarding my above phrase "being more similar to some common
description/definition of a typical entity object", I wrote that
phrase because I do not think the difference between identity and
attribute are always obvious.
(at least not if an identity is allowed to be a compound value)
For example, consider a Person class which include the following data:
class Person
{
// six immutable (compound key fields) fields:
string name;
string country;
string city;
string streetaddress;
DateTime birthDate;
DateTime theDateWhenAllTheAboveAttributesWereStored;

// some mutable fields:
string currentName;
string currentCountry;

// ...
public bool Equals(...)
{
// compare the six immutable fields above
}
}

Some people might say that the above class is a value object since the
equals method compares a bunch of attributes (i.e. it does not compare
two instances through one simple identity value), though I would
rather agree with someone who says it is not an entity object since
the six fields are not unique enough, i.e. there is a possibility that
at a certain point in time there were indeed two persons with the same
name and address and the same birthdate.
However, that could simply be a matter of adding some more attributes
until you indeed can consider the combination of attributes as being
unique enough to be an identity combination.
(such additional attributes could be the name of the father and mother
and their respective birthdates and their addresses which they had at
a certain point in time).

This became a long post, so I will now finish by trying to repeat my
actual questions:
(1) Why is it meaningful to label an object as Value or Entity ???
(and please note: I do indeed understand the meaning of labeling an
object as immutable, since it is useful to know that an object can be
shared without problems)
(2) How do you, in practise, label an object as Value or Entity ???
(and if you do use metadata for labeling a class as immutable, do you
know of any Java Annotations and/or C# attributes which can be used
for validating that no attribute of an immutable labeled object is
mutated, and also that none of the attributes in the the aggregated,
nested attributes are mutated?)
(3) Can someone provide a good definition of identity (as in entities)
and attributes (as in value objects) to make it easier to realize
whether an object should be considered as a value object or entity ???
(as I was trying to explain above, I think a unique identity can
usually be constructed by combining attributes, in particular if you
choose to include a timestamp attribute for when those other attribute
values were measured/stored to uniquely define the identity)


#5234 From: "Joe A. Reddy" <jreddy@...>
Date: Wed Apr 11, 2007 2:18 pm
Subject: RE: Naming Conventions - nice lightweight question
joethebigshmoe
Send Email Send Email
 
Interesting, thanks.
 
-----Original Message-----
From: domaindrivendesign@yahoogroups.com [mailto:domaindrivendesign@yahoogroups.com] On Behalf Of Bil Simser
Sent: Tuesday, April 10, 2007 11:13 PM
To: domaindrivendesign@yahoogroups.com
Subject: RE: [domaindrivendesign] Naming Conventions - nice lightweight question

I saw tomtdd’s long post but figured I would chime in with my simple approach (as I don’t want to get into the debate of why).

Originally I was doing something like this:

Class Person;

Class AddressVO;

I knew exactly that address (which might be a variable inside of Person) is a value object so I should treat it as such.

However a few things happened over the last couple of sprints:

1.       A few value objects started getting “smarts” and morphed or moved into the domain and grew up to become entities. I think this is a valid evolution.

2.       The fact we had a bunch of classes named xxxxVO didn’t really have any value when looking at the model

So today we just call them by a descriptive name (Address rather than AddressVO) and they live in a ValueObjects namespace/folder in the system. If they move, we’ll move them and move the namespace (gotta love ReSharper!).

From: domaindrivendesign@yahoogroups.com [mailto:domaindrivendesign@yahoogroups.com] On Behalf Of joethebigshmoe
Sent: Tuesday, April 10, 2007 12:43 PM
To: domaindrivendesign@yahoogroups.com
Subject: [domaindrivendesign] Naming Conventions - nice lightweight question

Anyone use naming conventions to differentiate between an entity object
and a value object?

So instead of CUser and CUserStatus I might have eUser vUserStatus or
something similar.

If you are doing it, can you tell me the perceived benefits?
If not, but thought about it, can you explain why you decided against
it.

Thanks,

Joe


#5235 From: "jupitermoon_beam" <jupitermoonbeam@...>
Date: Wed Apr 11, 2007 4:00 pm
Subject: Re: When aggregates become too heavy.
jupitermoon_...
Send Email Send Email
 
Maybe a specific example may help and then people could give specific
answers to the problem.

I will draw a domain around the traditional Customers and Orders scenario.

In this web based business ordering system we have a central
Customer.  The Customer has the following concepts: Orders, Accounts,
Buyers and Payment Methods.

Each of those concepts have specific rules specific rules around the
Customer:
* The number of payment methods (i.e. a credit card) allowed on a
customer is directly related to the number of accounts a customer has.
* A payment method can pay money off any account the customer has.
* A payment method can only belong to one Customer.
* The number of Accounts a Customer can have depends on the type of
Customer.
* An order can only be placed on a Customer if all the accounts are in
good order.
* Approved buyers can be enabled/disabled on a customer.
* Buyers cannot belong to more than x number of customers (for
security reasons).

This is actually a simplification of the real domain I am talking
about becoming heavy (there are even more concepts such as contact
histories etc.).

The issue is a lot of this logic requires that the Customer aggregate
executes some business logic whether it is Customer.AddOrder to
Customer.AddBuyer to Customer.AddPaymentMethod.  The core domain is
about placing orders not about making payments (that's a sub module)
or managing buyers (again a sub module).  But because there are rules
specific to the Customer the Customer needs to know about them.

For example I tried to seperate out Payment Methods but the logic to
register a payment method is something like:
if(this.PaymentMethods.Count < this.MaxNumberOfPaymentMethodsAllowed)
{
  PaymentMethods.Add(PaymentMethod);
}

I can't think of a way of ripping that out of the Customer wihtout
making it a service which seems silly because it works well in an
aggregate it's just the aggregate is getting too heavy.

I eagerly await feedback.

--- In domaindrivendesign@yahoogroups.com, "colin.jack"
<colin.jack@...> wrote:
>
> That might be one way to split it, I definitely would try to keep my
> Customer lightweight but I'm not sure if moving Orders off is the
> correct way to do that. Surely the most important thing about a
> Customer is that they make Orders? Thats what differentiates them
> from any other person that the model deals with (if the model deals
> with other people).
>
> I'd maybe consider breaking it a different way. For example if you
> have a lot of personal information on Client then move that into
> another hierarchy (Party) and have the Customer be a role that a
> Party can be in (see Arlow for examples of this).
>
> In any case though if you do move the rules into CustomerOrders then
> surely Customer can still reference CustomerOrders, thats just one
> aggregate root referencing another. I certainly wouldn't keep Order
> specific rules in Customer but I also wouldn't decouple Customer and
> Order unless I had other reasons for doing it, especially if most
> users of the Customer class are going to be accessing the Orders
> collection.
>
> Thats my 2cents anyway.
>
> --- In domaindrivendesign@yahoogroups.com, "jupitermoon_beam"
> <jupitermoonbeam@> wrote:
> >
> > I think Patrick's post is where my thinking was going (I will try
> and
> > confirm if I've got it right).
> >
> > It was the subject of Eric's post that was starting to concern me
> > about these Greedy Aggregates.  To take Eric's and Bert's posts are
> we
> > saying the the greedy aggregate
> > has concepts in it that can be split into more specific sub
> aggregates
> > (like the facets)?  In effect the aggregate needs to be inverted.
> >
> > For example rather than having a Customer holding all the rules for
> > managing Orders on itself have a CustomerOrders aggregate which
> deals
> > with the Customer as an entity (using Partick's example the Customer
> > becomes the key to retrieving the CustomerOrders aggregate).  Then
> to
> > deal with a customer's orders you can deal with the CustomerOrders
> > aggregate directly without having to deal with the rest of the
> > Customer.  It also means that the Customer can become modularised.
> >
> > Does this risk making the Customer aneamic? I guess if the focus of
> > the surgery is around preserving the core domain then the risk
> should
> > be contained.
> >
> > Also I've often found that we miss concepts in modelling that hide
> > within the Ubiqutous Language and need pulling out (Eric's book is
> > littered with examples).  For example in a system that tracks Car's
> > and their Owners (such as the British Road Tax system) people often
> > link Car directly to Owner but there is a concept of registration
> > whereby the Owner registers the Car with the system.  This
> > Registration often has it's own rules and data which live outside
> both
> > the Car and Owner and you often see people struggling with the model
> > because they haven't stumbled across the word "register" in the
> > language.  Basically maybe a lot of these concepts are 'hidden' even
> > further (such as CustomerOrders).
> >
> > Am I going in the right direction here?
> >
> > --- In domaindrivendesign@yahoogroups.com, Patrick Bohan
> > <patbohan@> wrote:
> > >
> > > I've dealt with what sounds like a similar problem.
> > >
> > > At a previous job we had an application that performed various
> types of
> > > batch processing on a very large components. By large I mean both
> > memory
> > > intensive (usually between 10 and 200 Mbs) and conceptually large
> (lots
> > > of little and not-so-little pieces.) The components were all
> related
> > but
> > > when and where we needed different parts was not common. (In one
> > area of
> > > the system we needed parts A and B, in another B and C, and a
> third A,
> > > B, and C).
> > >
> > > To manage this we did not create one monster object, we created a
> tiny
> > > core token object that contained the bare necessities and a suite
> of
> > > objects to cover of the other major parts. (We dubbed these other
> parts
> > > "facets", as in the facets or sides of a jewel. All the facets
> together
> > > make the complete jewel, but most of the time you are only
> looking at
> > > the few that you can see.)
> > >
> > > In practice what we always had a reference to the core object. It
> > was an
> > > immutable light weight object that everything in the system
> recognized.
> > > (For us it was limited to an ID number, type, and description.)
> The
> > core
> > > object by itself was useless except in one regard: we could use
> it to
> > > get the other, useful parts. We would supply the particular
> Repository
> > > that housed the type of parts we cared about this core object,
> and we'd
> > > get our part.
> > >
> > > We never created a direct reference from the core object to any
> of the
> > > parts. We deferred that activity to the areas that needed the
> parts. If
> > > an area needed a container class to hold the core object and
> several
> > > parts they would build one as needed.
> > >
> > > I don't know the domain of your problem, but we were only able to
> (and
> > > required to) achieve this splitting due to the nature of our
> > problem: we
> > > often only needed only one or two parts and we never needed all
> the
> > parts.
> > >
> > > Patrick
> > > ARKBAN
> > >
> > > Dru Sellers wrote:
> > > > I have this exact same problem but hadn't put words to it. The
> greedy
> > > > aggregate is indeed something that feels bad, but is it? I look
> > forward
> > > > to the comments from everyone on this. -d
> > > >
> > > > On 4/10/07, *jupitermoon_beam* <jupitermoonbeam@
> > > > <mailto:jupitermoonbeam@>> wrote:
> > > >
> > > >     Although in the DDD book there are many concpets about
> > modularizing
> > > >     the domain itself I am often faced with tackling heavy
> entities.
> > > >
> > > >     In many domains there is a single core aggregate (much of
> the time
> > > >     Customer) and a large amount of the logic and concepts in
> the
> > domain
> > > >     hang off of this one aggregate. The result is a rather heavy
> > > >     aggregate which contains a lot of concepts.
> > > >
> > > >     Because the aggregate owns a lot of the domains concepts it
> is
> > really
> > > >     difficult to split it. A lot of the concepts exist outside
> of the
> > > >     core domain but the domain naturally centralizes itself
> around
> > this
> > > >     one object.
> > > >
> > > >     Sometimes I find I can splinter the logic off into services
> or
> > turn
> > > >     simple lists (such as contact histories etc.) into
> aggregrates and
> > > >     give them their own repositories but sometimes there can be
> a
> > lot of
> > > >     domain logic that the central aggregate naturally owns.
> > > >
> > > >     How do people deal with these heavy aggregates? What tricks
> can be
> > > >     used to break our greedy aggregates down into smaller
> managebal
> > > >     entities?
> > > >
> > > >
> > > >
> > > >
> > > > --
> > > > cheers,
> > > > -d
> > >
> >
>

#5236 From: "trondeirikkolloen" <trond-eirik@...>
Date: Wed Apr 11, 2007 4:13 pm
Subject: Re: Defining aggrage roots (and transitions between them)
trondeirikko...
Send Email Send Email
 
Hi Pascal

Thanks a lot for your respons.

I see that my example

"myProject.Activity[0].Peformers[0].Person.Name += "(a project
member)";".

was not very good.

Name was ment to be a string, and the meaning with Name += was just
to illustrate that you changed something on the person. In this case
the persons name.

I see your point of repositories, and I think I agree. But at the
same time it all depends on how many aggragates you have and how
corse grained your aggreates are.

The post "When aggregates become too heavy." seems to regard the
exact same issues that I'm wondering about, just much more on the
issue!

TEK


--- In domaindrivendesign@yahoogroups.com, "Pascal Lindelauf"
<pascal@...> wrote:
>
> Hi Trond-Eirik,
>
> Interesting topic. Well, from my point of view I lean far more
towards
> having a repository per aggregate root. One per application will
simply
> become far too large too soon. From a client's perspective, this
doesn't
> seem too ackward either... remember that in the ol' 2-tier days a
client
> application had to be aware of each and every table in the
database. A
> repository per aggregate root is then already step up.
>
> For large applications, though, I like to take it another step up
and
> use modules to partition my domain model, where a module contains
> multiple aggregate roots. You can then choose to have a repository
per
> module. This might work well for you.
>
> As  for your question with regards to if it's okay to write
> "myProject.Activity[0].Peformers[0].Person.Name += "(a project
> member)";". Let's start by saying that this code kind of smells. So
this
> will make me look more closer at what's going on here and in this
case,
> I would say: you wouldn't want to modify a person's name from the
> project he's a member of, especially if he's an aggregate root and
> entity object of his own. It almost seems in this example like
you're
> aiming at creating and adding new person instances to
the "Performers
> collection" (using the "+=" operator). If that's the case, then the
> Person is actually a value object (quite the opposite of an
aggregate
> root, entity object).
>
> But let's imagine you need to know a person's age on project level;
in
> that case I guess there's nothing wrong with directly accessing
> "myProject.Activity[0].Peformers[0].Age".
>
> Furthermore, with regards to your question about how to determine
what
> is an aggregate root... I don't really have a set rule, but I
remember
> that John Daniels & John Cheesman wrote the following about this in
> their book UML Components. (note that they use the term "core type"
for
> an "aggregate root"):
> A core business type is a business type that has independent
existence
> within the business, characterized by the following:
> • A business identifier, usually independent of other identifiers
> • Independent existence—no mandatory associations, except to a
> categorizing type
> The second point needs a little explanation. A categorizing type is
one
> whose instances categorize or classify the instances of another
type.
> This is not an aggregation or composition association, simply a
> classifying one. For example, Room has a mandatory association with
> RoomType, but RoomType is a categorizing type for Room, so Room
could
> still be a core type. We do not make Room a core type, however,
since it
> also has a mandatory association with Hotel.
> Hope this helps.
>
> Pascal.
>
> --- In domaindrivendesign@yahoogroups.com, "trondeirikkolloen"
> <trond-eirik@> wrote:
> >
> > There is a lot of discussion about different technics to use in
DDD,
> > and many of them have some focus on the aggregation root when
> > peforming stuff.
> >
> > The aggregation root is for example by some referred to as a
place to:
> > - use as a root for rule validation
> > - create a repository for returning entities
> >
> > Is there any good references of HOW to locate good candiates for
> > aggregation roots?
> > Another issue is transition between aggregate roots.
> > Should you be able or allowed to transit from one aggregate into a
> > completly different aggregate from deep within the sub-level of a
> > aggregate?
> >
> > Any recommended readings or papers on the issue would be
appriciated.
> >
> > Example:
> > A project has many project members.
> > A project has many (several thousand) activities.
> > Activities is peformed by project members
> > A project member is a person.
> > A person may be a member of several projects.
> >
> > In my mind a possible/wanted model for this would be:
> > (to avoid some issues, lets say that you will always be working
with
> > all data in memory)
> > Adding and removing of entities/values is done by calling
Add/Remove
> > on the given collection types.
> >
> > [Repository]
> > class ProjectRepository{
> >   Project GetProjectByNumber(int number);
> >   ProjectCollection Projects{get;}
> > }
> > [Repository]
> > class PersonRepository{
> >   PersonCollection Persons{get;}
> >   Person[] GetPersonsByName(string name);
> >   Person GetPersonById(int id);
> > }
> >
> > [AggregationRoot]
> > class Project{
> >   ActityCollection Activities{get;}
> >   ProjectMemberCollection ProjectMembers{get;}
> >   ProjectMember GetProjectMemberByName(string name);
> >   Activity[] GetActivitiesForProjectMember(ProjectMember);
> > }
> >
> > [Entity]
> > class Activity{
> >   Project Project{get;}
> >   Activity Parent{get;set;}
> >   ActivityCollection ChildActivities{get;}
> >   ProjectMemberCollection Peformers{get;}
> > }
> >
> > [Value]
> > class ProjectMember{
> >   Person Person{get;}
> >   string ProjectRole{get;}
> >   Project Project{get;}
> > }
> >
> > [AggregationRoot]
> > class Person{
> >   int Id;
> >   string Name
> > }
> >
> > Some toughts about this:
> >
> > As you see here there are two aggregation roots and two
repositories.
> > One aggregation root is project and one is Person.
> >
> > Project is a huge aggregation root with A LOT of data.
> > Is this a good design?
> >
> > The other issue is with the ProjectMember class where you have a
link
> > between data in two different aggregates, Project and Person.
> > Is it resonable that you should be allowed to write code like
this?
> > myProject.Activity[0].Peformes[0].Person.Name += "(a project
member)";
> >
> > For a user of the domain model, this will mean that he will be
> > crossing over between different aggregates without even beeing
aware
> > of it.
> > Is that OK?
> >
> > A short comment regarding the use of repositories vs. not using
> > repositories:
> > I'm in strong belive that a repository makes it very mutch easier
for
> > the user of the domain model to find his starting point and locate
> > the important aggregates root/starting objects than using for
example
> > static methods on objects.
> > If it's a good idea to have one repository pr. aggregate type is
> > something I'm a lot more unsecure of.
> >
> > For example, instead of two repositories above I could have done
> > something like this:
> > ApplicationRepository{
> >   Project GetProjectByNumber(int number);
> >   ProjectCollection Projects{get;}
> >   PersonCollection Persons{get;}
> >   Person[] GetPersonsByName(string name);
> >   Person GetPersonById(int id);
> > }
> >
> > Sure, the repository would be large for a large system, but for
the
> > user it would be very easy to find all aggregate roots as there
would
> > be one single entry point for all the data.
> > And in huge system this would problably not scale good enough,
still
> > you could problably have done with 5 repository instead of 100.
> >
> > I guess this would be more clear to me when I get a better
> > understanding on how to locate the aggregation roots.
> >
> > If anyone is still with me ;-)
> > Best regards, Trond-Eirik
> >
>

#5237 From: cbeams <cbeams@...>
Date: Wed Apr 11, 2007 4:41 pm
Subject: DDD Annotations (was: Re: Naming Conventions - nice lightweight question)
cbeams78
Send Email Send Email
 
I'm using a simple set of DDD annotations that could be thought of as analogous to 'marker' interfaces:

@AggregateRoot
@Repository
@Entity
@ValueObject
@Factory
@Service

The primary intention of these annotations is not one of tooling or validation (thought that's conceivable), but rather as a lightweight communication mechanism for developers.  Given that a team has a working context for DDD, it's of value to be able to browse through the code and immediately see the intent of any particular model object.  I've packaged these within our codebase as 'org.domaindrivendesign.*' for additional clarity, and each annotation's respective JavaDoc has @see references to the pages in the book that describe/distinguish that type of model object. 

Interestingly, Spring 2.0 introduced a package 'org.springframework.sterotype', which has a single annotation at this point: '@Repository' (http://www.springframework.org/docs/api/org/springframework/stereotype/package-summary.html).  The description of the package is "Annotations denoting the roles of types or methods in the overall architecture (at a conceptual, rather than implementation, level)."

It seems to me there's an opportunity here.  I would love to see an 'official' set of DDD annotations (i.e.: org.domaindrivendesign.*) - something that Spring could support, rather than create on it's own.

Anyone interested in this?  There's a lot of affinity between the Spring folks and DDD (http://www.nofluffjuststuff.com/speaker_topic_view.jsp?topicId=526, for example), and if Spring were to support a first-class set of annotations that were DDD-specific, it would only be good for DDD's continued adoption.

If you look at the package documentation above, Rod foreshadows the idea of using these kinds of annotations in tooling and aspects.  I haven't begun to think about the implications here, or what might be possible, but at any rate I think it would be of value to have these annotations out there and available (e.g.: in a jar in the global maven2 repository), so that folks can easily mark up their models and cleanly express their DDD nature.

- Chris

Chris Beams


I've actually packaged the annotations as 'org.domaindrivendesign' for extra clarity.



On Apr 10, 2007, at 11:42 AM, joethebigshmoe wrote:

Anyone use naming conventions to differentiate between an entity object
and a value object?

So instead of CUser and CUserStatus I might have eUser vUserStatus or
something similar.

If you are doing it, can you tell me the perceived benefits?
If not, but thought about it, can you explain why you decided against
it.

Thanks,

Joe



#5238 From: "James Kovacs" <jkovacs@...>
Date: Wed Apr 11, 2007 6:21 pm
Subject: Re: Naming Conventions - nice lightweight question
jkovacs@...
Send Email Send Email
 
I would agree with Bil. A value object sometimes morphs in to a full-fledged entity in the next iteration. This is similar to the classic argument against Hungarian notation. Data types change, but the variable name doesn't and you're left with a confusing codebase. (This is less of a concern with good refactoring tools because renaming is simple.) The root question is what value do you derive from knowing that something is a value object versus an entity? For that matter, should you identify aggregate roots versus other types of entities? I like Bil's idea of using namespaces to group together value objects and I've done the same thing in the past with success. If you need to reason about whether you're dealing with reference or value semantics, it's a quick check of the namespace, but the difference isn't smacking you in the face every time you read th code. Just my 3 cents. (Inflation, don't ya know.)

James
--
James Kovacs, B.Sc., M.Sc., MCSD, MCT
Microsoft MVP - Solutions Architect
http://www.jameskovacs.com
Please send all correspondence to jkovacs@...

On 10 Apr 2007 21:13:23 -0700, Bil Simser <bsimser@...> wrote:

I saw tomtdd's long post but figured I would chime in with my simple approach (as I don't want to get into the debate of why).

 

Originally I was doing something like this:

 

Class Person;

Class AddressVO;

 

I knew exactly that address (which might be a variable inside of Person) is a value object so I should treat it as such.

 

However a few things happened over the last couple of sprints:

 

1.       A few value objects started getting "smarts" and morphed or moved into the domain and grew up to become entities. I think this is a valid evolution.

2.       The fact we had a bunch of classes named xxxxVO didn't really have any value when looking at the model

 

So today we just call them by a descriptive name (Address rather than AddressVO) and they live in a ValueObjects namespace/folder in the system. If they move, we'll move them and move the namespace (gotta love ReSharper!).

 

From: domaindrivendesign@yahoogroups.com [mailto:domaindrivendesign@yahoogro ups.com] On Behalf Of joethebigshmoe
Sent: Tuesday, April 10, 2007 12:43 PM
To: domaindrivendesign@yahoogroups.com
Subject: [domaindrivendesign] Naming Conventions - nice lightweight question

 

Anyone use naming conventions to differentiate between an entity object
and a value object?

So instead of CUser and CUserStatus I might have eUser vUserStatus or
something similar.

If you are doing it, can you tell me the perceived benefits?
If not, but thought about it, can you explain why you decided against
it.

Thanks,

Joe





#5239 From: "Claude Montpetit" <claude@...>
Date: Wed Apr 11, 2007 7:05 pm
Subject: Re: Naming Conventions - nice lightweight question
claude_montp...
Send Email Send Email
 
One aspect of DDD that I think is critical is to share a common
precise domain language. This helps everyone talking about the same
thing when discussing the domain.

Applying this rule to the patterns used in the implementation can also
be beneficial. So making the patterns as part of the code makes sense
to me. Take for example the situation where new developers join the
domain team.  We can give them the DDD book and ask them to read it
for a day or two, and very well understand what are Entitites,
Aggregates, ValueObjects, Repositories, Service, etc.

Next, when they jump in the code, and directly see what each object
is. It becomes much easier for them to integrate.

Now does this can take the form of annotations, namespace (packages),
or postfixed/prefiixed class names, but relying only on documentation
(javadoc or else) and has never proven to be very efficient to me.

--
Claude

#5240 From: "Joe A. Reddy" <jreddy@...>
Date: Wed Apr 11, 2007 7:17 pm
Subject: RE: Naming Conventions - nice lightweight question
joethebigshmoe
Send Email Send Email
 
Claude,
I / we just could not come up with a reason why anyone would need to know. What would a developer, new to DDD or experienced, gain from knowing that an object is an entity or value object? What would he do differently or approach differently.
 
We use naming conventions already to denote other things and someone on my team suggested we do this in this case. I asked them and this group to tell me any reason I would benefit from knowing this while I was working with code. So far no one has had a very good reason.
 
To date I cannot recall a time when I got tripped up and thought, I sure wish the class name could have told me this info upfront so I never would have done [fill in the blank]. See what I mean?
 
Cheers,
Joe
 
 
 
 
 
 
 
 
-----Original Message-----
From: domaindrivendesign@yahoogroups.com [mailto:domaindrivendesign@yahoogroups.com] On Behalf Of Claude Montpetit
Sent: Wednesday, April 11, 2007 2:06 PM
To: domaindrivendesign@yahoogroups.com
Subject: Re: [domaindrivendesign] Naming Conventions - nice lightweight question

One aspect of DDD that I think is critical is to share a common
precise domain language. This helps everyone talking about the same
thing when discussing the domain.

Applying this rule to the patterns used in the implementation can also
be beneficial. So making the patterns as part of the code makes sense
to me. Take for example the situation where new developers join the
domain team. We can give them the DDD book and ask them to read it
for a day or two, and very well understand what are Entitites,
Aggregates, ValueObjects, Repositories, Service, etc.

Next, when they jump in the code, and directly see what each object
is. It becomes much easier for them to integrate.

Now does this can take the form of annotations, namespace (packages),
or postfixed/prefiixed class names, but relying only on documentation
(javadoc or else) and has never proven to be very efficient to me.

--
Claude


#5241 From: "Claude Montpetit" <claude@...>
Date: Wed Apr 11, 2007 7:50 pm
Subject: Re: Naming Conventions - nice lightweight question
claude_montp...
Send Email Send Email
 
 
To date I cannot recall a time when I got tripped up and thought, I sure wish the class name could have told me this info upfront so I never would have done [fill in the blank]. See what I mean?

Would that be anything you would have remembered anyway? But I guess you are right, there is no rational reason. It just feels good ;)

--
Claude


#5242 From: "colin.jack" <colin.jack@...>
Date: Wed Apr 11, 2007 8:06 pm
Subject: Re: When aggregates become too heavy.
colin.jack
Send Email Send Email
 
I'm no expert but I'd start have thought the obvious place for that
logic is PaymentMethods itself (ignore the naming and so on, but you
can see what I mean):

  if(this.PaymentMethods.IsFull == false)
  {
    this.PaymentMethods.Add(paymentMethod);
  }

..or maybe..

  this.PaymentMethods.AddIfNotFull(paymentMethod);

Obviously this only works if PaymentMethods is a custom collection
but I often find this is needed anyway.

You don't say where "PaymentMethod" is coming from, is it being
created just before the lines of code you show? If so can the
PaymentMethods collection create and add the new PaymentMethod?

--- In domaindrivendesign@yahoogroups.com, "jupitermoon_beam"
<jupitermoonbeam@...> wrote:
>
> Maybe a specific example may help and then people could give
specific
> answers to the problem.
>
> I will draw a domain around the traditional Customers and Orders
scenario.
>
> In this web based business ordering system we have a central
> Customer.  The Customer has the following concepts: Orders,
Accounts,
> Buyers and Payment Methods.
>
> Each of those concepts have specific rules specific rules around the
> Customer:
> * The number of payment methods (i.e. a credit card) allowed on a
> customer is directly related to the number of accounts a customer
has.
> * A payment method can pay money off any account the customer has.
> * A payment method can only belong to one Customer.
> * The number of Accounts a Customer can have depends on the type of
> Customer.
> * An order can only be placed on a Customer if all the accounts are
in
> good order.
> * Approved buyers can be enabled/disabled on a customer.
> * Buyers cannot belong to more than x number of customers (for
> security reasons).
>
> This is actually a simplification of the real domain I am talking
> about becoming heavy (there are even more concepts such as contact
> histories etc.).
>
> The issue is a lot of this logic requires that the Customer
aggregate
> executes some business logic whether it is Customer.AddOrder to
> Customer.AddBuyer to Customer.AddPaymentMethod.  The core domain is
> about placing orders not about making payments (that's a sub module)
> or managing buyers (again a sub module).  But because there are
rules
> specific to the Customer the Customer needs to know about them.
>
> For example I tried to seperate out Payment Methods but the logic to
> register a payment method is something like:
> if(this.PaymentMethods.Count <
this.MaxNumberOfPaymentMethodsAllowed)
> {
>  PaymentMethods.Add(PaymentMethod);
> }
>
> I can't think of a way of ripping that out of the Customer wihtout
> making it a service which seems silly because it works well in an
> aggregate it's just the aggregate is getting too heavy.
>
> I eagerly await feedback.
>
> --- In domaindrivendesign@yahoogroups.com, "colin.jack"
> <colin.jack@> wrote:
> >
> > That might be one way to split it, I definitely would try to keep
my
> > Customer lightweight but I'm not sure if moving Orders off is the
> > correct way to do that. Surely the most important thing about a
> > Customer is that they make Orders? Thats what differentiates them
> > from any other person that the model deals with (if the model
deals
> > with other people).
> >
> > I'd maybe consider breaking it a different way. For example if
you
> > have a lot of personal information on Client then move that into
> > another hierarchy (Party) and have the Customer be a role that a
> > Party can be in (see Arlow for examples of this).
> >
> > In any case though if you do move the rules into CustomerOrders
then
> > surely Customer can still reference CustomerOrders, thats just
one
> > aggregate root referencing another. I certainly wouldn't keep
Order
> > specific rules in Customer but I also wouldn't decouple Customer
and
> > Order unless I had other reasons for doing it, especially if most
> > users of the Customer class are going to be accessing the Orders
> > collection.
> >
> > Thats my 2cents anyway.
> >
> > --- In domaindrivendesign@yahoogroups.com, "jupitermoon_beam"
> > <jupitermoonbeam@> wrote:
> > >
> > > I think Patrick's post is where my thinking was going (I will
try
> > and
> > > confirm if I've got it right).
> > >
> > > It was the subject of Eric's post that was starting to concern
me
> > > about these Greedy Aggregates.  To take Eric's and Bert's posts
are
> > we
> > > saying the the greedy aggregate
> > > has concepts in it that can be split into more specific sub
> > aggregates
> > > (like the facets)?  In effect the aggregate needs to be
inverted.
> > >
> > > For example rather than having a Customer holding all the rules
for
> > > managing Orders on itself have a CustomerOrders aggregate which
> > deals
> > > with the Customer as an entity (using Partick's example the
Customer
> > > becomes the key to retrieving the CustomerOrders aggregate).
Then
> > to
> > > deal with a customer's orders you can deal with the
CustomerOrders
> > > aggregate directly without having to deal with the rest of the
> > > Customer.  It also means that the Customer can become
modularised.
> > >
> > > Does this risk making the Customer aneamic? I guess if the
focus of
> > > the surgery is around preserving the core domain then the risk
> > should
> > > be contained.
> > >
> > > Also I've often found that we miss concepts in modelling that
hide
> > > within the Ubiqutous Language and need pulling out (Eric's book
is
> > > littered with examples).  For example in a system that tracks
Car's
> > > and their Owners (such as the British Road Tax system) people
often
> > > link Car directly to Owner but there is a concept of
registration
> > > whereby the Owner registers the Car with the system.  This
> > > Registration often has it's own rules and data which live
outside
> > both
> > > the Car and Owner and you often see people struggling with the
model
> > > because they haven't stumbled across the word "register" in the
> > > language.  Basically maybe a lot of these concepts are 'hidden'
even
> > > further (such as CustomerOrders).
> > >
> > > Am I going in the right direction here?
> > >
> > > --- In domaindrivendesign@yahoogroups.com, Patrick Bohan
> > > <patbohan@> wrote:
> > > >
> > > > I've dealt with what sounds like a similar problem.
> > > >
> > > > At a previous job we had an application that performed
various
> > types of
> > > > batch processing on a very large components. By large I mean
both
> > > memory
> > > > intensive (usually between 10 and 200 Mbs) and conceptually
large
> > (lots
> > > > of little and not-so-little pieces.) The components were all
> > related
> > > but
> > > > when and where we needed different parts was not common. (In
one
> > > area of
> > > > the system we needed parts A and B, in another B and C, and a
> > third A,
> > > > B, and C).
> > > >
> > > > To manage this we did not create one monster object, we
created a
> > tiny
> > > > core token object that contained the bare necessities and a
suite
> > of
> > > > objects to cover of the other major parts. (We dubbed these
other
> > parts
> > > > "facets", as in the facets or sides of a jewel. All the
facets
> > together
> > > > make the complete jewel, but most of the time you are only
> > looking at
> > > > the few that you can see.)
> > > >
> > > > In practice what we always had a reference to the core
object. It
> > > was an
> > > > immutable light weight object that everything in the system
> > recognized.
> > > > (For us it was limited to an ID number, type, and
description.)
> > The
> > > core
> > > > object by itself was useless except in one regard: we could
use
> > it to
> > > > get the other, useful parts. We would supply the particular
> > Repository
> > > > that housed the type of parts we cared about this core
object,
> > and we'd
> > > > get our part.
> > > >
> > > > We never created a direct reference from the core object to
any
> > of the
> > > > parts. We deferred that activity to the areas that needed the
> > parts. If
> > > > an area needed a container class to hold the core object and
> > several
> > > > parts they would build one as needed.
> > > >
> > > > I don't know the domain of your problem, but we were only
able to
> > (and
> > > > required to) achieve this splitting due to the nature of our
> > > problem: we
> > > > often only needed only one or two parts and we never needed
all
> > the
> > > parts.
> > > >
> > > > Patrick
> > > > ARKBAN
> > > >
> > > > Dru Sellers wrote:
> > > > > I have this exact same problem but hadn't put words to it.
The
> > greedy
> > > > > aggregate is indeed something that feels bad, but is it? I
look
> > > forward
> > > > > to the comments from everyone on this. -d
> > > > >
> > > > > On 4/10/07, *jupitermoon_beam* <jupitermoonbeam@
> > > > > <mailto:jupitermoonbeam@>> wrote:
> > > > >
> > > > >     Although in the DDD book there are many concpets about
> > > modularizing
> > > > >     the domain itself I am often faced with tackling heavy
> > entities.
> > > > >
> > > > >     In many domains there is a single core aggregate (much
of
> > the time
> > > > >     Customer) and a large amount of the logic and concepts
in
> > the
> > > domain
> > > > >     hang off of this one aggregate. The result is a rather
heavy
> > > > >     aggregate which contains a lot of concepts.
> > > > >
> > > > >     Because the aggregate owns a lot of the domains
concepts it
> > is
> > > really
> > > > >     difficult to split it. A lot of the concepts exist
outside
> > of the
> > > > >     core domain but the domain naturally centralizes itself
> > around
> > > this
> > > > >     one object.
> > > > >
> > > > >     Sometimes I find I can splinter the logic off into
services
> > or
> > > turn
> > > > >     simple lists (such as contact histories etc.) into
> > aggregrates and
> > > > >     give them their own repositories but sometimes there
can be
> > a
> > > lot of
> > > > >     domain logic that the central aggregate naturally owns.
> > > > >
> > > > >     How do people deal with these heavy aggregates? What
tricks
> > can be
> > > > >     used to break our greedy aggregates down into smaller
> > managebal
> > > > >     entities?
> > > > >
> > > > >
> > > > >
> > > > >
> > > > > --
> > > > > cheers,
> > > > > -d
> > > >
> > >
> >
>

#5243 From: "Bil Simser" <bsimser@...>
Date: Thu Apr 12, 2007 12:37 am
Subject: RE: Naming Conventions - nice lightweight question
sim0099
Send Email Send Email
 

I’m not hijacking this thread, but something Claude said struck a bit of a chord with me.

 

Unless the developer is a senior guy who can dance OO circles around and with me, I wouldn’t hand him a copy of DDD and tell him to read it for a day or two. If anything I might get them to read DDD Quickly, but I would sit down with them and go over the basics. A DDD 010 course that shouldn’t be more than an hour or two. This would go over Entities, Aggregates, Repositories, etc. with some concrete examples.

 

I just didn’t want what Claude say here to be taken as “read this book and you’ll get it”.

 

It took me 2 reads (one skim and one solid read) of Eric’s book and about 6 months of spiking and trying out concepts in projects before the light bulb went on (and I still have a lot to learn.

 

From: domaindrivendesign@yahoogroups.com [mailto:domaindrivendesign@yahoogroups.com] On Behalf Of Claude Montpetit
Sent: Wednesday, April 11, 2007 1:06 PM
To: domaindrivendesign@yahoogroups.com
Subject: Re: [domaindrivendesign] Naming Conventions - nice lightweight question

 

One aspect of DDD that I think is critical is to share a common
precise domain language. This helps everyone talking about the same
thing when discussing the domain.

Applying this rule to the patterns used in the implementation can also
be beneficial. So making the patterns as part of the code makes sense
to me. Take for example the situation where new developers join the
domain team. We can give them the DDD book and ask them to read it
for a day or two, and very well understand what are Entitites,
Aggregates, ValueObjects, Repositories, Service, etc.

Next, when they jump in the code, and directly see what each object
is. It becomes much easier for them to integrate.

Now does this can take the form of annotations, namespace (packages),
or postfixed/prefiixed class names, but relying only on documentation
(javadoc or else) and has never proven to be very efficient to me.

--
Claude


#5244 From: "Bil Simser" <bsimser@...>
Date: Thu Apr 12, 2007 12:49 am
Subject: RE: DDD Annotations (was: Re: Naming Conventions - nice lightweight question)
sim0099
Send Email Send Email
 

I wrote a post awhile back about using a different type definition rather than “class” for various things. The post is here:

http://weblogs.asp.net/bsimser/archive/2007/01/21/domain-driven-design-for-c-3-0.aspx

 

Essentially rather than “class Order” and “class Person” the types are defined as “entity Order” and “valueobject Person”. I like the way it reads, but don’t think it’s doable in at least C# 3.0 (maybe 3.5 but all the numbers get me confused).

 

John Lam mentioned this was completely doable in Ruby (what isn’t?) but with extensions in C# it might be possible.

 

In any case, it’s good to tag your code with some kind of nomenclature (especially for people reading it for the first time). In .NET we can use xml tags in the comments (and these can be anything) so I’ve been doing something like this in my class definitions. When API docs are generated (every night) everything is grouped by the tag and there’s a special view I created in the output HTML file for the docs that lets me see a tree view of Entities, Aggregates, VOs, Repositories, etc. based on that tag.

 

From: domaindrivendesign@yahoogroups.com [mailto:domaindrivendesign@yahoogroups.com] On Behalf Of cbeams
Sent: Wednesday, April 11, 2007 10:42 AM
To: domaindrivendesign@yahoogroups.com
Subject: [domaindrivendesign] DDD Annotations (was: Re: Naming Conventions - nice lightweight question)

 

I'm using a simple set of DDD annotations that could be thought of as analogous to 'marker' interfaces:

 

@AggregateRoot

@Repository

@Entity

@ValueObject

@Factory

@Service

 

The primary intention of these annotations is not one of tooling or validation (thought that's conceivable), but rather as a lightweight communication mechanism for developers.  Given that a team has a working context for DDD, it's of value to be able to browse through the code and immediately see the intent of any particular model object.  I've packaged these within our codebase as 'org.domaindrivendesign.*' for additional clarity, and each annotation's respective JavaDoc has @see references to the pages in the book that describe/distinguish that type of model object. 

 

Interestingly, Spring 2.0 introduced a package 'org.springframework.sterotype', which has a single annotation at this point: '@Repository' (http://www.springframework.org/docs/api/org/springframework/stereotype/package-summary.html).  The description of the package is "Annotations denoting the roles of types or methods in the overall architecture (at a conceptual, rather than implementation, level)."

 

It seems to me there's an opportunity here.  I would love to see an 'official' set of DDD annotations (i.e.: org.domaindrivendesign.*) - something that Spring could support, rather than create on it's own.

 

Anyone interested in this?  There's a lot of affinity between the Spring folks and DDD (http://www.nofluffjuststuff.com/speaker_topic_view.jsp?topicId=526, for example), and if Spring were to support a first-class set of annotations that were DDD-specific, it would only be good for DDD's continued adoption.

 

If you look at the package documentation above, Rod foreshadows the idea of using these kinds of annotations in tooling and aspects.  I haven't begun to think about the implications here, or what might be possible, but at any rate I think it would be of value to have these annotations out there and available (e.g.: in a jar in the global maven2 repository), so that folks can easily mark up their models and cleanly express their DDD nature.

 

- Chris

 

Chris Beams

 

 

I've actually packaged the annotations as 'org.domaindrivendesign' for extra clarity.

 

 

 

On Apr 10, 2007, at 11:42 AM, joethebigshmoe wrote:



Anyone use naming conventions to differentiate between an entity object
and a value object?

So instead of CUser and CUserStatus I might have eUser vUserStatus or
something similar.

If you are doing it, can you tell me the perceived benefits?
If not, but thought about it, can you explain why you decided against
it.

Thanks,

Joe

 


#5245 From: "Claude Montpetit" <claude@...>
Date: Thu Apr 12, 2007 1:44 am
Subject: Re: Naming Conventions - nice lightweight question
claude_montp...
Send Email Send Email
 


A DDD 010 course that shouldn't be more than an hour or two. This would go over Entities, Aggregates, Repositories, etc. with some concrete examples.

I just didn't want what Claude say here to be taken as "read this book and you'll get it".

You are right, I did not mean to say this. It strikes me how I am often read so literally; being precise, consise, and 100% accurate is not given to all people who dare writing in public. I certainly did not want to lead anyone into thinking that understanding Eric's book is quick and trivial. A close look at the archive in this list shows it is not.

--
Claude

#5246 From: "jupitermoon_beam" <jupitermoonbeam@...>
Date: Thu Apr 12, 2007 8:00 am
Subject: Re: When aggregates become too heavy.
jupitermoon_...
Send Email Send Email
 
> I'm no expert but I'd start have thought the obvious place for that
> logic is PaymentMethods itself

That's kinda what I was thinking with the CustomerOrders class in my
previous post.  In effect there would be a CustomerPaymentMethods class.

> You don't say where "PaymentMethod" is coming from, is it being
> created just before the lines of code you show? If so can the
> PaymentMethods collection create and add the new PaymentMethod?

In this particular domain PaymentMethod gets tricky because everytime
a succesful payment is made it (i.e. a Credit Card transaction is
approved) it moves from a value object and becomes an entity.  It is
then added to the list and if full the least used payment method is
dropped from the list (sorry I did omit that but for simplicities
sake).  So the simple answer is that yes the PaymentMethod is can be
created and added at the same time from the service.

>  if(this.PaymentMethods.IsFull == false)
The only niggle is that the answer to IsFull lies with the number of
Accounts the Customer has.  There are only two ways I can think of
solving this:
* Inject Customer into the customer collection (CustomerPaymentMethods)
* speak directly to a repository (and here we are again with the whole
repository argument).

The truth is both solutions are slightly frowned upon (without getting
another argument going).  Having a Greedy Aggregate meant staying
within the "rules" so is there another way or is it a case of the
lesser of evils (in which case I'd go with the custom
collection/middle object)?

--- In domaindrivendesign@yahoogroups.com, "colin.jack"
<colin.jack@...> wrote:
>
> I'm no expert but I'd start have thought the obvious place for that
> logic is PaymentMethods itself (ignore the naming and so on, but you
> can see what I mean):
>
>  if(this.PaymentMethods.IsFull == false)
>  {
>    this.PaymentMethods.Add(paymentMethod);
>  }
>
> ..or maybe..
>
>  this.PaymentMethods.AddIfNotFull(paymentMethod);
>
> Obviously this only works if PaymentMethods is a custom collection
> but I often find this is needed anyway.
>
> You don't say where "PaymentMethod" is coming from, is it being
> created just before the lines of code you show? If so can the
> PaymentMethods collection create and add the new PaymentMethod?
>
> --- In domaindrivendesign@yahoogroups.com, "jupitermoon_beam"
> <jupitermoonbeam@> wrote:
> >
> > Maybe a specific example may help and then people could give
> specific
> > answers to the problem.
> >
> > I will draw a domain around the traditional Customers and Orders
> scenario.
> >
> > In this web based business ordering system we have a central
> > Customer.  The Customer has the following concepts: Orders,
> Accounts,
> > Buyers and Payment Methods.
> >
> > Each of those concepts have specific rules specific rules around the
> > Customer:
> > * The number of payment methods (i.e. a credit card) allowed on a
> > customer is directly related to the number of accounts a customer
> has.
> > * A payment method can pay money off any account the customer has.
> > * A payment method can only belong to one Customer.
> > * The number of Accounts a Customer can have depends on the type of
> > Customer.
> > * An order can only be placed on a Customer if all the accounts are
> in
> > good order.
> > * Approved buyers can be enabled/disabled on a customer.
> > * Buyers cannot belong to more than x number of customers (for
> > security reasons).
> >
> > This is actually a simplification of the real domain I am talking
> > about becoming heavy (there are even more concepts such as contact
> > histories etc.).
> >
> > The issue is a lot of this logic requires that the Customer
> aggregate
> > executes some business logic whether it is Customer.AddOrder to
> > Customer.AddBuyer to Customer.AddPaymentMethod.  The core domain is
> > about placing orders not about making payments (that's a sub module)
> > or managing buyers (again a sub module).  But because there are
> rules
> > specific to the Customer the Customer needs to know about them.
> >
> > For example I tried to seperate out Payment Methods but the logic to
> > register a payment method is something like:
> > if(this.PaymentMethods.Count <
> this.MaxNumberOfPaymentMethodsAllowed)
> > {
> >  PaymentMethods.Add(PaymentMethod);
> > }
> >
> > I can't think of a way of ripping that out of the Customer wihtout
> > making it a service which seems silly because it works well in an
> > aggregate it's just the aggregate is getting too heavy.
> >
> > I eagerly await feedback.
> >
> > --- In domaindrivendesign@yahoogroups.com, "colin.jack"
> > <colin.jack@> wrote:
> > >
> > > That might be one way to split it, I definitely would try to keep
> my
> > > Customer lightweight but I'm not sure if moving Orders off is the
> > > correct way to do that. Surely the most important thing about a
> > > Customer is that they make Orders? Thats what differentiates them
> > > from any other person that the model deals with (if the model
> deals
> > > with other people).
> > >
> > > I'd maybe consider breaking it a different way. For example if
> you
> > > have a lot of personal information on Client then move that into
> > > another hierarchy (Party) and have the Customer be a role that a
> > > Party can be in (see Arlow for examples of this).
> > >
> > > In any case though if you do move the rules into CustomerOrders
> then
> > > surely Customer can still reference CustomerOrders, thats just
> one
> > > aggregate root referencing another. I certainly wouldn't keep
> Order
> > > specific rules in Customer but I also wouldn't decouple Customer
> and
> > > Order unless I had other reasons for doing it, especially if most
> > > users of the Customer class are going to be accessing the Orders
> > > collection.
> > >
> > > Thats my 2cents anyway.
> > >
> > > --- In domaindrivendesign@yahoogroups.com, "jupitermoon_beam"
> > > <jupitermoonbeam@> wrote:
> > > >
> > > > I think Patrick's post is where my thinking was going (I will
> try
> > > and
> > > > confirm if I've got it right).
> > > >
> > > > It was the subject of Eric's post that was starting to concern
> me
> > > > about these Greedy Aggregates.  To take Eric's and Bert's posts
> are
> > > we
> > > > saying the the greedy aggregate
> > > > has concepts in it that can be split into more specific sub
> > > aggregates
> > > > (like the facets)?  In effect the aggregate needs to be
> inverted.
> > > >
> > > > For example rather than having a Customer holding all the rules
> for
> > > > managing Orders on itself have a CustomerOrders aggregate which
> > > deals
> > > > with the Customer as an entity (using Partick's example the
> Customer
> > > > becomes the key to retrieving the CustomerOrders aggregate).
> Then
> > > to
> > > > deal with a customer's orders you can deal with the
> CustomerOrders
> > > > aggregate directly without having to deal with the rest of the
> > > > Customer.  It also means that the Customer can become
> modularised.
> > > >
> > > > Does this risk making the Customer aneamic? I guess if the
> focus of
> > > > the surgery is around preserving the core domain then the risk
> > > should
> > > > be contained.
> > > >
> > > > Also I've often found that we miss concepts in modelling that
> hide
> > > > within the Ubiqutous Language and need pulling out (Eric's book
> is
> > > > littered with examples).  For example in a system that tracks
> Car's
> > > > and their Owners (such as the British Road Tax system) people
> often
> > > > link Car directly to Owner but there is a concept of
> registration
> > > > whereby the Owner registers the Car with the system.  This
> > > > Registration often has it's own rules and data which live
> outside
> > > both
> > > > the Car and Owner and you often see people struggling with the
> model
> > > > because they haven't stumbled across the word "register" in the
> > > > language.  Basically maybe a lot of these concepts are 'hidden'
> even
> > > > further (such as CustomerOrders).
> > > >
> > > > Am I going in the right direction here?
> > > >
> > > > --- In domaindrivendesign@yahoogroups.com, Patrick Bohan
> > > > <patbohan@> wrote:
> > > > >
> > > > > I've dealt with what sounds like a similar problem.
> > > > >
> > > > > At a previous job we had an application that performed
> various
> > > types of
> > > > > batch processing on a very large components. By large I mean
> both
> > > > memory
> > > > > intensive (usually between 10 and 200 Mbs) and conceptually
> large
> > > (lots
> > > > > of little and not-so-little pieces.) The components were all
> > > related
> > > > but
> > > > > when and where we needed different parts was not common. (In
> one
> > > > area of
> > > > > the system we needed parts A and B, in another B and C, and a
> > > third A,
> > > > > B, and C).
> > > > >
> > > > > To manage this we did not create one monster object, we
> created a
> > > tiny
> > > > > core token object that contained the bare necessities and a
> suite
> > > of
> > > > > objects to cover of the other major parts. (We dubbed these
> other
> > > parts
> > > > > "facets", as in the facets or sides of a jewel. All the
> facets
> > > together
> > > > > make the complete jewel, but most of the time you are only
> > > looking at
> > > > > the few that you can see.)
> > > > >
> > > > > In practice what we always had a reference to the core
> object. It
> > > > was an
> > > > > immutable light weight object that everything in the system
> > > recognized.
> > > > > (For us it was limited to an ID number, type, and
> description.)
> > > The
> > > > core
> > > > > object by itself was useless except in one regard: we could
> use
> > > it to
> > > > > get the other, useful parts. We would supply the particular
> > > Repository
> > > > > that housed the type of parts we cared about this core
> object,
> > > and we'd
> > > > > get our part.
> > > > >
> > > > > We never created a direct reference from the core object to
> any
> > > of the
> > > > > parts. We deferred that activity to the areas that needed the
> > > parts. If
> > > > > an area needed a container class to hold the core object and
> > > several
> > > > > parts they would build one as needed.
> > > > >
> > > > > I don't know the domain of your problem, but we were only
> able to
> > > (and
> > > > > required to) achieve this splitting due to the nature of our
> > > > problem: we
> > > > > often only needed only one or two parts and we never needed
> all
> > > the
> > > > parts.
> > > > >
> > > > > Patrick
> > > > > ARKBAN
> > > > >
> > > > > Dru Sellers wrote:
> > > > > > I have this exact same problem but hadn't put words to it.
> The
> > > greedy
> > > > > > aggregate is indeed something that feels bad, but is it? I
> look
> > > > forward
> > > > > > to the comments from everyone on this. -d
> > > > > >
> > > > > > On 4/10/07, *jupitermoon_beam* <jupitermoonbeam@
> > > > > > <mailto:jupitermoonbeam@>> wrote:
> > > > > >
> > > > > >     Although in the DDD book there are many concpets about
> > > > modularizing
> > > > > >     the domain itself I am often faced with tackling heavy
> > > entities.
> > > > > >
> > > > > >     In many domains there is a single core aggregate (much
> of
> > > the time
> > > > > >     Customer) and a large amount of the logic and concepts
> in
> > > the
> > > > domain
> > > > > >     hang off of this one aggregate. The result is a rather
> heavy
> > > > > >     aggregate which contains a lot of concepts.
> > > > > >
> > > > > >     Because the aggregate owns a lot of the domains
> concepts it
> > > is
> > > > really
> > > > > >     difficult to split it. A lot of the concepts exist
> outside
> > > of the
> > > > > >     core domain but the domain naturally centralizes itself
> > > around
> > > > this
> > > > > >     one object.
> > > > > >
> > > > > >     Sometimes I find I can splinter the logic off into
> services
> > > or
> > > > turn
> > > > > >     simple lists (such as contact histories etc.) into
> > > aggregrates and
> > > > > >     give them their own repositories but sometimes there
> can be
> > > a
> > > > lot of
> > > > > >     domain logic that the central aggregate naturally owns.
> > > > > >
> > > > > >     How do people deal with these heavy aggregates? What
> tricks
> > > can be
> > > > > >     used to break our greedy aggregates down into smaller
> > > managebal
> > > > > >     entities?
> > > > > >
> > > > > >
> > > > > >
> > > > > >
> > > > > > --
> > > > > > cheers,
> > > > > > -d
> > > > >
> > > >
> > >
> >
>

#5247 From: "jupitermoon_beam" <jupitermoonbeam@...>
Date: Thu Apr 12, 2007 11:40 am
Subject: DDD Annotations (was: Re: Naming Conventions - nice lightweight question)
jupitermoon_...
Send Email Send Email
 
I try to ensure that Value objects are immutable and are truly Value
objects.

I know there are some issues in Java with real value objects but in C#
you can make them structs (as Martin Fowler advises in PEAA).  The
only draw back is structs can't be inherited which can be a pain if
you want some sort of a hierachy with your VOs but I normally find
that if I can use composition with interfaces to give what would have
been my inherited hierachy.

I can see some other disadvantages to structs (like larger value
objects) but a lot of the time cutting your objects down to make them
more specific gets' around this 90% of the time.

Hope this helps.

--- In domaindrivendesign@yahoogroups.com, "Bil Simser" <bsimser@...>
wrote:
>
> I wrote a post awhile back about using a different type definition
rather
> than "class" for various things. The post is here:
>
>
http://weblogs.asp.net/bsimser/archive/2007/01/21/domain-driven-design-for-c
> -3-0.aspx
>
>
>
> Essentially rather than "class Order" and "class Person" the types are
> defined as "entity Order" and "valueobject Person". I like the way
it reads,
> but don't think it's doable in at least C# 3.0 (maybe 3.5 but all the
> numbers get me confused).
>
>
>
> John Lam mentioned this was completely doable in Ruby (what isn't?)
but with
> extensions in C# it might be possible.
>
>
>
> In any case, it's good to tag your code with some kind of nomenclature
> (especially for people reading it for the first time). In .NET we
can use
> xml tags in the comments (and these can be anything) so I've been doing
> something like this in my class definitions. When API docs are generated
> (every night) everything is grouped by the tag and there's a special
view I
> created in the output HTML file for the docs that lets me see a tree
view of
> Entities, Aggregates, VOs, Repositories, etc. based on that tag.
>
>
>
> From: domaindrivendesign@yahoogroups.com
> [mailto:domaindrivendesign@yahoogroups.com] On Behalf Of cbeams
> Sent: Wednesday, April 11, 2007 10:42 AM
> To: domaindrivendesign@yahoogroups.com
> Subject: [domaindrivendesign] DDD Annotations (was: Re: Naming
Conventions -
> nice lightweight question)
>
>
>
> I'm using a simple set of DDD annotations that could be thought of as
> analogous to 'marker' interfaces:
>
>
>
> @AggregateRoot
>
> @Repository
>
> @Entity
>
> @ValueObject
>
> @Factory
>
> @Service
>
>
>
> The primary intention of these annotations is not one of tooling or
> validation (thought that's conceivable), but rather as a lightweight
> communication mechanism for developers.  Given that a team has a working
> context for DDD, it's of value to be able to browse through the code and
> immediately see the intent of any particular model object.  I've
packaged
> these within our codebase as 'org.domaindrivendesign.*' for additional
> clarity, and each annotation's respective JavaDoc has @see
references to the
> pages in the book that describe/distinguish that type of model object.
>
>
>
> Interestingly, Spring 2.0 introduced a package
> 'org.springframework.sterotype', which has a single annotation at this
> point: '@Repository'
>
(http://www.springframework.org/docs/api/org/springframework/stereotype/pack
> age-summary.html).  The description of the package is "Annotations
denoting
> the roles of types or methods in the overall architecture (at a
conceptual,
> rather than implementation, level)."
>
>
>
> It seems to me there's an opportunity here.  I would love to see an
> 'official' set of DDD annotations (i.e.: org.domaindrivendesign.*) -
> something that Spring could support, rather than create on it's own.
>
>
>
> Anyone interested in this?  There's a lot of affinity between the Spring
> folks and DDD
> (http://www.nofluffjuststuff.com/speaker_topic_view.jsp?topicId=526, for
> example), and if Spring were to support a first-class set of annotations
> that were DDD-specific, it would only be good for DDD's continued
adoption.
>
>
>
> If you look at the package documentation above, Rod foreshadows the
idea of
> using these kinds of annotations in tooling and aspects.  I haven't
begun to
> think about the implications here, or what might be possible, but at any
> rate I think it would be of value to have these annotations out
there and
> available (e.g.: in a jar in the global maven2 repository), so that
folks
> can easily mark up their models and cleanly express their DDD nature.
>
>
>
> - Chris
>
>
>
> Chris Beams
>
>
>
>
>
> I've actually packaged the annotations as 'org.domaindrivendesign'
for extra
> clarity.
>
>
>
>
>
>
>
> On Apr 10, 2007, at 11:42 AM, joethebigshmoe wrote:
>
>
>
>
>
> Anyone use naming conventions to differentiate between an entity object
> and a value object?
>
> So instead of CUser and CUserStatus I might have eUser vUserStatus or
> something similar.
>
> If you are doing it, can you tell me the perceived benefits?
> If not, but thought about it, can you explain why you decided against
> it.
>
> Thanks,
>
> Joe
>

#5248 From: "billhamaker" <BillHamaker@...>
Date: Thu Apr 12, 2007 1:25 pm
Subject: Re: When aggregates become too heavy.
billhamaker
Send Email Send Email
 
It seems to me that one problem with putting this code in the
customer is that it is not very clear what the customer object
should do if the maximum payment business method is violated.
Throw an exception?   Return an error code or error message?

Another problem is that this design leaves all the business rules
scattered through out the code in the various domain logic.   So if
you are trying to figure out what the business rules are or need to
change them you are going to have to do a lot of detective work.

This makes we wonder if this logic might instead belong the
application layer and not the domain layer.   You might for have an
application objects which can be asked whether it is valid to add a
payment in a particular situation.

So I think my answer to your question would be that if the aggregate
class logic is getting too "heavy" I would tend to move it out of
the domain and into the application layer.   If the application gets
to heavy I might create a generic domain to lighten it (e.g. create
a generic business rule domain).

Bill Hamaker



--- In domaindrivendesign@yahoogroups.com, "jupitermoon_beam"
<jupitermoonbeam@...> wrote:
>
> Maybe a specific example may help and then people could give
specific
> answers to the problem.
>
> I will draw a domain around the traditional Customers and Orders
scenario.
>
> In this web based business ordering system we have a central
> Customer.  The Customer has the following concepts: Orders,
Accounts,
> Buyers and Payment Methods.
>
> Each of those concepts have specific rules specific rules around
the
> Customer:
> * The number of payment methods (i.e. a credit card) allowed on a
> customer is directly related to the number of accounts a customer
has.
> * A payment method can pay money off any account the customer has.
> * A payment method can only belong to one Customer.
> * The number of Accounts a Customer can have depends on the type of
> Customer.
> * An order can only be placed on a Customer if all the accounts
are in
> good order.
> * Approved buyers can be enabled/disabled on a customer.
> * Buyers cannot belong to more than x number of customers (for
> security reasons).
>
> This is actually a simplification of the real domain I am talking
> about becoming heavy (there are even more concepts such as contact
> histories etc.).
>
> The issue is a lot of this logic requires that the Customer
aggregate
> executes some business logic whether it is Customer.AddOrder to
> Customer.AddBuyer to Customer.AddPaymentMethod.  The core domain is
> about placing orders not about making payments (that's a sub
module)
> or managing buyers (again a sub module).  But because there are
rules
> specific to the Customer the Customer needs to know about them.
>
> For example I tried to seperate out Payment Methods but the logic
to
> register a payment method is something like:
> if(this.PaymentMethods.Count <
this.MaxNumberOfPaymentMethodsAllowed)
> {
>  PaymentMethods.Add(PaymentMethod);
> }
>
> I can't think of a way of ripping that out of the Customer wihtout
> making it a service which seems silly because it works well in an
> aggregate it's just the aggregate is getting too heavy.
>
> I eagerly await feedback.
>
>

#5249 From: "billhamaker" <BillHamaker@...>
Date: Thu Apr 12, 2007 2:54 pm
Subject: Large Scale Domain Structure
billhamaker
Send Email Send Email
 
Consider the following proposed high level domain structure for a
company that provides asset based tax services.

1.  Core Domain
Encapsulates Customers, Operational Contacts, Agreements, Customer
Owned or Managed Assets, Customer Business Locations, Taxing
Authorities, etc.

2.  Marketing and Client Relationship Domain
Encapsulates CRM functionality.

3.  Services Domains
The company provides a variety of services each with their own data
requirements.  So I would propose a separate domain for each
different type of service offered.

Some questions about this architecture.

1.  Do you think its a good starting point for a high level
structure?

2.  What kind of interface should there be between the Core and
Marketing Domains and the individual service domains?   Could you
use some kind of plug in architecture with dependency injection into
of service domains into the core domain or would that be too hard?

3.  What kind of interface should there be between the the Core and
Marketing Domains?  For example how does a prospect become a
customer in the core domain?   Show core domain repositories
directly read the CRM database?    How should Customer contacts of
interest to both domains be coordinated?

4.  How would you handle cross cutting functionality like agreements
and invoicing.  There are common invoicing requirements but for
example the format and content of an agreement or invoice probably
needs to be different in each service domain.   Does a central
controlling domain call with individual services domains get
variations in standard processing or do individual domains call a
central service domain to get shared functionality?


Bill Hamaker

#5250 From: "jupitermoon_beam" <jupitermoonbeam@...>
Date: Thu Apr 12, 2007 3:39 pm
Subject: When to use Whole Value
jupitermoon_...
Send Email Send Email
 
I love the whole value pattern and try and use it where I can (plug:
http://jupitermoonbeam.blogspot.com/2007/04/whole-values.html).

My question is how far should the exercise of Whole Value go?  Objects
like PostCode or TelephoneNumber are obvious but what about the
simpler things like Title, Surname or Forename?

On the surface is looks like Title, Surname and Forename can exist
happily as strings but you often find that you're soon adding
Surname.IsDoubleBarelled or Title.IsMilitary or Forename.IsSimilarTo
(a real method I've seen for matching duplicate customers e.g. Geoff
and Jeff).

My question is how aggresively do people use the Whole Value pattern
in their domains?  On one side of the corner is the argument that any
concept should be abstracted and encapsulated on the other side is are
you wasting your time?

#5251 From: "trondeirikkolloen" <trond-eirik@...>
Date: Thu Apr 12, 2007 3:41 pm
Subject: Re: When aggregates become too heavy.
trondeirikko...
Send Email Send Email
 
Many framework or suggested framework seems to be using the aggregate
as a root for stuff like business rule validation and getting state.

So as far as I can see, these heavy aggreate will cause practical
problems in this context.

For rules it migth be difficult for the customer to recognice what
rule is actually broken if the aggregate root is large and the broken
rule may involve one or several items a long way down in the relation
hiearchy.

Another example; The CSLA.Net frameworks's solution for undo support
is to get the state of the aggregate root and all child items.
This might be a very expensive operation when using heavy aggregates.

However, I see a lot of benefits by giving access to a lot of stuff
from the aggregate root, but the downside is stuff like mention above.
If someone has a solution to those exact issues, I'll be thrilled to
hear about them :-)

Best regards, Trond-Eirik
--- In domaindrivendesign@yahoogroups.com, "Dru Sellers" <dru@...>
wrote:
>
> I have this exact same problem but hadn't put words to it. The
greedy
> aggregate is indeed something that feels bad, but is it? I look
forward to
> the comments from everyone on this. -d
>
> On 4/10/07, jupitermoon_beam <jupitermoonbeam@...> wrote:
> >
> >   Although in the DDD book there are many concpets about
modularizing
> > the domain itself I am often faced with tackling heavy entities.
> >
> > In many domains there is a single core aggregate (much of the time
> > Customer) and a large amount of the logic and concepts in the
domain
> > hang off of this one aggregate. The result is a rather heavy
> > aggregate which contains a lot of concepts.
> >
> > Because the aggregate owns a lot of the domains concepts it is
really
> > difficult to split it. A lot of the concepts exist outside of the
> > core domain but the domain naturally centralizes itself around
this
> > one object.
> >
> > Sometimes I find I can splinter the logic off into services or
turn
> > simple lists (such as contact histories etc.) into aggregrates and
> > give them their own repositories but sometimes there can be a lot
of
> > domain logic that the central aggregate naturally owns.
> >
> > How do people deal with these heavy aggregates? What tricks can be
> > used to break our greedy aggregates down into smaller managebal
entities?
> >
> >
> >
>
>
>
> --
> cheers,
> -d
>

#5252 From: Gregg Irwin <greggirwin@...>
Date: Thu Apr 12, 2007 3:57 pm
Subject: Re: Large Scale Domain Structure
greggirwin143
Send Email Send Email
 
Hi Bill,

b> Consider the following proposed high level domain structure for a
b> company that provides asset based tax services.

I don't know anything about that domain, so I can't speak to how well
that domain structure might work. My general comment(s) would be to:

1) Consider the workflow of each item. That doesn't mean using a
    workflow toolkit, per se, but lay out at least a basic FSM for
    items that "move through the system"--where they start, what
    changes their state, and where they end. This may give you ideas of
    how the interface could work as well. I'm a big fan of low-tech
    message-based systems.

2) Sketch out multiple high-level structures--at least three--and see
    how they look as STDs, ERDs, CRC cards, etc. Sometimes a specific
    "language" will work better than others in a given situation, to
    let you see what you need to see in the data.

    The main point of doing more than one is to brainstorm and look for
    links and meta info that might otherwise be missed. In a way, it's
    also covering your bases and just general diligence. When someone
    asks me about a design I chose, criticizes it when an unforeseen
    change is hard to implement, or says "why didn't you do it this
    way?", I like to be able to say "I thought about it, and here's why
    I did what I did"; or "we planned for X and Y, but Z never even
    came up before. This other design would allow Z, but won't work
    well for Y...is Y still something we want to do?".

--Gregg


()  ASCII Ribbon Campaign
/\    - Against HTML Mail

#5253 From: "Joe A. Reddy" <jreddy@...>
Date: Thu Apr 12, 2007 4:08 pm
Subject: RE: When to use Whole Value
joethebigshmoe
Send Email Send Email
 

Practically speaking I think I follow the ol’ I’ll do it when I need it rule.

For example, Title is a string until it needs behavior like answering the question “Is Military?”

 

I don’t think it is black and white. Doing it all the time could sure be overkill and a pain, especially in the more unstable early iterations of your application. However, it is a real shame if we ignore the benefits, or are just ignorant of those benefits, or are ignorant of recognizing a situation that could benefit from this design.

 

-Joe

 

 

 

-----Original Message-----
From: domaindrivendesign@yahoogroups.com [mailto:domaindrivendesign@yahoogroups.com] On Behalf Of jupitermoon_beam
Sent: Thursday, April 12, 2007 10:40 AM
To: domaindrivendesign@yahoogroups.com
Subject: [domaindrivendesign] When to use Whole Value

 

I love the whole value pattern and try and use it where I can (plug:
http://jupitermoonbeam.blogspot.com/2007/04/whole-values.html).

My question is how far should the exercise of Whole Value go? Objects
like PostCode or TelephoneNumber are obvious but what about the
simpler things like Title, Surname or Forename?

On the surface is looks like Title, Surname and Forename can exist
happily as strings but you often find that you're soon adding
Surname.IsDoubleBarelled or Title.IsMilitary or Forename.IsSimilarTo
(a real method I've seen for matching duplicate customers e.g. Geoff
and Jeff).

My question is how aggresively do people use the Whole Value pattern
in their domains? On one side of the corner is the argument that any
concept should be abstracted and encapsulated on the other side is are
you wasting your time?


#5255 From: "colin.jack" <colin.jack@...>
Date: Thu Apr 12, 2007 7:00 pm
Subject: Re: When aggregates become too heavy.
colin.jack
Send Email Send Email
 
I disagree completely.

Sure we don't want the business rules scattered throughout the domain
code but that doesn't mean we have to move them out of the domain, we
just need to redistribute them within the domain.

I just don't think the solution to one object becoming heavyweight is
to move code to another layer. Thats not what our layers are there
for. Also if we did this and we're looking for a domain rule then
we're going to be somewhat confused, do I look in the application
layer (if so for which application).

To me this also isn't a reason for a generic subdomain, its a
specific rule related to payment methods so it should sit in the
domain close to the associated class.


--- In domaindrivendesign@yahoogroups.com, "billhamaker"
<BillHamaker@...> wrote:
>
> It seems to me that one problem with putting this code in the
> customer is that it is not very clear what the customer object
> should do if the maximum payment business method is violated.
> Throw an exception?   Return an error code or error message?
>
> Another problem is that this design leaves all the business rules
> scattered through out the code in the various domain logic.   So if
> you are trying to figure out what the business rules are or need to
> change them you are going to have to do a lot of detective work.
>
> This makes we wonder if this logic might instead belong the
> application layer and not the domain layer.   You might for have an
> application objects which can be asked whether it is valid to add a
> payment in a particular situation.
>
> So I think my answer to your question would be that if the
aggregate
> class logic is getting too "heavy" I would tend to move it out of
> the domain and into the application layer.   If the application
gets
> to heavy I might create a generic domain to lighten it (e.g. create
> a generic business rule domain).
>
> Bill Hamaker
>
>
>
> --- In domaindrivendesign@yahoogroups.com, "jupitermoon_beam"
> <jupitermoonbeam@> wrote:
> >
> > Maybe a specific example may help and then people could give
> specific
> > answers to the problem.
> >
> > I will draw a domain around the traditional Customers and Orders
> scenario.
> >
> > In this web based business ordering system we have a central
> > Customer.  The Customer has the following concepts: Orders,
> Accounts,
> > Buyers and Payment Methods.
> >
> > Each of those concepts have specific rules specific rules around
> the
> > Customer:
> > * The number of payment methods (i.e. a credit card) allowed on a
> > customer is directly related to the number of accounts a customer
> has.
> > * A payment method can pay money off any account the customer has.
> > * A payment method can only belong to one Customer.
> > * The number of Accounts a Customer can have depends on the type
of
> > Customer.
> > * An order can only be placed on a Customer if all the accounts
> are in
> > good order.
> > * Approved buyers can be enabled/disabled on a customer.
> > * Buyers cannot belong to more than x number of customers (for
> > security reasons).
> >
> > This is actually a simplification of the real domain I am talking
> > about becoming heavy (there are even more concepts such as contact
> > histories etc.).
> >
> > The issue is a lot of this logic requires that the Customer
> aggregate
> > executes some business logic whether it is Customer.AddOrder to
> > Customer.AddBuyer to Customer.AddPaymentMethod.  The core domain
is
> > about placing orders not about making payments (that's a sub
> module)
> > or managing buyers (again a sub module).  But because there are
> rules
> > specific to the Customer the Customer needs to know about them.
> >
> > For example I tried to seperate out Payment Methods but the logic
> to
> > register a payment method is something like:
> > if(this.PaymentMethods.Count <
> this.MaxNumberOfPaymentMethodsAllowed)
> > {
> >  PaymentMethods.Add(PaymentMethod);
> > }
> >
> > I can't think of a way of ripping that out of the Customer wihtout
> > making it a service which seems silly because it works well in an
> > aggregate it's just the aggregate is getting too heavy.
> >
> > I eagerly await feedback.
> >
> >
>

#5258 From: "colin.jack" <colin.jack@...>
Date: Thu Apr 12, 2007 7:35 pm
Subject: Re: When aggregates become too heavy.
colin.jack
Send Email Send Email
 
I'm assuming CustomerPaymentMethods is in the Customer aggregate? If
so moving rules into it is quite different to putting it in its own
aggregate (in my mind at least).

I just think the logical place for the rules is inside
CustomerPaymentMethods. I'd just move the rules to
CustomerPaymentMethods and call them from the Customer.

Not sure about a value object becoming an entity, that sounds odd and
when you say the approach about injecting the Customer is frowned
upon, do you just mean from a coupling perspective?

If so I accept that we want to decouple classes where possible but
coupling/cohesion are just two of quite a few factors I'd consider
and for me this sort of coupling isn't the end of the world. Sure its
bidirectional coupling but they're part of the same aggregate so it
isn't likely to be an issue. You can never access the
CustomerPaymentMethods except from the Customer and the Customer can
be involved in the creation of the CustomerPaymentMethods collection
so I don't see it as a big issue (though I may have missed something).


--- In domaindrivendesign@yahoogroups.com, "jupitermoon_beam"
<jupitermoonbeam@...> wrote:
>
> > I'm no expert but I'd start have thought the obvious place for
that
> > logic is PaymentMethods itself
>
> That's kinda what I was thinking with the CustomerOrders class in my
> previous post.  In effect there would be a CustomerPaymentMethods
class.
>
> > You don't say where "PaymentMethod" is coming from, is it being
> > created just before the lines of code you show? If so can the
> > PaymentMethods collection create and add the new PaymentMethod?
>
> In this particular domain PaymentMethod gets tricky because
everytime
> a succesful payment is made it (i.e. a Credit Card transaction is
> approved) it moves from a value object and becomes an entity.  It is
> then added to the list and if full the least used payment method is
> dropped from the list (sorry I did omit that but for simplicities
> sake).  So the simple answer is that yes the PaymentMethod is can be
> created and added at the same time from the service.
>
> >  if(this.PaymentMethods.IsFull == false)
> The only niggle is that the answer to IsFull lies with the number of
> Accounts the Customer has.  There are only two ways I can think of
> solving this:
> * Inject Customer into the customer collection
(CustomerPaymentMethods)
> * speak directly to a repository (and here we are again with the
whole
> repository argument).
>
> The truth is both solutions are slightly frowned upon (without
getting
> another argument going).  Having a Greedy Aggregate meant staying
> within the "rules" so is there another way or is it a case of the
> lesser of evils (in which case I'd go with the custom
> collection/middle object)?
>
> --- In domaindrivendesign@yahoogroups.com, "colin.jack"
> <colin.jack@> wrote:
> >
> > I'm no expert but I'd start have thought the obvious place for
that
> > logic is PaymentMethods itself (ignore the naming and so on, but
you
> > can see what I mean):
> >
> >  if(this.PaymentMethods.IsFull == false)
> >  {
> >    this.PaymentMethods.Add(paymentMethod);
> >  }
> >
> > ..or maybe..
> >
> >  this.PaymentMethods.AddIfNotFull(paymentMethod);
> >
> > Obviously this only works if PaymentMethods is a custom
collection
> > but I often find this is needed anyway.
> >
> > You don't say where "PaymentMethod" is coming from, is it being
> > created just before the lines of code you show? If so can the
> > PaymentMethods collection create and add the new PaymentMethod?
> >
> > --- In domaindrivendesign@yahoogroups.com, "jupitermoon_beam"
> > <jupitermoonbeam@> wrote:
> > >
> > > Maybe a specific example may help and then people could give
> > specific
> > > answers to the problem.
> > >
> > > I will draw a domain around the traditional Customers and
Orders
> > scenario.
> > >
> > > In this web based business ordering system we have a central
> > > Customer.  The Customer has the following concepts: Orders,
> > Accounts,
> > > Buyers and Payment Methods.
> > >
> > > Each of those concepts have specific rules specific rules
around the
> > > Customer:
> > > * The number of payment methods (i.e. a credit card) allowed on
a
> > > customer is directly related to the number of accounts a
customer
> > has.
> > > * A payment method can pay money off any account the customer
has.
> > > * A payment method can only belong to one Customer.
> > > * The number of Accounts a Customer can have depends on the
type of
> > > Customer.
> > > * An order can only be placed on a Customer if all the accounts
are
> > in
> > > good order.
> > > * Approved buyers can be enabled/disabled on a customer.
> > > * Buyers cannot belong to more than x number of customers (for
> > > security reasons).
> > >
> > > This is actually a simplification of the real domain I am
talking
> > > about becoming heavy (there are even more concepts such as
contact
> > > histories etc.).
> > >
> > > The issue is a lot of this logic requires that the Customer
> > aggregate
> > > executes some business logic whether it is Customer.AddOrder to
> > > Customer.AddBuyer to Customer.AddPaymentMethod.  The core
domain is
> > > about placing orders not about making payments (that's a sub
module)
> > > or managing buyers (again a sub module).  But because there are
> > rules
> > > specific to the Customer the Customer needs to know about them.
> > >
> > > For example I tried to seperate out Payment Methods but the
logic to
> > > register a payment method is something like:
> > > if(this.PaymentMethods.Count <
> > this.MaxNumberOfPaymentMethodsAllowed)
> > > {
> > >  PaymentMethods.Add(PaymentMethod);
> > > }
> > >
> > > I can't think of a way of ripping that out of the Customer
wihtout
> > > making it a service which seems silly because it works well in
an
> > > aggregate it's just the aggregate is getting too heavy.
> > >
> > > I eagerly await feedback.
> > >
> > > --- In domaindrivendesign@yahoogroups.com, "colin.jack"
> > > <colin.jack@> wrote:
> > > >
> > > > That might be one way to split it, I definitely would try to
keep
> > my
> > > > Customer lightweight but I'm not sure if moving Orders off is
the
> > > > correct way to do that. Surely the most important thing about
a
> > > > Customer is that they make Orders? Thats what differentiates
them
> > > > from any other person that the model deals with (if the model
> > deals
> > > > with other people).
> > > >
> > > > I'd maybe consider breaking it a different way. For example
if
> > you
> > > > have a lot of personal information on Client then move that
into
> > > > another hierarchy (Party) and have the Customer be a role
that a
> > > > Party can be in (see Arlow for examples of this).
> > > >
> > > > In any case though if you do move the rules into
CustomerOrders
> > then
> > > > surely Customer can still reference CustomerOrders, thats
just
> > one
> > > > aggregate root referencing another. I certainly wouldn't keep
> > Order
> > > > specific rules in Customer but I also wouldn't decouple
Customer
> > and
> > > > Order unless I had other reasons for doing it, especially if
most
> > > > users of the Customer class are going to be accessing the
Orders
> > > > collection.
> > > >
> > > > Thats my 2cents anyway.
> > > >
> > > > --- In domaindrivendesign@yahoogroups.com, "jupitermoon_beam"
> > > > <jupitermoonbeam@> wrote:
> > > > >
> > > > > I think Patrick's post is where my thinking was going (I
will
> > try
> > > > and
> > > > > confirm if I've got it right).
> > > > >
> > > > > It was the subject of Eric's post that was starting to
concern
> > me
> > > > > about these Greedy Aggregates.  To take Eric's and Bert's
posts
> > are
> > > > we
> > > > > saying the the greedy aggregate
> > > > > has concepts in it that can be split into more specific sub
> > > > aggregates
> > > > > (like the facets)?  In effect the aggregate needs to be
> > inverted.
> > > > >
> > > > > For example rather than having a Customer holding all the
rules
> > for
> > > > > managing Orders on itself have a CustomerOrders aggregate
which
> > > > deals
> > > > > with the Customer as an entity (using Partick's example the
> > Customer
> > > > > becomes the key to retrieving the CustomerOrders
aggregate).
> > Then
> > > > to
> > > > > deal with a customer's orders you can deal with the
> > CustomerOrders
> > > > > aggregate directly without having to deal with the rest of
the
> > > > > Customer.  It also means that the Customer can become
> > modularised.
> > > > >
> > > > > Does this risk making the Customer aneamic? I guess if the
> > focus of
> > > > > the surgery is around preserving the core domain then the
risk
> > > > should
> > > > > be contained.
> > > > >
> > > > > Also I've often found that we miss concepts in modelling
that
> > hide
> > > > > within the Ubiqutous Language and need pulling out (Eric's
book
> > is
> > > > > littered with examples).  For example in a system that
tracks
> > Car's
> > > > > and their Owners (such as the British Road Tax system)
people
> > often
> > > > > link Car directly to Owner but there is a concept of
> > registration
> > > > > whereby the Owner registers the Car with the system.  This
> > > > > Registration often has it's own rules and data which live
> > outside
> > > > both
> > > > > the Car and Owner and you often see people struggling with
the
> > model
> > > > > because they haven't stumbled across the word "register" in
the
> > > > > language.  Basically maybe a lot of these concepts
are 'hidden'
> > even
> > > > > further (such as CustomerOrders).
> > > > >
> > > > > Am I going in the right direction here?
> > > > >
> > > > > --- In domaindrivendesign@yahoogroups.com, Patrick Bohan
> > > > > <patbohan@> wrote:
> > > > > >
> > > > > > I've dealt with what sounds like a similar problem.
> > > > > >
> > > > > > At a previous job we had an application that performed
> > various
> > > > types of
> > > > > > batch processing on a very large components. By large I
mean
> > both
> > > > > memory
> > > > > > intensive (usually between 10 and 200 Mbs) and
conceptually
> > large
> > > > (lots
> > > > > > of little and not-so-little pieces.) The components were
all
> > > > related
> > > > > but
> > > > > > when and where we needed different parts was not common.
(In
> > one
> > > > > area of
> > > > > > the system we needed parts A and B, in another B and C,
and a
> > > > third A,
> > > > > > B, and C).
> > > > > >
> > > > > > To manage this we did not create one monster object, we
> > created a
> > > > tiny
> > > > > > core token object that contained the bare necessities and
a
> > suite
> > > > of
> > > > > > objects to cover of the other major parts. (We dubbed
these
> > other
> > > > parts
> > > > > > "facets", as in the facets or sides of a jewel. All the
> > facets
> > > > together
> > > > > > make the complete jewel, but most of the time you are
only
> > > > looking at
> > > > > > the few that you can see.)
> > > > > >
> > > > > > In practice what we always had a reference to the core
> > object. It
> > > > > was an
> > > > > > immutable light weight object that everything in the
system
> > > > recognized.
> > > > > > (For us it was limited to an ID number, type, and
> > description.)
> > > > The
> > > > > core
> > > > > > object by itself was useless except in one regard: we
could
> > use
> > > > it to
> > > > > > get the other, useful parts. We would supply the
particular
> > > > Repository
> > > > > > that housed the type of parts we cared about this core
> > object,
> > > > and we'd
> > > > > > get our part.
> > > > > >
> > > > > > We never created a direct reference from the core object
to
> > any
> > > > of the
> > > > > > parts. We deferred that activity to the areas that needed
the
> > > > parts. If
> > > > > > an area needed a container class to hold the core object
and
> > > > several
> > > > > > parts they would build one as needed.
> > > > > >
> > > > > > I don't know the domain of your problem, but we were only
> > able to
> > > > (and
> > > > > > required to) achieve this splitting due to the nature of
our
> > > > > problem: we
> > > > > > often only needed only one or two parts and we never
needed
> > all
> > > > the
> > > > > parts.
> > > > > >
> > > > > > Patrick
> > > > > > ARKBAN
> > > > > >
> > > > > > Dru Sellers wrote:
> > > > > > > I have this exact same problem but hadn't put words to
it.
> > The
> > > > greedy
> > > > > > > aggregate is indeed something that feels bad, but is
it? I
> > look
> > > > > forward
> > > > > > > to the comments from everyone on this. -d
> > > > > > >
> > > > > > > On 4/10/07, *jupitermoon_beam* <jupitermoonbeam@
> > > > > > > <mailto:jupitermoonbeam@>> wrote:
> > > > > > >
> > > > > > >     Although in the DDD book there are many concpets
about
> > > > > modularizing
> > > > > > >     the domain itself I am often faced with tackling
heavy
> > > > entities.
> > > > > > >
> > > > > > >     In many domains there is a single core aggregate
(much
> > of
> > > > the time
> > > > > > >     Customer) and a large amount of the logic and
concepts
> > in
> > > > the
> > > > > domain
> > > > > > >     hang off of this one aggregate. The result is a
rather
> > heavy
> > > > > > >     aggregate which contains a lot of concepts.
> > > > > > >
> > > > > > >     Because the aggregate owns a lot of the domains
> > concepts it
> > > > is
> > > > > really
> > > > > > >     difficult to split it. A lot of the concepts exist
> > outside
> > > > of the
> > > > > > >     core domain but the domain naturally centralizes
itself
> > > > around
> > > > > this
> > > > > > >     one object.
> > > > > > >
> > > > > > >     Sometimes I find I can splinter the logic off into
> > services
> > > > or
> > > > > turn
> > > > > > >     simple lists (such as contact histories etc.) into
> > > > aggregrates and
> > > > > > >     give them their own repositories but sometimes
there
> > can be
> > > > a
> > > > > lot of
> > > > > > >     domain logic that the central aggregate naturally
owns.
> > > > > > >
> > > > > > >     How do people deal with these heavy aggregates?
What
> > tricks
> > > > can be
> > > > > > >     used to break our greedy aggregates down into
smaller
> > > > managebal
> > > > > > >     entities?
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > > --
> > > > > > > cheers,
> > > > > > > -d
> > > > > >
> > > > >
> > > >
> > >
> >
>

#5259 From: "jupitermoon_beam" <jupitermoonbeam@...>
Date: Fri Apr 13, 2007 8:34 am
Subject: Re: When aggregates become too heavy.
jupitermoon_...
Send Email Send Email
 
> I'm assuming CustomerPaymentMethods is in the Customer aggregate? If
> so moving rules into it is quite different to putting it in its own
> aggregate (in my mind at least).

Yes.  Strangely the CustomerPaymentMethods isn't obviosuly Aggregate,
Entity or Value as it just holds and maintains rules and data on
behalf of Customer.  I suppose strictly it could be described as an
Entity using the Customer as it's Id.

> Not sure about a value object becoming an entity, that sounds odd

I didn't explain very well.  I often find parts of the domain have
concepts that start of as a Value and move to an Entity within
transactions.  In this example when someone enters the payment details
initially it is a Value object which is used solely for initiating a
request for payment (I call these Token Value objects).  If the
request is succesful (what constitutes a
succesful payment is a domain rule) then the Value object can be
passed to the PaymentMethodFactory to create the PaymentMethod Entity
(in effect 'cashing' in the token) which is then stored.  The details
from unsuccesful payments have no
concept in the domain as an entity and stay as value objects as part
of an audit history.

> when you say the approach about injecting the Customer is frowned
> upon, do you just mean from a coupling perspective?

From a coupling and a bi-directional association though I go with the
rest of your argument that it is cohesive.

By the way thanks for your help Colin: this issue had really been
bugging me and although I felt this may be the way having some
feedback gives a lot of confidence (which is why I love this message
group).

--- In domaindrivendesign@yahoogroups.com, "colin.jack"
<colin.jack@...> wrote:
>
> I'm assuming CustomerPaymentMethods is in the Customer aggregate? If
> so moving rules into it is quite different to putting it in its own
> aggregate (in my mind at least).
>
> I just think the logical place for the rules is inside
> CustomerPaymentMethods. I'd just move the rules to
> CustomerPaymentMethods and call them from the Customer.
>
> Not sure about a value object becoming an entity, that sounds odd and
> when you say the approach about injecting the Customer is frowned
> upon, do you just mean from a coupling perspective?
>
> If so I accept that we want to decouple classes where possible but
> coupling/cohesion are just two of quite a few factors I'd consider
> and for me this sort of coupling isn't the end of the world. Sure its
> bidirectional coupling but they're part of the same aggregate so it
> isn't likely to be an issue. You can never access the
> CustomerPaymentMethods except from the Customer and the Customer can
> be involved in the creation of the CustomerPaymentMethods collection
> so I don't see it as a big issue (though I may have missed something).
>
>
> --- In domaindrivendesign@yahoogroups.com, "jupitermoon_beam"
> <jupitermoonbeam@> wrote:
> >
> > > I'm no expert but I'd start have thought the obvious place for
> that
> > > logic is PaymentMethods itself
> >
> > That's kinda what I was thinking with the CustomerOrders class in my
> > previous post.  In effect there would be a CustomerPaymentMethods
> class.
> >
> > > You don't say where "PaymentMethod" is coming from, is it being
> > > created just before the lines of code you show? If so can the
> > > PaymentMethods collection create and add the new PaymentMethod?
> >
> > In this particular domain PaymentMethod gets tricky because
> everytime
> > a succesful payment is made it (i.e. a Credit Card transaction is
> > approved) it moves from a value object and becomes an entity.  It is
> > then added to the list and if full the least used payment method is
> > dropped from the list (sorry I did omit that but for simplicities
> > sake).  So the simple answer is that yes the PaymentMethod is can be
> > created and added at the same time from the service.
> >
> > >  if(this.PaymentMethods.IsFull == false)
> > The only niggle is that the answer to IsFull lies with the number of
> > Accounts the Customer has.  There are only two ways I can think of
> > solving this:
> > * Inject Customer into the customer collection
> (CustomerPaymentMethods)
> > * speak directly to a repository (and here we are again with the
> whole
> > repository argument).
> >
> > The truth is both solutions are slightly frowned upon (without
> getting
> > another argument going).  Having a Greedy Aggregate meant staying
> > within the "rules" so is there another way or is it a case of the
> > lesser of evils (in which case I'd go with the custom
> > collection/middle object)?
> >
> > --- In domaindrivendesign@yahoogroups.com, "colin.jack"
> > <colin.jack@> wrote:
> > >
> > > I'm no expert but I'd start have thought the obvious place for
> that
> > > logic is PaymentMethods itself (ignore the naming and so on, but
> you
> > > can see what I mean):
> > >
> > >  if(this.PaymentMethods.IsFull == false)
> > >  {
> > >    this.PaymentMethods.Add(paymentMethod);
> > >  }
> > >
> > > ..or maybe..
> > >
> > >  this.PaymentMethods.AddIfNotFull(paymentMethod);
> > >
> > > Obviously this only works if PaymentMethods is a custom
> collection
> > > but I often find this is needed anyway.
> > >
> > > You don't say where "PaymentMethod" is coming from, is it being
> > > created just before the lines of code you show? If so can the
> > > PaymentMethods collection create and add the new PaymentMethod?
> > >
> > > --- In domaindrivendesign@yahoogroups.com, "jupitermoon_beam"
> > > <jupitermoonbeam@> wrote:
> > > >
> > > > Maybe a specific example may help and then people could give
> > > specific
> > > > answers to the problem.
> > > >
> > > > I will draw a domain around the traditional Customers and
> Orders
> > > scenario.
> > > >
> > > > In this web based business ordering system we have a central
> > > > Customer.  The Customer has the following concepts: Orders,
> > > Accounts,
> > > > Buyers and Payment Methods.
> > > >
> > > > Each of those concepts have specific rules specific rules
> around the
> > > > Customer:
> > > > * The number of payment methods (i.e. a credit card) allowed on
> a
> > > > customer is directly related to the number of accounts a
> customer
> > > has.
> > > > * A payment method can pay money off any account the customer
> has.
> > > > * A payment method can only belong to one Customer.
> > > > * The number of Accounts a Customer can have depends on the
> type of
> > > > Customer.
> > > > * An order can only be placed on a Customer if all the accounts
> are
> > > in
> > > > good order.
> > > > * Approved buyers can be enabled/disabled on a customer.
> > > > * Buyers cannot belong to more than x number of customers (for
> > > > security reasons).
> > > >
> > > > This is actually a simplification of the real domain I am
> talking
> > > > about becoming heavy (there are even more concepts such as
> contact
> > > > histories etc.).
> > > >
> > > > The issue is a lot of this logic requires that the Customer
> > > aggregate
> > > > executes some business logic whether it is Customer.AddOrder to
> > > > Customer.AddBuyer to Customer.AddPaymentMethod.  The core
> domain is
> > > > about placing orders not about making payments (that's a sub
> module)
> > > > or managing buyers (again a sub module).  But because there are
> > > rules
> > > > specific to the Customer the Customer needs to know about them.
> > > >
> > > > For example I tried to seperate out Payment Methods but the
> logic to
> > > > register a payment method is something like:
> > > > if(this.PaymentMethods.Count <
> > > this.MaxNumberOfPaymentMethodsAllowed)
> > > > {
> > > >  PaymentMethods.Add(PaymentMethod);
> > > > }
> > > >
> > > > I can't think of a way of ripping that out of the Customer
> wihtout
> > > > making it a service which seems silly because it works well in
> an
> > > > aggregate it's just the aggregate is getting too heavy.
> > > >
> > > > I eagerly await feedback.
> > > >
> > > > --- In domaindrivendesign@yahoogroups.com, "colin.jack"
> > > > <colin.jack@> wrote:
> > > > >
> > > > > That might be one way to split it, I definitely would try to
> keep
> > > my
> > > > > Customer lightweight but I'm not sure if moving Orders off is
> the
> > > > > correct way to do that. Surely the most important thing about
> a
> > > > > Customer is that they make Orders? Thats what differentiates
> them
> > > > > from any other person that the model deals with (if the model
> > > deals
> > > > > with other people).
> > > > >
> > > > > I'd maybe consider breaking it a different way. For example
> if
> > > you
> > > > > have a lot of personal information on Client then move that
> into
> > > > > another hierarchy (Party) and have the Customer be a role
> that a
> > > > > Party can be in (see Arlow for examples of this).
> > > > >
> > > > > In any case though if you do move the rules into
> CustomerOrders
> > > then
> > > > > surely Customer can still reference CustomerOrders, thats
> just
> > > one
> > > > > aggregate root referencing another. I certainly wouldn't keep
> > > Order
> > > > > specific rules in Customer but I also wouldn't decouple
> Customer
> > > and
> > > > > Order unless I had other reasons for doing it, especially if
> most
> > > > > users of the Customer class are going to be accessing the
> Orders
> > > > > collection.
> > > > >
> > > > > Thats my 2cents anyway.
> > > > >
> > > > > --- In domaindrivendesign@yahoogroups.com, "jupitermoon_beam"
> > > > > <jupitermoonbeam@> wrote:
> > > > > >
> > > > > > I think Patrick's post is where my thinking was going (I
> will
> > > try
> > > > > and
> > > > > > confirm if I've got it right).
> > > > > >
> > > > > > It was the subject of Eric's post that was starting to
> concern
> > > me
> > > > > > about these Greedy Aggregates.  To take Eric's and Bert's
> posts
> > > are
> > > > > we
> > > > > > saying the the greedy aggregate
> > > > > > has concepts in it that can be split into more specific sub
> > > > > aggregates
> > > > > > (like the facets)?  In effect the aggregate needs to be
> > > inverted.
> > > > > >
> > > > > > For example rather than having a Customer holding all the
> rules
> > > for
> > > > > > managing Orders on itself have a CustomerOrders aggregate
> which
> > > > > deals
> > > > > > with the Customer as an entity (using Partick's example the
> > > Customer
> > > > > > becomes the key to retrieving the CustomerOrders
> aggregate).
> > > Then
> > > > > to
> > > > > > deal with a customer's orders you can deal with the
> > > CustomerOrders
> > > > > > aggregate directly without having to deal with the rest of
> the
> > > > > > Customer.  It also means that the Customer can become
> > > modularised.
> > > > > >
> > > > > > Does this risk making the Customer aneamic? I guess if the
> > > focus of
> > > > > > the surgery is around preserving the core domain then the
> risk
> > > > > should
> > > > > > be contained.
> > > > > >
> > > > > > Also I've often found that we miss concepts in modelling
> that
> > > hide
> > > > > > within the Ubiqutous Language and need pulling out (Eric's
> book
> > > is
> > > > > > littered with examples).  For example in a system that
> tracks
> > > Car's
> > > > > > and their Owners (such as the British Road Tax system)
> people
> > > often
> > > > > > link Car directly to Owner but there is a concept of
> > > registration
> > > > > > whereby the Owner registers the Car with the system.  This
> > > > > > Registration often has it's own rules and data which live
> > > outside
> > > > > both
> > > > > > the Car and Owner and you often see people struggling with
> the
> > > model
> > > > > > because they haven't stumbled across the word "register" in
> the
> > > > > > language.  Basically maybe a lot of these concepts
> are 'hidden'
> > > even
> > > > > > further (such as CustomerOrders).
> > > > > >
> > > > > > Am I going in the right direction here?
> > > > > >
> > > > > > --- In domaindrivendesign@yahoogroups.com, Patrick Bohan
> > > > > > <patbohan@> wrote:
> > > > > > >
> > > > > > > I've dealt with what sounds like a similar problem.
> > > > > > >
> > > > > > > At a previous job we had an application that performed
> > > various
> > > > > types of
> > > > > > > batch processing on a very large components. By large I
> mean
> > > both
> > > > > > memory
> > > > > > > intensive (usually between 10 and 200 Mbs) and
> conceptually
> > > large
> > > > > (lots
> > > > > > > of little and not-so-little pieces.) The components were
> all
> > > > > related
> > > > > > but
> > > > > > > when and where we needed different parts was not common.
> (In
> > > one
> > > > > > area of
> > > > > > > the system we needed parts A and B, in another B and C,
> and a
> > > > > third A,
> > > > > > > B, and C).
> > > > > > >
> > > > > > > To manage this we did not create one monster object, we
> > > created a
> > > > > tiny
> > > > > > > core token object that contained the bare necessities and
> a
> > > suite
> > > > > of
> > > > > > > objects to cover of the other major parts. (We dubbed
> these
> > > other
> > > > > parts
> > > > > > > "facets", as in the facets or sides of a jewel. All the
> > > facets
> > > > > together
> > > > > > > make the complete jewel, but most of the time you are
> only
> > > > > looking at
> > > > > > > the few that you can see.)
> > > > > > >
> > > > > > > In practice what we always had a reference to the core
> > > object. It
> > > > > > was an
> > > > > > > immutable light weight object that everything in the
> system
> > > > > recognized.
> > > > > > > (For us it was limited to an ID number, type, and
> > > description.)
> > > > > The
> > > > > > core
> > > > > > > object by itself was useless except in one regard: we
> could
> > > use
> > > > > it to
> > > > > > > get the other, useful parts. We would supply the
> particular
> > > > > Repository
> > > > > > > that housed the type of parts we cared about this core
> > > object,
> > > > > and we'd
> > > > > > > get our part.
> > > > > > >
> > > > > > > We never created a direct reference from the core object
> to
> > > any
> > > > > of the
> > > > > > > parts. We deferred that activity to the areas that needed
> the
> > > > > parts. If
> > > > > > > an area needed a container class to hold the core object
> and
> > > > > several
> > > > > > > parts they would build one as needed.
> > > > > > >
> > > > > > > I don't know the domain of your problem, but we were only
> > > able to
> > > > > (and
> > > > > > > required to) achieve this splitting due to the nature of
> our
> > > > > > problem: we
> > > > > > > often only needed only one or two parts and we never
> needed
> > > all
> > > > > the
> > > > > > parts.
> > > > > > >
> > > > > > > Patrick
> > > > > > > ARKBAN
> > > > > > >
> > > > > > > Dru Sellers wrote:
> > > > > > > > I have this exact same problem but hadn't put words to
> it.
> > > The
> > > > > greedy
> > > > > > > > aggregate is indeed something that feels bad, but is
> it? I
> > > look
> > > > > > forward
> > > > > > > > to the comments from everyone on this. -d
> > > > > > > >
> > > > > > > > On 4/10/07, *jupitermoon_beam* <jupitermoonbeam@
> > > > > > > > <mailto:jupitermoonbeam@>> wrote:
> > > > > > > >
> > > > > > > >     Although in the DDD book there are many concpets
> about
> > > > > > modularizing
> > > > > > > >     the domain itself I am often faced with tackling
> heavy
> > > > > entities.
> > > > > > > >
> > > > > > > >     In many domains there is a single core aggregate
> (much
> > > of
> > > > > the time
> > > > > > > >     Customer) and a large amount of the logic and
> concepts
> > > in
> > > > > the
> > > > > > domain
> > > > > > > >     hang off of this one aggregate. The result is a
> rather
> > > heavy
> > > > > > > >     aggregate which contains a lot of concepts.
> > > > > > > >
> > > > > > > >     Because the aggregate owns a lot of the domains
> > > concepts it
> > > > > is
> > > > > > really
> > > > > > > >     difficult to split it. A lot of the concepts exist
> > > outside
> > > > > of the
> > > > > > > >     core domain but the domain naturally centralizes
> itself
> > > > > around
> > > > > > this
> > > > > > > >     one object.
> > > > > > > >
> > > > > > > >     Sometimes I find I can splinter the logic off into
> > > services
> > > > > or
> > > > > > turn
> > > > > > > >     simple lists (such as contact histories etc.) into
> > > > > aggregrates and
> > > > > > > >     give them their own repositories but sometimes
> there
> > > can be
> > > > > a
> > > > > > lot of
> > > > > > > >     domain logic that the central aggregate naturally
> owns.
> > > > > > > >
> > > > > > > >     How do people deal with these heavy aggregates?
> What
> > > tricks
> > > > > can be
> > > > > > > >     used to break our greedy aggregates down into
> smaller
> > > > > managebal
> > > > > > > >     entities?
> > > > > > > >
> > > > > > > >
> > > > > > > >
> > > > > > > >
> > > > > > > > --
> > > > > > > > cheers,
> > > > > > > > -d
> > > > > > >
> > > > > >
> > > > >
> > > >
> > >
> >
>

#5260 From: "jupitermoon_beam" <jupitermoonbeam@...>
Date: Fri Apr 13, 2007 9:14 am
Subject: Re: When to use Whole Value
jupitermoon_...
Send Email Send Email
 
> Practically speaking I think I follow the ol' I'll do it when I need
it rule.

YAGNI is certainly where I try to stand on this but what's interesting
is I find that over time most concepts very easily end up as Whole
Values.  Also I think YAGNI can be a bit grey here because this can be
  more about good vs bad practice.

> Doing it all the time could sure be overkill and a pain

Interestingly the reason it is a pain isn't to do with the concept
being a bad practice.  It would be very hard to argue why a domain
concept (such as forename) shouldn't become a Whole Value apart from
the fact there is a programming overhead (I'm sure someone passionate
enough could give many very sound reasons).  If languages made it as
easy to create Whole Values as creating Classes then we wouldn't be
worried about overkill.  Personally I use code generation solutions to
create the WVs meaning the overhead in creation is quite low (though
not as low as typing string).  Doing it early can sometimes reduce
maintanance as refactoring Name from a string can mean going through
and replacing a lot of the basic string validation code through the
domain.

> recognizing a situation that could benefit from this design.

Things like PostCode and TelephoneNumber are obvious because they do
have composite parts which make a whole (they aren't just strings).
Things like names are tricky but even then as a domain progresses
concepts (especially validation and cleaning) sneak in and the best
place for them is within the WV.

As I said above that the only critisism of being too purist with WV is
that you may just be creating extra work for yourself but it isn't a
"bad thing" and in some respects is more OOP (imagine how nice it
would be working in a domain with 100% of all concepts modelled into
objects).

By the way I'm just playing devil's advocate here I'm not nessasarily
arguing that every concept should be an object (for the reasons
already given) I'm just interested to find out if overhead is the only
reason and if there are any specific technical reasons why it could be
a "bad thing".

--- In domaindrivendesign@yahoogroups.com, "Joe A. Reddy" <jreddy@...>
wrote:
>
> Practically speaking I think I follow the ol' I'll do it when I need it
> rule.
>
> For example, Title is a string until it needs behavior like answering
> the question "Is Military?"
>
>
>
> I don't think it is black and white. Doing it all the time could sure be
> overkill and a pain, especially in the more unstable early iterations of
> your application. However, it is a real shame if we ignore the benefits,
> or are just ignorant of those benefits, or are ignorant of recognizing a
> situation that could benefit from this design.
>
>
>
> -Joe
>
>
>
>
>
>
>
> -----Original Message-----
> From: domaindrivendesign@yahoogroups.com
> [mailto:domaindrivendesign@yahoogroups.com] On Behalf Of
> jupitermoon_beam
> Sent: Thursday, April 12, 2007 10:40 AM
> To: domaindrivendesign@yahoogroups.com
> Subject: [domaindrivendesign] When to use Whole Value
>
>
>
> I love the whole value pattern and try and use it where I can (plug:
> http://jupitermoonbeam.blogspot.com/2007/04/whole-values.html
> <http://jupitermoonbeam.blogspot.com/2007/04/whole-values.html> ).
>
> My question is how far should the exercise of Whole Value go? Objects
> like PostCode or TelephoneNumber are obvious but what about the
> simpler things like Title, Surname or Forename?
>
> On the surface is looks like Title, Surname and Forename can exist
> happily as strings but you often find that you're soon adding
> Surname.IsDoubleBarelled or Title.IsMilitary or Forename.IsSimilarTo
> (a real method I've seen for matching duplicate customers e.g. Geoff
> and Jeff).
>
> My question is how aggresively do people use the Whole Value pattern
> in their domains? On one side of the corner is the argument that any
> concept should be abstracted and encapsulated on the other side is are
> you wasting your time?
>

#5261 From: Juan Bernabó <juan.bernabo@...>
Date: Fri Apr 13, 2007 12:39 pm
Subject: Mixing Coad DNC with DDD
jbernab
Send Email Send Email
 
Hi,

I would like to know if someone is using DDD and Peter Coad UML in
Colors DNC (Domain Neutral Component) archetypes together.

http://www.petercoad.com/download/bookpdfs/jmcuch01.pdf

Personally I think that DNC can add value to the DDD entity concept,
helping us to discover entities that are Moment/Interals,
Party/Place/Things, Descriptions and Roles and follows the DNC
structure, but in practice I had not have the oportunity to use this
in a real project, so I dont really know the details.

I have some questions.

Has someone tried this in practice?
Is there any conflicts betwen the concepts of DDD and Coad DNC?
Is this is adding any value to the domain models?
What are the cons?
What are the pros?

Thanks in advance,
Juan.

#5262 From: "Joe A. Reddy" <jreddy@...>
Date: Fri Apr 13, 2007 2:15 pm
Subject: RE: Re: When to use Whole Value
joethebigshmoe
Send Email Send Email
 

I agree with everything you are saying. Its one of those things that feels like overhead, like overkill and it eats at your gut. But I don’t think you can come up with any strong argument against it. Hell, opening up a code generator and typing “Surname” and “string” then clicking a button is almost more work than just typing out the code yourself. ;-)

 

 

-----Original Message-----
From: domaindrivendesign@yahoogroups.com [mailto:domaindrivendesign@yahoogroups.com] On Behalf Of jupitermoon_beam
Sent:
Friday, April 13, 2007 4:14 AM
To: domaindrivendesign@yahoogroups.com
Subject: [domaindrivendesign] Re: When to use Whole Value

 

> Practically speaking I think I follow the ol' I'll do it when I need
it rule.

YAGNI is certainly where I try to stand on this but what's interesting
is I find that over time most concepts very easily end up as Whole
Values. Also I think YAGNI can be a bit grey here because this can be
more about good vs bad practice.

> Doing it all the time could sure be overkill and a pain

Interestingly the reason it is a pain isn't to do with the concept
being a bad practice. It would be very hard to argue why a domain
concept (such as forename) shouldn't become a Whole Value apart from
the fact there is a programming overhead (I'm sure someone passionate
enough could give many very sound reasons). If languages made it as
easy to create Whole Values as creating Classes then we wouldn't be
worried about overkill. Personally I use code generation solutions to
create the WVs meaning the overhead in creation is quite low (though
not as low as typing string). Doing it early can sometimes reduce
maintanance as refactoring Name from a string can mean going through
and replacing a lot of the basic string validation code through the
domain.

> recognizing a situation that could benefit from this design.

Things like PostCode and TelephoneNumber are obvious because they do
have composite parts which make a whole (they aren't just strings).
Things like names are tricky but even then as a domain progresses
concepts (especially validation and cleaning) sneak in and the best
place for them is within the WV.

As I said above that the only critisism of being too purist with WV is
that you may just be creating extra work for yourself but it isn't a
"bad thing" and in some respects is more OOP (imagine how nice it
would be working in a domain with 100% of all concepts modelled into
objects).

By the way I'm just playing devil's advocate here I'm not nessasarily
arguing that every concept should be an object (for the reasons
already given) I'm just interested to find out if overhead is the only
reason and if there are any specific technical reasons why it could be
a "bad thing".

--- In domaindrivendesign@yahoogroups.com, "Joe A. Reddy" <jreddy@...>
wrote:
>
> Practically speaking I think I follow the ol' I'll do it when I need it
> rule.
>
> For example, Title is a string until it needs behavior like answering
> the question "Is Military?"
>
>
>
> I don't think it is black and white. Doing it all the time could sure be
> overkill and a pain, especially in the more unstable early iterations of
> your application. However, it is a real shame if we ignore the benefits,
> or are just ignorant of those benefits, or are ignorant of recognizing a
> situation that could benefit from this design.
>
>
>
> -Joe
>
>
>
>
>
>
>
> -----Original Message-----
> From: domaindrivendesign@yahoogroups.com
> [mailto:domaindrivendesign@yahoogroups.com] On Behalf Of
> jupitermoon_beam
> Sent: Thursday, April 12, 2007 10:40 AM
> To: domaindrivendesign@yahoogroups.com
> Subject: [domaindrivendesign] When to use Whole Value
>
>
>
> I love the whole value pattern and try and use it where I can (plug:
> http://jupitermoonbeam.blogspot.com/2007/04/whole-values.html
> <http://jupitermoonbeam.blogspot.com/2007/04/whole-values.html> ).
>
> My question is how far should the exercise of Whole Value go? Objects
> like PostCode or TelephoneNumber are obvious but what about the
> simpler things like Title, Surname or Forename?
>
> On the surface is looks like Title, Surname and Forename can exist
> happily as strings but you often find that you're soon adding
> Surname.IsDoubleBarelled or Title.IsMilitary or Forename.IsSimilarTo
> (a real method I've seen for matching duplicate customers e.g. Geoff
> and Jeff).
>
> My question is how aggresively do people use the Whole Value pattern
> in their domains? On one side of the corner is the argument that any
> concept should be abstracted and encapsulated on the other side is are
> you wasting your time?
>


#5263 From: "Chris Gardner" <chris_gardner76@...>
Date: Fri Apr 13, 2007 4:02 pm
Subject: Re: Mixing Coad DNC with DDD
chris_gardner76
Send Email Send Email
 
I think DNC, as is Streamlined Object Modeling, a tool that can help
you discover the right kinds of class in a DDD effort.  Analysis
patterns, as stated in the book, is another.

--- In domaindrivendesign@yahoogroups.com, Juan Bernabó
<juan.bernabo@...> wrote:
>
> Hi,
>
> I would like to know if someone is using DDD and Peter Coad UML in
> Colors DNC (Domain Neutral Component) archetypes together.
>
> http://www.petercoad.com/download/bookpdfs/jmcuch01.pdf
>
> Personally I think that DNC can add value to the DDD entity concept,
> helping us to discover entities that are Moment/Interals,
> Party/Place/Things, Descriptions and Roles and follows the DNC
> structure, but in practice I had not have the oportunity to use this
> in a real project, so I dont really know the details.
>
> I have some questions.
>
> Has someone tried this in practice?
> Is there any conflicts betwen the concepts of DDD and Coad DNC?
> Is this is adding any value to the domain models?
> What are the cons?
> What are the pros?
>
> Thanks in advance,
> Juan.
>

#5264 From: cbeams <cbeams@...>
Date: Fri Apr 13, 2007 4:16 pm
Subject: Re: Re: Mixing Coad DNC with DDD
cbeams78
Send Email Send Email
 
Big +1 for Streamlined Object Modeling. It's part of the Coad Series of books, and I've found that it works hand-in-hand with DDD, and is most useful when distinguishing the particular relationships between entities.  You'll see the Moment/Interval Group/Member  Place/Outer Place  Line Item/Transaction, etc.. patterns; it builds on Coad's earlier work.  The book does a brilliant job of distinguishing the various possible entity relationships, and how to have those entities collaborate (in code) effectively.

- Chris

On Apr 13, 2007, at 9:06 AM, Chris Gardner wrote:

I think DNC, as is Streamlined Object Modeling, a tool that can help
you discover the right kinds of class in a DDD effort. Analysis
patterns, as stated in the book, is another.

--- In domaindrivendesign@yahoogroups.com, Juan Bernabó
<juan.bernabo@...> wrote:
>
> Hi,
>
> I would like to know if someone is using DDD and Peter Coad UML in
> Colors DNC (Domain Neutral Component) archetypes together.
>
> http://www.petercoad.com/download/bookpdfs/jmcuch01.pdf
>
> Personally I think that DNC can add value to the DDD entity concept,
> helping us to discover entities that are Moment/Interals,
> Party/Place/Things, Descriptions and Roles and follows the DNC
> structure, but in practice I had not have the oportunity to use this
> in a real project, so I dont really know the details.
>
> I have some questions.
>
> Has someone tried this in practice?
> Is there any conflicts betwen the concepts of DDD and Coad DNC?
> Is this is adding any value to the domain models?
> What are the cons?
> What are the pros?
>
> Thanks in advance,
> Juan.
>



Messages 5232 - 5264 of 24152   Oldest  |  < Older  |  Newer >  |  Newest
Add to My Yahoo!      XML What's This?

Copyright © 2010 Yahoo! Inc. All rights reserved.
Privacy Policy - Terms of Service - Guidelines NEW - Help