Udi Dahan | 1 Jan 09:48
Picon

Re: Using DDD for Order processing

On the issue of “adding an order item needs to update the product inventory”, well, it probably doesn’t.

 

As long as you know you have enough inventory for the order, you can move forwards.

 

Only after you’ve accepted the order (which could mean billing the customer, or not, if they’re a corporate customer in which case you may do monthly billing, COD, whatever), then you can go about managing inventory.

 

That being said, inventory management is a different bounded context than order processing. For instance, you can accept an order for a product that is out of stock (minded you tell the user and they order anyway).

 

Between these bounded contexts I’d suggest using an event-style interaction where your order processing publishes an OrderAccepted event that inventory management is subscribed to. You don’t share transactions between these bounded contexts, such that each does its own transaction.

 

For a more detailed description of the events between these bounded contexts, see:

 

http://www.udidahan.com/2008/11/01/soa-eda-and-cep-a-winning-combo/

 

Hope that helps,

 

--
Udi Dahan - The Software Simplist
Enterprise Development Expert & SOA Specialist

 

__._,_.___

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

__,_._,___
Casey Charlton | 1 Jan 10:48
Picon
Gravatar

Re: Re: Using DDD for Order processing

That was my thought when I browsed this question ... having written a number of ecommerce systems, the ordering and inventory parts have rarely had muchto do with each other. Ordering requires conirmation that it is likely to be possible to ship (likely because writing a locking system over stock is not only very complicated, but also pretty pointless in reality), and only when a payment is taken and the order is confirmed does inventory need to be involved, as part of the Fulfillment.


 
2009/1/1 Udi Dahan <thesoftwaresimplist <at> gmail.com>

On the issue of "adding an order item needs to update the product inventory", well, it probably doesn't.

 

As long as you know you have enough inventory for the order, you can move forwards.

 

Only after you've accepted the order (which could mean billing the customer, or not, if they're a corporate customer in which case you may do monthly billing, COD, whatever), then you can go about managing inventory.

 

That being said, inventory management is a different bounded context than order processing. For instance, you can accept an order for a product that is out of stock (minded you tell the user and they order anyway).

 

Between these bounded contexts I'd suggest using an event-style interaction where your order processing publishes an OrderAccepted event that inventory management is subscribed to. You don't share transactions between these bounded contexts, such that each does its own transaction.

 

For a more detailed description of the events between these bounded contexts, see:

 

http://www.udidahan.com/2008/11/01/soa-eda-and-cep-a-winning-combo/

 

Hope that helps,

 

--
Udi Dahan - The Software Simplist
Enterprise Development Expert & SOA Specialist

 


__._,_.___

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

__,_._,___
Peter Morris | 1 Jan 16:03
Picon
Gravatar

Re: Re: Pessimistic locking

>  There are other ways of making state durable than "throwing it in the 
> database"

I'd certainly be keen for you to tell me what they are :-)

> Frankly keeping something like locks in memory inside of ASP.NET
> sounds like a really bad idea to me.

To me too, but I think it would be less complicated than using a DB.

> How do
> you even know that it is a pessimistic lock from another user blocking
> you and not some multi-threaded code somewhere that is in a deadlock?

With in-memory locks I would be able to place the entire lock within a 
single lock() statement.  Only 1 thread at a time can place / remove locks. 
The fact that I will be using coarse grained locks and only on a few 
structures means that I wont be acquiring or releasing locks very often. 
However, sometimes locking a specific object will also involve locking 
children, grandchildren, and great grand children also because changes to 
this object will propagate changes to all of those objects.  Locking these 
objects would be a single call to AcquireLocks(), so only a single call but 
lots of objects to lock.  In a DB I think this might take quite some time, 
whereas in memory it would be very quick.

> How can I view all the pessimistic locks that are currently held?

I would be able to read the data structures.

> An interesting side discussion is that in terms of later scaling YAGNI
> can't really apply here i.e. an in memory version can be used now then
> later a different shared state version could be dropped in to support
> say multiple servers. This is unfortunately not the case and it would
> fall under a few of the fallacies of distributed computing
> http://en.wikipedia.org/wiki/Fallacies_of_Distributed_Computing. The
> key bit being when you move to distribution you will probably prefer
> to pessimistically lock objects in groups as opposed to one by one
> which would likely work great for an in memory implementation.

I don't intend to pessimistic lock every object in the system.  Most of the 
objects will have a time stamp.  It's only these specific related structures 
where I will need pessimistic locking.  The structure goes something like 
this

[TemplateDefinition]
Properties (one to many association to TemplateDefinitionProperty)
Templates (one to many association to Template)

