Yay!! 2 days of blogging at lunch (then at home, time crunch today so excuse the hurried format) in a row, keeping on track. In DDDD 1 we looked at boundaries where messaging is applicable / good. We will in the future look more at why we would want to message on those boundaries but first it is time to see how messaging may impact our ubiquitous language which is imho the most important part of Domain Driven Design.
The largest place that our ubiquitous language is changed is in dealing with infrastructure services within our domain. As has been written about Java, C# tends to be the land of the nouns. Unfortunately this creeps into our domain and we end often with many nouns in our language that only represent gateways to verbs. An example may make this more clear ...
Do you have an EmailGateway, IEmailGteway : EmailProvider, IEmailer, DomainContext.Current.EmailProvider.SendEmail(email), etc in your domain? Is it part of your ubiquitous language? How do you discuss the action of SENDING an email? Why is it that this verb has become an interaction with a noun?
I have seen some go much further than this as well under the guise of loose coupling (read testability). I have even seen people going to the point of injecting things like email providers directly into domain objects. This is a great example of technical details leaking into the domain (even with dependency injection).
Domain Driven Design is not all about nouns; it is more so about verbs (and some very important adjectives/adverbs ;-)). Verbs are the most important parts of our ubiquitous language as they define interactions which in turn defines our nouns, consider this in comparison with active record where the process tends to be reversed. The introduction of nouns such as EmailProvider to support our verbs such as SendEmail not only is artificial but it also distracts our attention from the domain verb of sending an email and focuses it on the noun that is doing it. There is no need for this noun to be in our ubiquitous language therefor there is also no reason for it to exist in our model.
By replacing the interaction with a Message we gain in terms of our Ubiquitous Language. Let's imagine a contrived example of printing a purchase order to a file at the completion of it being created. Instead of introducing a FileDocumentPrinter that has a method Print<PurchaseOrder> on it that we would then have to deal with the injecting of ... We would introduce a first class domain concept of a PrintPurchaseOrderDocumentMessage ...
One valid argument here is that PrintPurchaseOrderDocumentMessage is still a noun but in conversation it loses its suffix and becomes PrintPurchaseOrderDocument. We have quite a few of these in our domain InsertTrade, CancelOrder, MarkOrderAsKnownTrader. One could make the argument that they should be renamed without the suffix but I have found that it can be confusing for developers to not have the suffix. Another idea I have been working with is to instead give a prefix such as Do for these style messages or to use a fluent builder ala A use for extension methods and prefix it with Actions. then have the creations work with the verb.
By replacing with a message we have removed the nouns from our discussion, and at the same time lowered our coupling to the actual services involved. We can at runtime bind up our infrastructure and our domain (and ubiquitous language) are blissfully unaware of the mechanism that we use to hook it up.
Another interesting note here is a subtle difference between the Ubiquitous Language and the model implementation is the synchronous vs asynchronous behaviors of any method based approach. When do I consider it ok to continue in terms of the printing being done? Is it when the document is done or when I told it to do it? This can lead to bugs in the implementation as well as a much less fleshed out domain model. Messaging makes this interaction specific in the Ubiquitous Language, if it is not waiting on a reply the action is considered to be asynchronous.
Later ... I will come back to this topic in terms of Repositories and making the implicit explicit but there is alot to cover first.
Posted
Fri, Apr 11 2008 12:33 AM
by
Greg