Re: DRY and cross domain logic

"Tom Eugelink [email protected] [domaindrivendesign]" <[email protected]> Fri, 22 May 2015 16:48:42 +0200
Newsgroups gmane.comp.programming.domain-driven-design
Message-ID <[email protected]>
Agree, however a domain service does not seem like the correct place. I would expect a setup similar to repositories, with an interface defined in Patient's domain and an implementation in Patient's boundary, which then can do the anti-corruption to the CalculateAgeService in Client's BC.


On 22-5-2015 16:44, Paul Rayner [email protected] [domaindrivendesign] wrote:
> Think about this in model terms. The CalculateAgeService belongs in the Clients BC, which means it speaks the Client BC language. You don't want that language bleeding into your Patient BC, so I'd recommend something to translate the language from one context to another and isolate that translation at the boundary. Perhaps it could start out as a domain service in the Patient BC which functions as an anti-corruption layer by wrapping the Client open host service. So, yes, call something within it's own boundary.
>
> On Fri, May 22, 2015 at 8:31 AM, Tom Eugelink [email protected] <mailto:[email protected]> [domaindrivendesign] <[email protected] <mailto:[email protected]>> wrote:
>
>     Duplication, within limits, was my initial idea as well, but my team kinda goes beserk over duplication. And, as said, the algorithm may be more complex and must stay within the one BC.
>
>     Open Host Service, basically a call to another BC's API, that is what I'm currently looking at. Would Patient.calculateAge() call the CalculateAgeService in Client's BC directly? I feel entities should not call out to another BC directly, but instead call something in its own boundary.
>
>     Tom
>
>
>
>     On 22-5-2015 16:16, Jorge Branco [email protected] <mailto:[email protected]> [domaindrivendesign] wrote:
>>     > Secondly, you could implement the logic in both bounded contexts. I'm less concerned about DRY across bounded contexts, since we are talking about different models.
>>
>>     That was my thought. Is everyone working on those 2 BCs or do different teams each have their own BC?
>>
>>     I'd say over time it may actually be okay to have some code duplicated in that situation, as it starts getting hard to have both teams in total sync.
>>
>>     On Fri, May 22, 2015 at 3:12 PM, Paul Rayner [email protected] <mailto:[email protected]> [domaindrivendesign] <[email protected] <mailto:[email protected]>> wrote:
>>
>>         I see (at least) three options, with various tradeoffs: Firstly, the Client bounded context could provide an Open Host Service that takes in the relevant info and reports out the result, which the Patient bounded context could then call. This seems the likely candidate if several entities/aggregates are required from Client.
>>
>>         Secondly, you could implement the logic in both bounded contexts. I'm less concerned about DRY across bounded contexts, since we are talking about different models.
>>
>>         Thirdly, share the logic in some way (abstract base class etc), which gives you a Shared Kernel. Shared Kernels are tricky to get right, and given what you've said about the algorithm and the potential need for other entities, I'd be wary of this one.
>>
>>         Paul.
>>
>>         On Fri, May 22, 2015 at 8:02 AM, Tom Eugelink [email protected] <mailto:[email protected]> [domaindrivendesign] <[email protected] <mailto:[email protected]>> wrote:
>>
>>             But what if the input of the algorithm requires other entities in the Client's BC? The output may be simple, but maybe the age calculation also depends on the country where the client is born, because they use a different calendar (e.g. Chinese). The country is not present in Patient's BC.
>>
>>             Tom
>>
>>
>>             On 22-5-2015 15:09, Jose Fernandez [email protected] <mailto:[email protected]> [domaindrivendesign] wrote:
>>>             Just create  base class with common members and methods. Inherit your AR from it.
>>>
>>>             public class Person
>>>             {
>>>             public DateTime BirthDate;
>>>             public int CalculateAge()
>>>             {
>>>             return age here;
>>>             }
>>>             }
>>>
>>>             Public class Client: Person, IAggregateRoot
>>>
>>>             Same for Patient.
>>>
>>>             Sent from my iPhone
>>>
>>>             On May 22, 2015, at 8:31 AM, Tom Eugelink [email protected] <mailto:[email protected]> [domaindrivendesign] <[email protected] <mailto:[email protected]>> wrote:
>>>
>>>>             We have a discussion in my current project group about the following:
>>>>             - There are two bounded context.
>>>>             - In each bounded context there is an person-alike entity, in one BC it is Client in the other it is Patient, mostly with their own business logic and methods specific to their roles.
>>>>             - However, at some point Patient requires some determining logic that is implemented in Client. For simplicity let's assume both have a date-of-birth and the to-be-called logic is calculateAge().
>>>>
>>>>             This is not something that can be done with events, and because of DRY you do not want to implement calculateAge() twice. What is the best option to calculate the age of a patient? Client and Patient share a unique id, so Patient knows which Client to get. (N.B. I seek a conceptual solution, not one specific to the calculate age problem.)
>>>>
>>>>             Tom
>>>>
>>
>>
>>
>
>
>