llisticc | 1 Feb 01:22
Picon

Re: Handling reporting store read/write contention

Hi, 

Based on what you've said for reporting doing insert-only may be Ok, although if you we're doing CQRS where
this data is shown to users on screen, I'm a little confused on how this would work?

If you do not update the affected rows, wouldn't you be showing users multiple versions of the same data?

Thanks
Quang

--- In domaindrivendesign <at> yahoogroups.com, "Udi Dahan" <thesoftwaresimplist@...> wrote:
>
> Matt,
> 
>  
> 
> If you've explicitly modeled the staleness of the data in your query model,
> the writing of events from the command side to the query side should be
> possible to be done in an insert-only fashion, solving many of the
> contention issues since they're now working on different rows.
> 
>  
> 
> Does that answer your question?
> 
>  
> 
> -- Udi Dahan
> 
>  
(Continue reading)

Matt Burton | 1 Feb 02:45
Picon
Gravatar

Re: Re: Handling reporting store read/write contention

In our particular case the view is a historical one, so the tables are
write-only, effectively, as the items which are stored will only come
in once. (there are exceptions but those are irrelevant to the thread)
In a situation where you have data which needs to be updated for a
given view - a users current account balance, etc... - you can still
model that as write-only - you can insert multiple versions of the
same data and just show the last one based on timestamp or version
always. Then have a sensible purge job come along and get rid of the
old versions if appropriate.

HTH,
Matt

On Sun, Jan 31, 2010 at 4:22 PM, llisticc <quang.minh.ngo <at> gmail.com> wrote:
> Hi,
>
> Based on what you've said for reporting doing insert-only may be Ok, although if you we're doing CQRS where
this data is shown to users on screen, I'm a little confused on how this would work?
>
> If you do not update the affected rows, wouldn't you be showing users multiple versions of the same data?
>
> Thanks
> Quang
>
> --- In domaindrivendesign <at> yahoogroups.com, "Udi Dahan" <thesoftwaresimplist@...> wrote:
>>
>> Matt,
>>
>>
>>
(Continue reading)

Quang Ngo | 1 Feb 09:03
Picon

Re: Re: Handling reporting store read/write contention

Cheers Matt for the clarification :).  By doing versioning and purging  
this may be a better approach than updating, especially for cases  
where there are many viewmodels rely on the same event.

Quang

------------------------------------

jbenami1 | 1 Feb 22:07
Picon
Favicon

Re: services and BCs

Nuno, I liked your implementation scenarios (1-4) and your pro/con
discussion. That gives me some insight as far as my original question
goes.
Altogether this discussion, though it went quite abstract, was very
relevant for me. Thank you all.

Cheers
Joni

--- In domaindrivendesign <at> yahoogroups.com, Nuno Lopes <nbplopes@...>
wrote:
>
> Hi Udi,
>
> Thank you for clarifying. So for you an UI mashing up multiple BCs
into a cohesive user experience forms an BC. This even though such BC
might not have a domain model. In this case the UL is interpreted by a
UI Model I would think, but that is not strict DDD is it?
>
> I'm not arguing against that vision, just wanted that clarified.
Having this clarified, I must say I see your point,  and that is why
IMHO DDD as it stands in the blue book lacks greater enterprise insight
IMHO, responding to problems of IT today.
>
> The fact is that in todays enterprise languages from multiple BCs are
orchestrated to create new behavior coping with either new words or
change in enterprise semantics of its context. What techniques are being
used here will probably lead to patterns yet to be found.
>
> What I mean by this:
(Continue reading)

jbenami1 | 1 Feb 22:29
Picon
Favicon

Re: Abacus : sample

Well this looks like some serious work.  Could you say a bit about which
patterns you decided to go with in the architecture (CQRS?)? Also I'd be
interested to see a scenario flowchart, i.e., tracing the flow of a
simple request through the architecture, or the like.

Joni

--- In domaindrivendesign <at> yahoogroups.com, "eben_roux" <ebenroux@...>
wrote:
>
> Hello all,
>
> I have created a sample application to demonstrate various techniques.
It can be used as a foundation and built on to create something that can
point folks to a working piece of software they can use to see an
implementation --- something most people are after.
>
> http://www.ebenroux.co.za/page/Abacus.aspx
>
> As I state on the page I am not happy with everything and there is
quite a bit I still want to add and change but what is there is probably
OK to get started.  I will add documentation about the idea behind the
solution at some point.
>
> For now: it is used to design custom calculations using formula
operations.  Arguments are set up and passed into the system using a
web-based end-point (a message will be added in due course).  The result
is then returned.  Quite simple but may be useful :)
>
> I am off to South-West Africa (nowadays Namibia) so I'll only be back
(Continue reading)