[Template]
Properties (one to many association to TemplateProperty)
Instances (one to many association to TemplateInstance)

[TemplateInstance]
Properties (one to many association to TemplateInstanceProperty)

To edit any of the properties of any of these structures you will need to 
first lock the object that owns it, I wont be applying locks to individual 
properties as the structure is always edited as a whole.  In addition to 
this

01: A Template is created from a TemplateDefinition.  To create the Template 
I will first have to place a shared-read lock on TemplateDefinition to 
ensure it doesn't change until I have finished creating the Template.
02: A TemplateInstance is created from a Template.  As above I will first 
place a shared-read lock on its TemplateDefinition.

This factory process takes milliseconds.

and now the big one.  The user cannot add/remove properties on any of these 
structures, they can only set values on the properties.  When the structure 
of TemplateDefinition changes it is re-imported from a file.  To import I 
will need to do this

Requirement:
Prevent any new Templates or TemplateInstances from being created that are 
ultimately based on this TemplateDefinition.

Solution:
Acquire a write lock on the TemplateDefinition.

Requirement:
Any new properties added to the TemplateDefinition will need relevant 
properties added to Template and TemplateInstance.  Any properties removed 
will need removing from Template and TemplateInstance.

Solution:
Acquire write locks on all Templates and TemplateInstances based on the 
TemplateDefinition being re-imported.

This is a lot of locking, but as you can see I only lock the aggregate root 
and not all of the properties too.  Writing out this email it has occurred 
to me that to speed things up I could not only implement reader/writer locks 
for editing these objects but on TemplateDefinition I could have an 
additional lock object.

For normal use
A: To edit a TemplateInstance you need
    a write lock on TemplateInstance.EditLock
    a read lock on TemplateInstance.Template.TemplateDefinition.ImportLock

B: To edit a Template you need
    a write lock on Template.EditLock
    a read lock on Template.TemplateDefinition.ImportLock

C: To edit a TemplateDefinition you need
    a write lock on TemplateDefinition.EditLock
    a read lock on TemplateDefinition.ImportLock

Then to import a TemplateDefinition I only need to place a single write 
lock, on TemplateDefinition.ImportLock.  This effectively acts like a 
super-lock for an individual TemplateDefinition, it's Templates, and their 
TemplateInstances.

Okay, that seems like a *lot* less locking!  This means that one of my two 
concerns about using a DB (lots of disk work) has been addressed.  There was 
one more concern I had with using a DB and this is related to session 
timeouts.

Session time outs
============
If I store a session in a table I can then have a link table between Session 
and Lock with a reference count in it, which would allow me to have multiple 
read locks on an object for the same session and allow my code to be 
reentrant.  The client (a Silverlight app) will ping the server every 30 
seconds for example to tell it that it is still alive, I can then update the 
relevant row in the DB with the last alive time.

When I need to know "Can I place write lock on this lock object?" I first 
need to check that there are no read locks.  Rather than simply checking 
there are none I will need to check there are none related to sessions that 
have not timed out.  Rather than taking that approach maybe I should have a 
thread that runs in my app layer than checks every 60 seconds for sessions 
with an expired ping time and deletes those + any locks they have held. 
This would be much more efficient I expect.

Pete
====
http://mrpmorris.blogspot.com
http://www.capableobjects.com - Think domain, not database 

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

Carfield Yim | 2 Jan 07:03
Picon

Re: Using DDD for Order processing

Just see this discussion, IMHO I think the problem of Anemic Object is that there are multiple services class access directly to the data model ( or database fields) to do various processing, once the data model change, a lot of service class need to change, and the worst part is sometime you are not aware until deliver to user :-/ . 

I found it is easy to ending up with something like  Anemic domain model if you start from the requirement, to data model ( schema ) , then coding. If you do strickly TDD, you probably end up with difference design :-)

It is hard to comment if  Anemic domain model with command pattern is good enough or not, I think if you already come up enough amount of coding, can think about try adding some 1 / 2 fields in DB, and see how many service class need to change.

On Wed, Dec 31, 2008 at 6:13 AM, ericpopivker <eric <at> entechsolutions.com> wrote:

I am trying to come up with DDD approach to Order processing, but I
keep ending up with something like Anemic Domain Model.

Unlike many of the simple examples, almost every action in my Order
processing is dependent on several aggregates, entities or external
services. For ex:

1. AddOrderItem - needs to update Product Inventory
2. TakePayment - use external payment services
3. Ship - use external shipping services
4. CalculateTotal - uses TaxCalculator

So I have something like this:

=============================

//Entity
Order
{
Status;
OrderLines;
DateCreated;
...

}

