gbilodeau <at> yahoo.com [domaindrivendesign] <domaindrivendesign <at> yahoogroups.com>
2014-10-08 15:32:39 GMT
For the last year, I've been part of a small team of 2 developers working on a large project that is usually tackled by much larger teams. We are trying to drive the design of our domain model using DDD principles. We are succeeding to a certain extent, but we are struggling with the definition and separation of bounded contexts. I would like to request your advice on this problem.
To sum up the purpose of our application, we could say that it allows organizations to plan, track and report on collaborative projects. The main features are as follows:
organization management (internal
org chart, employees)
relationship management (customer / vendor accounts, contacts)
ratecard management (services, pricing models)
project tracking (task assignment, progress and completion, etc.)
procurement (requests for proposal, business proposals, purchase orders)
accounting (invoices, receivables and payables, payments, collection, etc.)
reporting (budgeted vs invoiced, employee productivity, profit margins, etc.)
There is a strong requirement for traceability between entities throughout the process: one should be able to reconstitute the path from an original budgeted line item up to an invoiced line item, thereby allowing an organization to produce high-quality reports.
Reading the literature (both the Evans and Vernon books), I gather that bounded contexts serve multiple purposes: defining a linguistic barrier within which concepts are clear and unambiguous, allowing teams to work in parallel with minimal friction, and reducing coupling between different pa
rts of the model. I also gather that an application may be divided in bounded contexts of varying granularity, ranging from a single coarse bounded context for the whole application down to several fine bounded contexts, one per feature. Given the application we're working on, and the current size of our team, it's unclear where in that granularity spectrum we should be standing.
There is a case to be made for having a single bounded context:
Our team is small, we communicate easily and we have a low integration cost.
We have elaborated a clear vocabulary within which concepts are clear(ish) and ambiguities are few and
Integration between features is a selling point for this application, and so some entities are to be used by several features (e.g. a ratecard element can be used in a budget, a project timesheet and an invoice)
No duplication. An organization is an organization is an organization.
There is also a case to be made for having several bounded contexts:
Although our team is small today, we hope to grow in the future. Both communication and integration will become harder. Bounded context
s would help us grow more easily.
The application will assuredly grow, and so will our vocabulary. Ambiguities and polysemes will surely appear. Bounded contexts would help us better contain and demarcate models.
- Already, some concepts are used differently depending on the feature they live in.
- For example: a ratecard element is used as an entity within the ratecard management feature (allowing for change tracking and an approval process), but it is used as a value in other consuming features (where it is considered to be stable, valid and approved).
- Another example: an organization is responsible for hiring an employee within the organization management feature, while it is responsible for launching a project in the project tracking feature. Having separate implementations of the organization concept would allow for classes with clearer responsibilities (instead of having a God-like organization responsible for creating everything).
Already, changes to a central concept (customer / vendor account) has rippled throughout the model because of the high coupling to it.
As an experiment, we have attempted to separate the application in a few contexts.
We saw some advantages: lower coupling between features and clearer responsibilities for classes. But we also saw some drawbacks: *lots* of duplicated code (n implementations of Organization, n implementations of Customer, etc.) and *lots* of translation code between contexts, which leads us to questions such as "why didn't I just use the original entity instead?" It also brought some questions regarding the visibility of concepts, such as "when defining the vendors to invite to a RFP, should I consult the relationship management context or the procurement context? and so will I need to add similar API endpoints to retrieve vendors in every consuming context?"
Needless to say, these questions are driving us mad and leading to discussio
ns that, while interesting, ultimately leave us feeling like a) we don't understand anything, and b) we're losing our time on over-architecture.
So... if you're not exhausted from reading this, what advice could you give its very confused author? :)
Thank you very much in advance!
Posted by: gbilodeau <at> yahoo.com