Re: A domain entity bridging two bounded contexts?
vvernon_shiftmethod <vvernon <at> shiftmethod.com>
2010-02-02 00:28:01 GMT
Well, I don't think of a Repository as exposing persistence knowledge. As you know you could implement a
Repository backed by a standard concrete collection, such as some kind of Set. When you add an Aggregate to
the Repository there's nothing that indicates *how* your object will stick around until you need it again.
Additionally, if you use domain Services to bridge BCs it is not the same as bridging BCs with the
Application Layer's services. Those are completely different service types. Remember that services
that are part of the Application Layer are used to control transactions, for example. Services that are
part of the Domain Layer don't dare do that. That would definitely be polluting the model with the wrong
concerns. Services in the Application Layer may deal with all sorts of things that have nothing to do with a
core domain. Services that are declared as part of the Domain Layer are concerned only with fulfilling
domain model concerns, even if their implementation must take a detour to go out and chat with another
system briefly. In the end it is providing logic and possibly objects that are
part of the BC and UL that its interface is declared in.
Vaughn
--- In domaindrivendesign <at> yahoogroups.com, "jbenami1" <jbenami1@...> wrote:
>
> I see what you're saying.
>
> > I am not clear on what you are struggling with as far as Service and
> Repository implementations.
>
> Well, as you may know, I'm pretty new to DDD. I guess for some reason I
> picked up DDD together with persistence ignorance, I'm not sure why. I
> guess I was affected, as Dan says, by those
> "vocal DDD practitioners here who disagree with the above approach, and
> prefer to put all bridging in the next level up, ie in the application
> service layer".
>
> As I said before, I've also read a lot about people extending PI to
> "infrastructure ignorance", and the idea that, if you sweep out the
> infrastructure, the domain should continue to work (on some level at
> least).
>
> But it's good for me to hear that there isn't a consensus about PI,
> because from my work so far, it has been more of a pain than anything
> else. Also it lets me rethink things with a more open mind.
>
>
> --- In domaindrivendesign <at> yahoogroups.com, "vvernon_shiftmethod"
> <vvernon@> wrote:
> >
> > > If I can pass an entity a service interface to communicate
> > > with another BC, why can't I pass it a repository interface
> > > to access or save data to the data store?
> >
> > I think it's a matter of taste. One of Eric's early posts to this
> group indicated that he sees (domain) Services and Repositories as
> residing in a mini layer within the model just above the Aggregates and
> other typical domain objects (Entities and Value Objects). Martin Fowler
> sees this a bit differently, as in his PofEAA under Repository pattern
> his examples all show Entities making use of a Repository to manage lazy
> loading.
> >
> > I have personally done this. I don't have an issue with it, but you
> may. I see the model as a mixture of various objects including Services
> and Repositories, along with Aggregates, Entities, and Value Objects,
> all residing at the same level in the domain model layer and
> interchangeably usable.
> >
> > I am not clear on what you are struggling with as far as Service and
> Repository implementations. If, for example, and Aggregate's root or
> some other Aggregate part takes a domain Service interface as a
> parameter and double-dispatches to it, why does that pollute the
> Aggregate with some implementation knowledge? All the Aggregate sees is
> the Service interface, not the implementation class. The same goes for a
> Repository.
> >
> > To drive this home a bit more, it is possible that the Application
> Layer services above the model are what have the domain Services and
> Repository implementation classes injected, but referenced only via the
> interfaces. These Application Layer thin services then orchestrate usage
> of the model, passing in as parameters whatever domain Service
> references were injected (for double-dispatch) or calling directly onto
> them for domain behavior.
> >
> > ========================
> > Application Layer (SOA services)
> > private SomeDomainService someDomainServiceInjectedRef;
> > ...
> > someDomainServiceInjectedRef.someBehavior();
> > ========================
> > Domain Model Layer
> > interface SomeDomainService
> > ========================
> > Infrastructure Layer
> > class SomeDomainServiceImpl
> > ========================
> >
> > Also, unless the domain Service is doing something special that
> requires it to be implemented in a lower layer, it could well be
> implemented in the Domain Model Layer. For example, if it is just
> providing some basic model behavior, it is implemented in the Domain
> Model Layer.
> >
> > Vaughn
> >
> >
> >
> > --- In domaindrivendesign <at> yahoogroups.com, "jbenami1" jbenami1@ wrote:
> > >
> > > Well, I've continued thinking about these things and am both
> interested
> > > and unsure. All this leads me to one main question:
> > > How freely should one use dependency injection and inversion of
> control?
> > >
> > > The more my entities are aware of outside elements, the more
> behavior
> > > they can encapsulate. Assuming that said behavior is actually within
> the
> > > realm of a given entity's logical responsibility, should I provide
> it
> > > everything it needs to do its work (whether by DI, service locator,
> > > method parameters, whatever)?
> > >
> > > Because I am not working with an ORM, this leads me to think: If I
> can
> > > pass an entity a service interface to communicate with another BC,
> why
> > > can't I pass it a repository interface to access or save data to the
> > > data store?
> > >
> > > Any thoughts?
> > >
> > >
> > > --- In domaindrivendesign <at> yahoogroups.com, "vvernon_shiftmethod"
> > > <vvernon@> wrote:
> > > >
> > > > It would be bad if the domain was dependent on infrastructure. But
> > > that's not the intention nor is it necessary. You can use DI or
> Service
> > > Locator (or Registry) pattern or whatever to prevent coupling of the
> > > model to infrastructure. There are enough elegant approaches that it
> > > should not be a stumbling block.
> > > >
> > > > Vaughn
> > > >
> > > >
> > > > --- In domaindrivendesign <at> yahoogroups.com, "jbenami1" jbenami1@
> wrote:
> > > > >
> > > > > Well I've mulled the technical aspect of it over a bit, and I
> can't
> > > > > quite see how it would work, not without dependency injection at
> > > least.
> > > > > But assuming it can be done technically, doesn't it negate some
> > > basic
> > > > > DDD concepts? Isn't making the domain dependent on
> infrastructure
> > > > > against the aim of domain encapsulation? Isn't having the domain
> > > call
> > > > > out to an infrastructure equivalent to having domain objects
> call
> > > > > repositories? Isn't persistence ignorance generally interpreted
> > > also as
> > > > > infrastructure ignorance?
> > > > >
> > > > >
> > > > > --- In domaindrivendesign <at> yahoogroups.com, "vvernon_shiftmethod"
> > > > > <vvernon@> wrote:
> > > > > >
> > > > > > > I don't really understand this. From my understanding so far
> > > > > > > of DDD, the domain is layered off in such a way that it can
> > > > > > > only interact with other domain objects. Have I
> misunderstood?
> > > > > >
> > > > > > You've got it. Except that there is a kind of Service that
> lives
> > > in
> > > > > the domain model (which you seem to refer to). Look at Services
> > > pattern
> > > > > in the DDD book. Note that the Domain Service, as with a Service
> in
> > > the
> > > > > Application Layer, has an interface and an implementation. Since
> the
> > > > > implementation can be pushed down a layer to the Infrastructure
> > > Layer as
> > > > > Repository implementations are, the implementation can interact
> with
> > > > > external systems. If you read the Anticorruption Layer pattern
> it
> > > will
> > > > > clue you in on that detail.
> > > > > >
> > > > > > > To be honest, the book's
> > > > > > > discussion of Open Host Services is a bit ambiguous.
> > > > > >
> > > > > > Ok, view Open Host Service as a set of Web Services. Maybe
> they
> > > use
> > > > > RPC or maybe are RESTful, but they provide an API for some other
> > > systems
> > > > > to use your services externally. In that case Open Host Service
> > > > > implementations are probably backed by Services in your
> Application
> > > > > Layer.
> > > > > >
> > > > > > The Published Language pattern could be used to define the XML
> > > that is
> > > > > output and taken as input by the web service.
> > > > > >
> > > > > > An external system would get the XML as the result of some
> query
> > > > > (http://host/app/userRoles/2291). It would then turn the XML
> into
> > > domain
> > > > > objects that are defined in the core domain's BC (Author,
> > > SalesPerson,
> > > > > etc).
> > > > > >
> > > > > > > I assumed that it
> > > > > > > would be implemented by an API provided by a Service layer
> > > > > > > to operations
> > > > > > > within that BC's domain layer. Which would mean that the
> > > > > > > RoleProvider
> > > > > > > domain service would be interacting with an application
> service?
> > > > > >
> > > > > > Again, since RoleProvider's implementation can be in the
> > > > > Infrastructure Layer, it could interact with say a RESTful web
> > > service
> > > > > provided by another application as its Open Host Service to get
> the
> > > User
> > > > > and Role information and then morph them into a Value Object
> product
> > > > > that belongs in your core domain (see above).
> > > > > >
> > > > > > > Actually, along this line, is the service/application layer
> part
> > > > > > > of a BC
> > > > > > > or is totally separate, being associated more with a
> particular
> > > > > > > application and therefore possibly spanning multiple BCs?
> > > > > >
> > > > > > The layering is defined in at least two places in the blue
> book:
> > > p70
> > > > > and p107. Per the Layers architecture pattern (POSA1) the layers
> in
> > > the
> > > > > blue book are stacked the way they work, and no lower layer can
> > > access a
> > > > > higher layer. So no, the Domain Layer would not interact with
> the
> > > > > Application Layer if it had to be bound to it. One way around
> that
> > > is
> > > > > when the Application Layer implements an interface defined by
> the
> > > Domain
> > > > > Layer (e.g GoF Mediator or Double Dispatch). Since the Domain
> Layer
> > > only
> > > > > has to require the interface, the Application Layer's
> implementation
> > > > > could become a provider for what the Domain Layer requires.
> > > > > >
> > > > > > Here's a typical Layers architecture:
> > > > > >
> > > > > > ======================
> > > > > > Presentation Layer
> > > > > > ======================
> > > > > > Application Layer
> > > > > > ======================
> > > > > > Domain Layer | CRM BC | CMS BC |
> > > > > > ======================
> > > > > > Infrastructure Layer
> > > > > > ======================
> > > > > >
> > > > > > Using an Open Host Service living in an external system, you'd
> be
> > > > > interacting with that system's Application Layer, it would
> interact
> > > with
> > > > > its system's Domain Layer. So the above two BCs indicate ones
> living
> > > in
> > > > > a single system.
> > > > > >
> > > > > > ======================
> > > > > > RESTful Web Services
> > > > > > ======================
> > > > > > Application Layer
> > > > > > ======================
> > > > > > Domain Layer | I&A (User, Role) |
> > > > > > ======================
> > > > > > Infrastructure Layer
> > > > > > ======================
> > > > > >
> > > > > > Anyway, if you ran with what I defined two posts ago you'd be
> > > fine. I
> > > > > was just trying to give you another perspective on how Domain
> > > Services
> > > > > could influence things. You could go with the former approach
> first
> > > and
> > > > > then refactor to the Domain Services approach later if you
> desire.
> > > > > >
> > > > > > Vaughn
> > > > > >
> > > > > >
> > > > > >
> > > > > > --- In domaindrivendesign <at> yahoogroups.com, "jbenami1"
> jbenami1@
> > > wrote:
> > > > > > >
> > > > > > > > Lots to think about.
> > > > > > >
> > > > > > > Yes it is.
> > > > > > >
> > > > > > > > No, SalesPerson and Author both contain enough necessary
> state
> > > to
> > > > > > > allow navigation back to the User. But remember that the
> notion
> > > of
> > > > > User,
> > > > > > > at least in my example, does not live in the CRM or CMS
> Bounded
> > > > > > > Contexts. However, all we'd need to do to get the User is to
> use
> > > the
> > > > > > > indentityAndAccess service, which is probably backed by Open
> > > Host
> > > > > > > Service...
> > > > > > >
> > > > > > > That makes sense.
> > > > > > >
> > > > > > > > Also, note that the original example app service method I
> > > provided
> > > > > > > below is a wee bit oversimplified. Some of the code could be
> > > pushed
> > > > > > > lower into Domain Services. For one thing, an Open Host
> Service
> > > > > client
> > > > > > > might be implemented by a Domain Service. A Domain Service
> > > wouldn't
> > > > > > > return a User, because the Domain Service is in a BC that
> > > doesn't
> > > > > > > understand Users. You might do something more like this:
> > > > > > > >
> > > > > > > > Author author = roleProvider.getRoleFor(authorId,
> "Author");
> > > > > > > >
> > > > > > > > Then the implementation of the RoleProvider Domain Service
> > > would
> > > > > > > interact with the I&A Open Host Service, but only to the
> extent
> > > that
> > > > > it
> > > > > > > needs to turn a userId and role name into a BC-specific
> role,
> > > namely
> > > > > an
> > > > > > > Author. (Of course you could still handle it as my original
> > > example
> > > > > > > did.)
> > > > > > >
> > > > > > > I don't really understand this. From my understanding so far
> of
> > > DDD,
> > > > > the
> > > > > > > domain is layered off in such a way that it can only
> interact
> > > with
> > > > > other
> > > > > > > domain objects. Have I misunderstood? To be honest, the
> book's
> > > > > > > discussion of Open Host Services is a bit ambiguous. I
> assumed
> > > that
> > > > > it
> > > > > > > would be implemented by an API provided by a Service layer
> to
> > > > > operations
> > > > > > > within that BC's domain layer. Which would mean that the
> > > > > RoleProvider
> > > > > > > domain service would be interacting with an application
> service?
> > > > > > > Actually, along this line, is the service/application layer
> part
> > > of
> > > > > a BC
> > > > > > > or is totally separate, being associated more with a
> particular
> > > > > > > application and therefore possibly spanning multiple BCs?
> > > > > > >
> > > > > > >
> > > > > > > Joni
> > > > > > >
> > > > > > > --- In domaindrivendesign <at> yahoogroups.com,
> "vvernon_shiftmethod"
> > > > > > > <vvernon@> wrote:
> > > > > > > >
> > > > > > > > > From my very light reading about the actor-role pattern,
> it
> > > > > seems to
> > > > > > > > > suggest that "it's possible to navigate from a role to
> the
> > > actor
> > > > > who
> > > > > > > > > currently plays it", i.e., that the role composes the
> actor.
> > > But
> > > > > > > > > in your sketch this is not the case, for example, to
> create
> > > a
> > > > > > > > > SalesPerson, you don't pass in the salesUser, but rather
> the
> > > > > > > > > salesUser's username and
> > > > > > > > > fullname. What are the considerations for this choice?
> > > > > > > >
> > > > > > > > No, SalesPerson and Author both contain enough necessary
> state
> > > to
> > > > > > > allow navigation back to the User. But remember that the
> notion
> > > of
> > > > > User,
> > > > > > > at least in my example, does not live in the CRM or CMS
> Bounded
> > > > > > > Contexts. However, all we'd need to do to get the User is to
> use
> > > the
> > > > > > > indentityAndAccess service, which is probably backed by Open
> > > Host
> > > > > > > Service, to find it:
> > > > > > > >
> > > > > > > > User user =
> > > > > > >
> > > identityAndAccess.getUserFromUsername(salesPerson.getUsername());
> > > > > > > >
> > > > > > > > So, no, the navigation is not as simple as this:
> > > > > > > >
> > > > > > > > User user = salesPerson.getUser();
> > > > > > > >
> > > > > > > > But it gives you the ability to eliminate Users from
> Bounded
> > > > > Contexts
> > > > > > > where they really don't apply. Of course I am assuming that
> User
> > > > > doesn't
> > > > > > > apply in CRM and CMS. But to me, and maybe to your DEs, they
> > > really
> > > > > > > don't belong. Because typically CMS uses Author, Reviewer,
> > > Editor,
> > > > > > > Releaser, Publisher, etc.
> > > > > > > >
> > > > > > > > Still, the pure Actor-Role pattern is implemented by the
> I&A
> > > BC.
> > > > > The
> > > > > > > other two BCs, CRM and CMS, turn it on its ear more like
> > > Role-Actor.
> > > > > > > >
> > > > > > > > > Should the SalesContract know about its Folder? Even
> more,
> > > > > should it
> > > > > > > > > know about its customer (as you have indicated in this
> > > example)?
> > > > > Or
> > > > > > > > > should traversal be one way the other way (Customer to
> > > Folder to
> > > > > > > > > SalesContract)?
> > > > > > > >
> > > > > > > > It depends. I was not trying to solve your aggregate
> > > composition
> > > > > > > problem, just trying to illustrate how you might design with
> > > three
> > > > > BCs,
> > > > > > > each focused on separate concerns of I&A, CRM, and CMS. In
> > > Document
> > > > > > > Management Systems I have worked with (Documentum) and
> designed
> > > > > (DMS/CMS
> > > > > > > patterns, which have some characteristics of Documentum) the
> > > > > > > ManagedDocument does know its parent ManagedFolder. And my
> > > example
> > > > > below
> > > > > > > does not bar that possibility, because the internals of
> > > > > addDocument()
> > > > > > > could do something like this:
> > > > > > > >
> > > > > > > > public void addDocument(Document aDocument) {
> > > > > > > > // ...
> > > > > > > > aDocument.setFolder(this);
> > > > > > > > }
> > > > > > > >
> > > > > > > > It's just a matter of how you settle on your composition.
> That
> > > > > said,
> > > > > > > to me a Customer would never own Folders. For one thing,
> because
> > > > > > > Customer is not part of CMS, it is part of CRM. (I'll add
> that
> > > to
> > > > > some
> > > > > > > DMS people, like Documentum folks I've worked with,
> everything
> > > > > becomes a
> > > > > > > Document. Right, that whole "every problem looks like a
> nail"
> > > thing.
> > > > > So
> > > > > > > Customer becomes a Document subclass, and then it might
> > > "naturally"
> > > > > own
> > > > > > > Folders. I think this is rash and poor thinking. But it
> happens
> > > > > because
> > > > > > > many DMS people just want to use the facilities of the DMS
> and
> > > not
> > > > > think
> > > > > > > about domain modeling.)
> > > > > > > >
> > > > > > > > Also, note that the original example app service method I
> > > provided
> > > > > > > below is a wee bit oversimplified. Some of the code could be
> > > pushed
> > > > > > > lower into Domain Services. For one thing, an Open Host
> Service
> > > > > client
> > > > > > > might be implemented by a Domain Service. A Domain Service
> > > wouldn't
> > > > > > > return a User, because the Domain Service is in a BC that
> > > doesn't
> > > > > > > understand Users. You might do something more like this:
> > > > > > > >
> > > > > > > > Author author = roleProvider.getRoleFor(authorId,
> "Author");
> > > > > > > >
> > > > > > > > Then the implementation of the RoleProvider Domain Service
> > > would
> > > > > > > interact with the I&A Open Host Service, but only to the
> extent
> > > that
> > > > > it
> > > > > > > needs to turn a userId and role name into a BC-specific
> role,
> > > namely
> > > > > an
> > > > > > > Author. (Of course you could still handle it as my original
> > > example
> > > > > > > did.)
> > > > > > > >
> > > > > > > > In either case you would still need identityAndAccess
> service
> > > > > fronting
> > > > > > > the I&A BC Open Host Service in order to deal with flipping
> > > username
> > > > > > > back into a User if you needed to do that.
> > > > > > > >
> > > > > > > > Lots to think about.
> > > > > > > >
> > > > > > > > Vaughn
> > > > > > > >
> > > > > > > >
> > > > > > > >
> > > > > > > > --- In domaindrivendesign <at> yahoogroups.com, "jbenami1"
> > > jbenami1@
> > > > > wrote:
> > > > > > > > >
> > > > > > > > > I see. This looks great! I'll have to contemplate this
> some,
> > > but
> > > > > now
> > > > > > > I
> > > > > > > > > understand what you meant, and it does seem like a clear
> way
> > > to
> > > > > > > express
> > > > > > > > > the domain.
> > > > > > > > > I have a couple of questions, though:
> > > > > > > > >
> > > > > > > > > From my very light reading about the actor-role pattern,
> it
> > > > > seems to
> > > > > > > > > suggest that "it's possible to navigate from a role to
> the
> > > actor
> > > > > who
> > > > > > > > > currently plays it", i.e., that the role composes the
> actor.
> > > But
> > > > > in
> > > > > > > your
> > > > > > > > > sketch this is not the case, for example, to create a
> > > > > SalesPerson,
> > > > > > > you
> > > > > > > > > don't pass in the salesUser, but rather the salesUser's
> > > username
> > > > > and
> > > > > > > > > fullname. What are the considerations for this choice?
> > > > > > > > >
> > > > > > > > > Another side-question, about these lines:
> > > > > > > > > > SalesContract salesContract = new
> > > > > > > > > SalesContract(customer.getCustomerNumber(), author,
> > > > > > > contractContent);
> > > > > > > > > > Folder folder = folderRepository.get(folderName);
> > > > > > > > > > folder.addDocument(salesContract);
> > > > > > > > >
> > > > > > > > > This examples raises an issue that I've faced a lot in
> my
> > > > > design. In
> > > > > > > the
> > > > > > > > > terms of this example:
> > > > > > > > > - Customer aggregates Folders
> > > > > > > > > - Folders aggregate SalesContracts
> > > > > > > > >
> > > > > > > > > Should the SalesContract know about its Folder? Even
> more,
> > > > > should it
> > > > > > > > > know about its customer (as you have indicated in this
> > > example)?
> > > > > Or
> > > > > > > > > should traversal be one way the other way (Customer to
> > > Folder to
> > > > > > > > > SalesContract)?
> > > > > > > > >
> > > > > > > > >
> > > > > > > > >
> > > > > > > > > --- In domaindrivendesign <at> yahoogroups.com,
> > > "vvernon_shiftmethod"
> > > > > > > > > <vvernon@> wrote:
> > > > > > > > > >
> > > > > > > > > > It is not necessarily Shared Kernel, and my preference
> is
> > > that
> > > > > it
> > > > > > > is
> > > > > > > > > not. You could use Open Host Service, for example, to
> > > interact
> > > > > with
> > > > > > > the
> > > > > > > > > various BCs. This is possible because you own them. If
> you
> > > don't
> > > > > own
> > > > > > > > > Identity and Access Management BC, maybe you put it
> behind
> > > an
> > > > > > > > > Anticorruption Layer.
> > > > > > > > > >
> > > > > > > > > > Anyway, you have three distinct BCs, with specific
> domain
> > > > > objects:
> > > > > > > > > >
> > > > > > > > > > 1. Identify and Access Management BC
> > > > > > > > > >
> > > > > > > > > > Aggregate: User
> > > > > > > > > >
> > > > > > > > > > 2. Customer Relationship Management BC
> > > > > > > > > >
> > > > > > > > > > Aggregate: Customer
> > > > > > > > > > Value Object: SalesPerson (a role)
> > > > > > > > > >
> > > > > > > > > > 3. Content Management System BC
> > > > > > > > > >
> > > > > > > > > > Aggregate: Folder
> > > > > > > > > > Aggregate: SalesContract
> > > > > > > > > > Value Object: Author (a role)
> > > > > > > > > >
> > > > > > > > > > You have a Service above your domain models in the
> > > Application
> > > > > > > Layer.
> > > > > > > > > It's called something like CustomerSalesService. It
> provides
> > > a
> > > > > means
> > > > > > > to
> > > > > > > > > author CMS SalesContract documents and save them in a
> CMS
> > > > > Folder. It
> > > > > > > > > also provides a means hook up a Customer to that
> > > SalesContract
> > > > > and
> > > > > > > > > indicate which Sales guys are involved.
> > > > > > > > > >
> > > > > > > > > > //===== Application Layer
> > > > > > > > > >
> > > > > > > > > > public class CustomerSalesService ... {
> > > > > > > > > >
> > > > > > > > > > public void createCustomerSalesContract(long
> customerId,
> > > > > String
> > > > > > > > > salesPersonId, String authorId, String contractContent,
> > > String
> > > > > > > > > folderName) {
> > > > > > > > > >
> > > > > > > > > > User salesUser =
> identityAndAccess.getUser(salesPersonId);
> > > > > > > > > > if (!salesUser.isInRole("Sales")) {
> > > > > > > > > > throw new NotInRoleException(salesPersonId, "Sales");
> > > > > > > > > > }
> > > > > > > > > >
> > > > > > > > > > User authorUser = identityAndAccess.getUser(authorId);
> > > > > > > > > > if (!authorUser.isInRole("Author")) {
> > > > > > > > > > throw new NotInRoleException(authorId, "Author");
> > > > > > > > > > }
> > > > > > > > > >
> > > > > > > > > > // could be behind another thin app service for the
> CRM BC
> > > > > > > > > > SalesPerson salesPerson = new
> > > > > SalesPerson(salesUser.getUsername(),
> > > > > > > > > salesUser.getFullName())
> > > > > > > > > > Customer customer =
> customerRepository.get(customerId);
> > > > > > > > > > customer.currentSalesPerson(salesPerson);
> > > > > > > > > >
> > > > > > > > > > // could be behind another thin app service for the
> CMS BC
> > > > > > > > > > Author author = new Author(authorUser.getUsername(),
> > > > > > > > > authorUser.getFullName());
> > > > > > > > > > SalesContract salesContract = new
> > > > > > > > > SalesContract(customer.getCustomerNumber(), author,
> > > > > > > contractContent);
> > > > > > > > > > Folder folder = folderRepository.get(folderName);
> > > > > > > > > > folder.addDocument(salesContract);
> > > > > > > > > > }
> > > > > > > > > >
> > > > > > > > > > }
> > > > > > > > > >
> > > > > > > > > > I know the above code is not the prettiest. The point
> is
> > > to
> > > > > > > capture
> > > > > > > > > the essence of the design. User is a separate concept
> that
> > > > > doesn't
> > > > > > > enter
> > > > > > > > > into the CRM and CMS domains, only its essential parts
> as
> > > needed
> > > > > by
> > > > > > > the
> > > > > > > > > role-based value objects SalesPerson and Author.
> > > > > > > > > >
> > > > > > > > > > Vaughn
> > > > > > > > > >
> > > > > > > > > >
> > > > > > > > > >
> > > > > > > > > > --- In domaindrivendesign <at> yahoogroups.com, "jbenami1"
> > > > > jbenami1@
> > > > > > > wrote:
> > > > > > > > > > >
> > > > > > > > > > > Vaughn,
> > > > > > > > > > >
> > > > > > > > > > > Your suggestion sounds elegant, but the pattern is
> > > > > unfamiliar to
> > > > > > > me.
> > > > > > > > > > > Probably it is similar to what Nuno was suggesting.
> Let
> > > me
> > > > > try
> > > > > > > to
> > > > > > > > > > > interpret it into more technical terms, tell if I'm
> > > close.
> > > > > > > > > > >
> > > > > > > > > > > There would be an Access Management module with a
> User
> > > > > entity.
> > > > > > > > > > > In a module in the CMS BC I would have something
> like a
> > > > > CmsUser
> > > > > > > that
> > > > > > > > > > > inherits from User? Or if not by inheritance how
> else
> > > are
> > > > > you
> > > > > > > > > > > implementing this actor-role pattern?
> > > > > > > > > > > Same for the CRM BC, but with a different
> > > implementation.
> > > > > > > > > > >
> > > > > > > > > > > What is the significance of treating this as actors
> and
> > > > > roles?
> > > > > > > > > Doesn't
> > > > > > > > > > > this idea just boil down to a shared kernel, used by
> to
> > > > > separate
> > > > > > > > > > > implementations of User?
> > > > > > > > > > >
> > > > > > > > > > >
> > > > > > > > > > > --- In domaindrivendesign <at> yahoogroups.com,
> > > > > "vvernon_shiftmethod"
> > > > > > > > > > > <vvernon@> wrote:
> > > > > > > > > > > >
> > > > > > > > > > > > Make sure you use names from your Ubiquitous
> Language.
> > > My
> > > > > > > guess is
> > > > > > > > > > > that your domain experts never speak in terms of
> > > UserWrapper
> > > > > and
> > > > > > > > > > > UserInfo.
> > > > > > > > > > > >
> > > > > > > > > > > > I would propose a three-way separation: (1) you
> have a
> > > > > User in
> > > > > > > an
> > > > > > > > > > > Identity and Access Management domain (BC), (2) you
> have
> > > > > some
> > > > > > > > > role-based
> > > > > > > > > > > domain object in your CMS domain, and (3) you have
> some
> > > > > > > role-based
> > > > > > > > > > > domain object in your CRM domain. In 2 and 3 you
> want to
> > > > > have
> > > > > > > terms
> > > > > > > > > that
> > > > > > > > > > > match how the domain experts speak of those roles.
> > > > > > > > > > > >
> > > > > > > > > > > > An Application Layer service likely interacts with
> the
> > > > > > > identity
> > > > > > > > > and
> > > > > > > > > > > access management BC, and then creates or finds a
> domain
> > > > > object
> > > > > > > > > either 2
> > > > > > > > > > > or 3 that represents the concepts in the specific
> BC. If
> > > the
> > > > > > > > > role-based
> > > > > > > > > > > object truly owns folders, documents, etc., in the
> CMS
> > > BC,
> > > > > then
> > > > > > > that
> > > > > > > > > > > role object would be an entity (first created, then
> > > found
> > > > > via
> > > > > > > > > repository
> > > > > > > > > > > in subsequent uses). If it really doesn't own them,
> but
> > > gets
> > > > > > > > > associated
> > > > > > > > > > > with them as a creator, editor, etc., then that role
> > > object
> > > > > > > could be
> > > > > > > > > a
> > > > > > > > > > > value object (always created).
> > > > > > > > > > > >
> > > > > > > > > > > > At a minimum there is a separate BC for 1, which
> is
> > > what
> > > > > your
> > > > > > > > > current
> > > > > > > > > > > refactoring is on track to do. If CRM stands for
> > > Customer
> > > > > > > > > Relationship
> > > > > > > > > > > Management, I don't see how that can share a BC with
> > > CMS, if
> > > > > > > that
> > > > > > > > > stands
> > > > > > > > > > > for Content Management System. Even if 2 and 3
> really
> > > are
> > > > > hand
> > > > > > > in
> > > > > > > > > glove,
> > > > > > > > > > > separating them makes them both more flexible for
> future
> > > > > paths.
> > > > > > > > > > > >
> > > > > > > > > > > > I would also imagine that you have two groups of
> > > domain
> > > > > > > experts
> > > > > > > > > > > involved.
> > > > > > > > > > > >
> > > > > > > > > > > > Vaughn
> > > > > > > > > > > >
> > > > > > > > > > > >
> > > > > > > > > > > >
> > > > > > > > > > > > --- In domaindrivendesign <at> yahoogroups.com,
> "jbenami1"
> > > > > > > jbenami1@
> > > > > > > > > wrote:
> > > > > > > > > > > > >
> > > > > > > > > > > > > Hi all,
> > > > > > > > > > > > >
> > > > > > > > > > > > > We have a pretty simple model that has until now
> > > been
> > > > > > > > > encapsulated
> > > > > > > > > > > in one bounded context, revolving around content
> > > management
> > > > > > > (CMS).
> > > > > > > > > There
> > > > > > > > > > > was a user module but it was integrated into a CMS
> > > module.
> > > > > Now
> > > > > > > we
> > > > > > > > > are
> > > > > > > > > > > starting to refactor out the module to which it
> should
> > > > > belong,
> > > > > > > > > revolving
> > > > > > > > > > > around customer relations (CRM). The problem is that
> > > there
> > > > > is a
> > > > > > > User
> > > > > > > > > > > object that has content and some functionality from
> the
> > > CMS
> > > > > > > modules
> > > > > > > > > > > (folders, documents and queries), and also some from
> the
> > > CRM
> > > > > > > modules
> > > > > > > > > > > (questions, authentication). These functionalities
> also
> > > work
> > > > > in
> > > > > > > the
> > > > > > > > > > > infrastructure against separate databases.
> > > > > > > > > > > > >
> > > > > > > > > > > > > Our thought right now is to have two separate
> User
> > > > > objects,
> > > > > > > one
> > > > > > > > > > > aggregated by the other, basically a UserWrapper and
> a
> > > > > UserInfo.
> > > > > > > The
> > > > > > > > > > > UserWrapper includes CMS functionality as well as
> > > exposing
> > > > > > > important
> > > > > > > > > > > properties/functionality of the aggregated UserInfo
> > > object.
> > > > > > > > > > > > >
> > > > > > > > > > > > > So getting a "User" object would entail sending
> the
> > > > > > > > > authentication
> > > > > > > > > > > information to the UserWrapper repository, which
> would
> > > pass
> > > > > this
> > > > > > > on
> > > > > > > > > to
> > > > > > > > > > > the UserInfo repository, which would do its own
> > > > > authentication,
> > > > > > > > > > > returning a UserInfo object to the UserWrapper
> > > repository.
> > > > > The
> > > > > > > > > > > UserRepository then performs its own logic and
> returns a
> > > > > > > UserWrapper
> > > > > > > > > to
> > > > > > > > > > > the caller, which aggregates the UserInfo object.
> > > > > > > > > > > > >
> > > > > > > > > > > > > This seems bizarre and unwieldy to me, but I
> don't
> > > have
> > > > > a
> > > > > > > better
> > > > > > > > > > > idea right now. It implies that an object in one
> bounded
> > > > > context
> > > > > > > > > > > (UserWrapper in CMS) aggregates an object in another
> > > bounded
> > > > > > > context
> > > > > > > > > > > (UserInfo in CRM). Does someone have a more elegant
> > > solution
> > > > > to
> > > > > > > > > this?
> > > > > > > > > > > > >
> > > > > > > > > > > > > Infrastructurally, this object MUST be separate
> > > because
> > > > > I
> > > > > > > will
> > > > > > > > > have
> > > > > > > > > > > separate repositories for the CRM-related
> functionality
> > > and
> > > > > the
> > > > > > > > > > > CMS-related functionality.
> > > > > > > > > > > > >
> > > > > > > > > > > > > Has anyone else had to deal with an object in
> one BC
> > > > > > > aggregating
> > > > > > > > > > > members in another BC? Like a User object containing
> > > > > documents
> > > > > > > or
> > > > > > > > > the
> > > > > > > > > > > like?
> > > > > > > > > > > > >
> > > > > > > > > > > >
> > > > > > > > > > >
> > > > > > > > > >
> > > > > > > > >
> > > > > > > >
> > > > > > >
> > > > > >
> > > > >
> > > >
> > >
> >
>
------------------------------------