//Domain services
AddOrderLineCommand
{
_productInventoryService; //injected


Execute() {...};
}

TakePaymentCommand
{
_paymentService; //Injected


Execute() {...};
}

...

//Application services
OrderService
{
_orderRepository; //injected

[Transaction]
AddOrderLine(Order, Product, quantity);
{

AddOrderLineCommand command=new AddOrderLineCommand(Order, Product,
quantity);
command.Execute();

_orderRepository.UpdateOrder(order);
}

[Transaction]
TakePayment(Order);
{

}

}
========================

The issue is that once again there is no logic in Order entity. All
logic is in Domain Services.

Does this approach follow DDD? Is it just Anemic domain model with
command pattern?


__._,_.___

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

__,_._,___
Rickard Öberg | 2 Jan 11:19
Picon
Gravatar

Re: DDD vs canned data model

Peter Morris wrote:
> Hi Rickard
> 
>  > This looks similar to what you can do with Qi4j today in Java. The above
>  > would be as follows in Qi4j:
>  > interface PersonEntity
>  > extends Customer, Supplier, Nameable, ..., EntityComposite
>  > {}
> 
> I don't really understand your example :-) Let me reillustrate what I mean
> and then if it is the same thing maybe a different example from you will
> clear up what you meant?
> 
> [aspect:StockHolder]
> public class Person
> {
> }
> 
> [aspect:StockHolder]
> public class StoreRoom
> {
> }
> 
> I could now write code like this (even within the Person/StoreRoom classes)
> 
> StockTransfer st = new StockTransfer(bensonAndHedges20, person1, 
> storeroom2,
> 100);
> 
> This is because the aspect actually alters the compilers understanding of
> the class during the compilation process, so you can typecast to an aspect
> introduced interface for example without a compiler error, or see aspect
> introduced members (methods / properties / etc) in code-insight.
> 
> Although I don't write in Java I'd still be interested in knowing if it 
> does
> the same kind of thing, or if it is a post-compile operation (as it is in
> PostSharp).

Right, what we have done is to simply say that ALL functionality in an 
object comes from aspects, meaning, in your example Person and StoreRoom 
would have no state and no methods. They're only there as something to 
put the "aspects" on top of. The assembly of fragments, which we call a 
Composite.

The syntax I used is plain Java. Like so:
interface PersonEntity
   extends Customer, Supplier, Nameable, ..., EntityComposite
{}

This is just a regular interface, which extends other regular 
interfaces. Because of this, if you have a reference to a PersonEntity 
you can in your IDE do code completion on all the methods that are 
included as "aspects". This not only gives you typesafety, but also IDE 
convenience.

The "magic" in Qi4j comes when those regular interfaces (which you would 
NEVER implement using just plain Java, because typically you would have 
10-15 interfaces as "aspects" and you would then have to implement all 
of them in ONE class) are to be mapped to implementation methods. You 
then write a mixin with the actual implementation. Like so:
interface Nameable
{
   String getName();
   void setName(String name);
}
is the "aspect", and then the implementation is:
public class NameableMixin implements Nameable
{
   String name;
   String getName() { return name; }
   void setName(String name) { this.name = name; }
}
which is matched to the interface through an annotation on the PersonEntity:
@Mixins({NameableMixin.class,...})
interface PersonEntity
   extends Nameable, ...
{}

The ability to instantiate the "huge" interface PersonEntity with a 
proxy that delegates to NameableMixin on calls to Nameable is the basis 
for Qi4j (and then a whole lot more). This allows for the creation of 
"nice to have" aspects, as you said, and then put them together using 
the "super interfaces" (or Composite declarations as we call them). I 
have built a large commercial CMS/portal product using this technique, 
and it is very nice IMO.

I hope this makes it clear!

/Rickard

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

Justin Daubenmire | 2 Jan 21:07
Picon
Favicon

DDD fog need clarification



#ygrp-mkp { BORDER-RIGHT: #d8d8d8 1px solid; PADDING-RIGHT: 14px; BORDER-TOP: #d8d8d8 1px solid; PADDING-LEFT: 14px; PADDING-BOTTOM: 0px; MARGIN: 14px 0px; BORDER-LEFT: #d8d8d8 1px solid; PADDING-TOP: 0px; BORDER-BOTTOM: #d8d8d8 1px solid; FONT-FAMILY: Arial } #ygrp-mkp HR { BORDER-RIGHT: #d8d8d8 1px solid; BORDER-TOP: #d8d8d8 1px solid; BORDER-LEFT: #d8d8d8 1px solid; BORDER-BOTTOM: #d8d8d8 1px solid } #ygrp-mkp #hd { FONT-WEIGHT: bold; FONT-SIZE: 85%; MARGIN: 10px 0px; COLOR: #628c2a; LINE-HEIGHT: 122% } #ygrp-mkp #ads { MARGIN-BOTTOM: 10px } #ygrp-mkp .ad { PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; PADDING-TOP: 0px } #ygrp-mkp .ad A { COLOR: #0000ff; TEXT-DECORATION: none }
All,
 
