Re: Validating aggregate collections: when and whose job is it?

Michael Rempel <[email protected]>
Newsgroups gmane.comp.programming.domain-driven-design
Message-ID <CAN2bj2BcEYXO0p=x2sZKwdk7o7F8LR8b6zojn7M+Svi7e12TPQ@mail.gmail.com>
A few observations.
Your rules only need to be checked when the data changes or is created. So
having some kind of validation check timestamp or version is a good idea.
The first rule you dont mention is that rules change. You should account
for this.

In this specific domain you seem to have over complicated things with the
rules. It looks like you might have 2 states of a company with some simpler
rules. Some rules always apply, some only apply when 'registered'.

If you take an action or command approach to the domain rules, rather than
a state approach I think you will see this more clearly. You express the
rules as actions, but think about objects themselves as states. I have two
models in mind myself. Read models, and write models. An object written to
the database should then be read-refreshed anyway. This keeps your data
sharding strategy as simple as possible. When read you can also check it's
validation state and ask the user for updates as needed to keep it current,
or to require new data for extended functionality. Classic DDD doesnt
express this pattern, but the CQRS with Event store extension does sort of.
Event store is overkill for projects that maintain relationships. It is
more for high volume update situations. But thinking in terms of commands
and events is very useful.


On Sat, Feb 1, 2014 at 5:23 PM, <[email protected]> wrote:

>
>
> Hi all,
>
> I would like to have your input on a relatively simple problem that has me
> looking everywere for guidelines.  Here it goes.
>
> Let's consider a relatively simple subset of the application on which I'm
> working.  Aside from other considerations, this application allows users to:
> - manage the inner structure of their company: head office, departments,
> employees, etc.
> - manage the relationships their company has with external customers
>
> If we focus on the relationship management part, we learn that a customer
> can be:
> - registered: referring to a company already registered in the
> application, or
> - virtual: not referring to any registered company (and basically a
> placeholder until the company actually registers)
>
> There are two main rules that must be respected:
> 1. for a given company, no virtual company can be created with a given
> website if that website is already owned by an existing company (basically,
> don't create virtual customers when registered customers exist), and
> 2. for a given company, no two customers, virtual or registered, must own
> the same website
>
> To clarify, considering two registered companies, company1 (website
> company1.com) and company2 (company2.com):
> 1. company1 cannot add a virtual customer with website company2.com,
> instead it must add company2 as a registered customer
> 2. company1 cannot add twice the virtual customer company3 with website
> company3.com
>
> Although we could get into a discussion of which contexts exist, for the
> moment let's consider a single "company management" context with two
> aggregates:
> - Company { companyId, name, website }
> - Customer { customerId, ownerCompanyId, name, website,
> registeredCompanyId }
>
> There are two basic questions: when are the two above business rules
> validated and by whom? I see two options:
>
> 1. The rules can be verified when instantiating the Customer aggregate or
> when saving it to the data store. Validating at instantiation time benefits
> us since we know that there can never be an invalid Customer in memory.
> Instantiation would be performed by the Company aggregate. That would
> require Company or its Company.createCustomer methods to have access
> reference to both a CompanyRepository and a CustomerRepository to lookup
> any Company or Customer by website. Introducing a dependency between
> Company and these repositories doesn't produce a clean and intuitive API,
> plus doesn't feel like a very healthy dependency.
> 2. The rules can be verified when saving to the data store. This would be
> performed by the CustomerRepository implementation. This approach removes
> the Company - repository dependencies, and having an invalid Customer in
> memory isn't really an issue.  But is validation logic really part of a
> Repository's responsibilities? Also, this would require the
> CustomerRepository.add and CustomerRepository.update methods to have a
> reference to a CompanyRepository to lookup any Company website. Introducing
> a dependency between two repositories doesn't feel right: my understanding
> is that a repository should only manage instances of a given aggregate
> regardless of its environment, but maybe this is too short-sighted.
>
> What do you think? How do you usually model these kinds of business rules?
>
> Thanks a bunch!
> GB
>
>  
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.