jbenami1 | 1 Feb 23:40
Picon
Favicon

Re: A domain entity bridging two bounded contexts?

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
(Continue reading)

jbenami1 | 1 Feb 23:43
Picon
Favicon

Re: A domain entity bridging two bounded contexts?

> I tend to think of domain services precisely in terms of bridging
> contexts

In "contexts" are you including BCs? This is still a bit confusing to me
I guess. If two BCs are at the same height, i.e., one is not downstream
from the other, should they really be talking to each other? Isn't a BC
supposed to be autonomous?

Joni

--- In domaindrivendesign <at> yahoogroups.com, Dan Haywood <danhaywood@...>
wrote:
>
> On 27/01/2010 22:34, jbenami1 wrote:
> >
> >
> > 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?
> >
> Yup, we do this.  In fact, I think of repositories and factories as
> subtypes of a more general domain service.  This isn't a distinction
> that Evans makes in his book, but it holds up in practice veru well.
>
> I tend to think of domain services precisely in terms of bridging
(Continue reading)

Dan Haywood | 2 Feb 00:29
Favicon

Re: Re: A domain entity bridging two bounded contexts?



On 01/02/2010 22:43, jbenami1 wrote:

> I tend to think of domain services precisely in terms of bridging
> contexts

In "contexts" are you including BCs?

Yup, I meant BCs.


This is still a bit confusing to me
I guess. If two BCs are at the same height, i.e., one is not downstream
from the other, should they really be talking to each other?

Sure they can.  That's what the strategic patterns (open host, published language, anti-corruption layer etc) are all about.

Isn't a BC
supposed to be autonomous?

It defines the boundary in which a UL can be used.  Whenever two BCs interact, we are explicitly recognizing that a translation may be required from the UL of one BC to the UL of another.  Not only a technical (protocol/encoding) translation, but also a business-level semantics translation too.

One BC may well call another, either sync or async.  We use both, but mostly async (and always async if there are transactional issues involved; to use Greg Young's term, the two BCs are then "eventually consistent").

HTH
Dan




Joni

--- In domaindrivendesign <at> yahoogroups. com, Dan Haywood <danhaywood <at> ...>
wrote:
>
> On 27/01/2010 22:34, jbenami1 wrote:
> >
> >
> > 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?
> >
> Yup, we do this. In fact, I think of repositories and factories as
> subtypes of a more general domain service. This isn't a distinction
> that Evans makes in his book, but it holds up in practice veru well.
>
> I tend to think of domain services precisely in terms of bridging
> contexts. Sometimes the contexts are both business-oriented (eg off
to
> the General Ledger), other times we are bridging to a technical domain
> (eg to an Email Sending service). You could think of repositories as
a
> bridge to the technical persistence layer.
>
> That said, there are several 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.
>
> HTH
> Dan
> blog: /http://danhaywood. com/
> book: /Domain Driven Design using Naked Objects/
>




__._,_.___


Your email settings: Individual Email|Traditional
Change settings via the Web (Yahoo! ID required)
Change settings via email: Switch delivery to Daily Digest | Switch to Fully Featured
Visit Your Group | Yahoo! Groups Terms of Use | Unsubscribe

__,_._,___
Favicon

Re: A domain entity bridging two bounded contexts?

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?
> > > > > > > > > > > > >
> > > > > > > > > > > >
> > > > > > > > > > >
> > > > > > > > > >
> > > > > > > > >
> > > > > > > >
> > > > > > >
> > > > > >
> > > > >
> > > >
> > >
> >
>

------------------------------------

leypascua | 2 Feb 02:41
Picon
Favicon
Gravatar

LINQ2SQL, Persistence Ignorance and Domain Models

Hi-

Has anyone here have used LINQ to SQL to support the persistence of domain models?

I'm not planning to use the LINQ2SQL entity designer and I'm currently having roadblocks.

I'm attempting to use it in a DDD example I'm doing, since my audience only knows LINQ2SQL.

What are your experiences with this? 

Your thoughts?

Thanks

Harley

------------------------------------


Gmane