I have to present on the basics of DDD this Monday. I was jotting down some notes and was wanting to confirm my thoughts so if others can help me focus on where I may be off some that would be appreciated!
 
A very highlevel description of DDD...
 
There are 4 layers in DDD:
 
1. UI
2. Application
3. Domain
4. Infrastructure
 
Notes (please clarify if incorrect):
 
1. In strictest theory, layers can only depend downwards, there cannot be a dependency upwards?
 
2. UI communicates to application layer which has services.
 
3. services communicate to repositories in domain layer.
 
4. repositories are part of domain layer.
 
5. Repositories return DTO objects and not domain objects to the service layer, which in turn returns the information to the UI layer.
 
6. Repositories communicate to domain layer objects? Or do repositories communicate to the infrastructure layer?
 
7. Domain layer objects communicate to infrastructure layer - database/xml/file etc. ?
 
Note: I am a bit fuzzy when it comes to the communication from repositories... do repositories communicate to the domain layer? infrastructure layer? In what layer are domain objects mapped to DTO's and returned to the application / service layer?
 
Thanks for any input guys!
 
Regards,
Justin
 
__._,_.___

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

__,_._,___
Angel Java Lopez | 2 Jan 21:22
Picon

Re: DDD fog need clarification

Short answers about 5:

Repositories doesn't return DTO, they return domain objects. Any needed DTO, I guess, is usually generated from service, returning to UI or another application.
 
About 6: repositories can manage, in test case, all-in-memory implementation, but in production, they invoke infrastructure for persistence.
 
About 7: in most cases, in the domain layer, only repositories call infrastructure objects
 
Angel "Java" Lopez
http://ajlopez.wordpress.com

 
On Fri, Jan 2, 2009 at 6:07 PM, Justin Daubenmire <jdaubenm <at> yahoo.com> wrote:



All,
 
I have to present on the basics of DDD this Monday. I was jotting down some notes and was wanting to confirm my thoughts so if others can help me focus on where I may be off some that would be appreciated!
 
A very highlevel description of DDD...
 
There are 4 layers in DDD:
 
1. UI
2. Application
3. Domain
4. Infrastructure
 
Notes (please clarify if incorrect):
 
1. In strictest theory, layers can only depend downwards, there cannot be a dependency upwards?
 
2. UI communicates to application layer which has services.
 
3. services communicate to repositories in domain layer.
 
4. repositories are part of domain layer.
 
5. Repositories return DTO objects and not domain objects to the service layer, which in turn returns the information to the UI layer.
 
6. Repositories communicate to domain layer objects? Or do repositories communicate to the infrastructure layer?
 
7. Domain layer objects communicate to infrastructure layer - database/xml/file etc. ?
 
Note: I am a bit fuzzy when it comes to the communication from repositories... do repositories communicate to the domain layer? infrastructure layer? In what layer are domain objects mapped to DTO's and returned to the application / service layer?
 
Thanks for any input guys!
 
Regards,
Justin
 


__._,_.___

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

__,_._,___
ericpopivker | 2 Jan 21:29

Re: Using DDD for Order processing

Hi Casey,

I see your point.  

In current system there is a business requirement that I can only add
product to Order if it is available in stock.  I was trying to keep it
simple and just decrease inventory as soon as customer added product
to order.  There is an agent that replenishes the inventory in case
the order is not completed in 2 hours.

It does makes a lot of sense to add
ProductInventory.ReserveQuantity(), so that actual ProductInventory
doesn't actually change until Order is shipped. 

Thank you,

Eric

--- In domaindrivendesign <at> yahoogroups.com, "Casey Charlton"
<casey@...> wrote:
>
> That was my thought when I browsed this question ... having written
a number
> of ecommerce systems, the ordering and inventory parts have rarely had
> muchto do with each other. Ordering requires conirmation that it is
likely
> to be possible to ship (likely because writing a locking system over
stock
> is not only very complicated, but also pretty pointless in reality), and
> only when a payment is taken and the order is confirmed does
inventory need
> to be involved, as part of the Fulfillment.
> 
> 
> 
> 2009/1/1 Udi Dahan <thesoftwaresimplist@...>
> 
> >    On the issue of "adding an order item needs to update the product
> > inventory", well, it probably doesn't.
> >
> >
> >
> > As long as you know you have enough inventory for the order, you
can move
> > forwards.
> >
> >
> >
> > Only after you've accepted the order (which could mean billing the
> > customer, or not, if they're a corporate customer in which case
you may do
> > monthly billing, COD, whatever), then you can go about managing
inventory.
> >
> >
> >
> > That being said, inventory management is a different bounded
context than
> > order processing. For instance, you can accept an order for a
product that
> > is out of stock (minded you tell the user and they order anyway).
> >
> >
> >
> > Between these bounded contexts I'd suggest using an event-style
interaction
> > where your order processing publishes an OrderAccepted event that
inventory
> > management is subscribed to. You don't share transactions between
these
> > bounded contexts, such that each does its own transaction.
> >
> >
> >
> > For a more detailed description of the events between these bounded
> > contexts, see:
> >
> >
> >
> > http://www.udidahan.com/2008/11/01/soa-eda-and-cep-a-winning-combo/
> >
> >
> >
> > Hope that helps,
> >
> >
> >
> > --
> > Udi Dahan - The Software Simplist
> > Enterprise Development Expert & SOA Specialist
> >
> >
> >
> > 
> >
>

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

ericpopivker | 2 Jan 21:49

Re: Using DDD for Order processing

Hi Udi,

With this approach - the Ordering context knows about Inventory
context and vica versa.  

How would it work if I use a 3rd party inventory management system and
I can't add a handler directly to that Inventory Service.  I presume,
I would have to create a facade on the 3rd party inventory system and
add event handler there.

In this type of system wouldn't there be a lot of bi-directional
dependencies?  So bounded contexts for: 

Billing
Shipping
Inventory Management
... and any other systems used during Order processing would need to
be aware of Order processing.

Is all the event handling implemented in Application Services layer or
is it a part of Domain?

Eric

--- In domaindrivendesign <at> yahoogroups.com, "Udi Dahan"
<thesoftwaresimplist@...> wrote:
>
> On the issue of "adding an order item needs to update the product
> inventory", well, it probably doesn't.
> 
>  
> 
> As long as you know you have enough inventory for the order, you can
move
> forwards.
> 
>  
> 
> Only after you've accepted the order (which could mean billing the
customer,
> or not, if they're a corporate customer in which case you may do monthly
> billing, COD, whatever), then you can go about managing inventory.
> 
>  
> 
> That being said, inventory management is a different bounded context
than
> order processing. For instance, you can accept an order for a
product that
> is out of stock (minded you tell the user and they order anyway).
> 
>  
> 
> Between these bounded contexts I'd suggest using an event-style
interaction
> where your order processing publishes an OrderAccepted event that
inventory
> management is subscribed to. You don't share transactions between these
> bounded contexts, such that each does its own transaction.
> 
>  
> 
> For a more detailed description of the events between these bounded
> contexts, see:
> 
>  
> 
> http://www.udidahan.com/2008/11/01/soa-eda-and-cep-a-winning-combo/
> 
>  
> 
> Hope that helps,
> 
>  
> 
> -- 
> Udi Dahan - The Software Simplist
> Enterprise Development Expert & SOA Specialist
>

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

Colin Jack | 2 Jan 21:50
Picon
Gravatar

Re: DDD fog need clarification

> 1. In strictest theory, layers can only depend downwards, there 
> cannot be a dependency upwards?

Not sure there's any real rules but it seems sensible. Depends on 
what you need tho.

> 2. UI communicates to application layer which has services.

Thats definitely an approach, some have UI talk to 
repositories/services/entities.

> 3. services communicate to repositories in domain layer.

Yup, but as I say earlier thats not the only way to do things.

> 4. repositories are part of domain layer.

Their interfaces are in many cases, implementations are something 
that most people keep seperate.

> 5. Repositories return DTO objects and not domain objects to the 
> service layer, which in turn returns the information to the UI 
> layer.

Repositories return aggregate root entities, not DTOs. Domain 
services also work in terms of entities but you might, for example, 
want the application layer to map these to DTOs to return (no rule).

> 6. Repositories communicate to domain layer objects? Or do 
> repositories communicate to the infrastructure layer?

Repositories work with aggregate roots, and yeah they'd communicate 
with infrastructure (directly or indirectly).

> 7. Domain layer objects communicate to infrastructure layer - 
> database/xml/file etc. ?

Nope, I prefer to keep my entities/value objects/specifications etc 
completely isolated from infrastructure.

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


Gmane