MSDN Magazine - February 2009 - (Page 52) Figure 4 A Simple Application Service public void void void } IPolicyService { Renew(PolicyRenewalDTO renewal); Terminate(PolicyTerminationDTO termination); Write(QuoteDTO quote); public PolicyService : Service { private readonly ILogger _logger; public PolicyService(ILogger logger, IPolicyRepository policies) { _logger = logger; _policies = policies; } public void Renew(PolicyRenewalDTO renewal) { var policy = _policies.Find(renewal.PolicyID); policy.Renew(); var logMessage = string.Format( "Policy {0} was successfully renewed by {1}.", Policy.Number, renewal.RequestedBy); _logger.Log(logMessage); } } toward the more black-box and state-testing paradigm. Aggregate roots and entities often end up as state machines, and the behavior matches accordingly. I end up with state validation, addition, and subtraction. There’s quite a bit of behavior going on in the renewal example in Figure 3, and it’s pretty clear how you can express this in a BDD style of test. Domain Services Model Primary Operations Sometimes you have operations or processes that do not have an identity or lifecycle in your domain. Domain services give you a tool for modeling these concepts. They’re typically stateless and highly cohesive, often providing a single public method and sometimes an overload for acting on sets. I like to use services for a few reasons. When there are a number of dependencies involved in a behavior and I can’t find a natural place on an entity to place that behavior, I’ll use a service. When my Ubiquitous Language talks about a process or operation as a first-order concept, I’ll question whether a service makes sense as a central point of orchestration for the model. You could use a domain service in the case of renewal. This is an alternative style. Rather than method injecting an IAuditNotifier directly into the method of the Policy entity’s Renew method, you might choose to extract a domain service to handle dependency resolution for us; it’s more natural for us to resolve a domain service from an IOC container than an entity. This strategy makes a lot more sense to me when there are multiple dependencies, but I’ll present the alternative anyway. Here is a short example of a domain service: public class PolicyRenewalProcesor { private readonly IAuditNotifier _notifier; public PolicyRenewalProcessor(IAuditNotifier notifier) { _notifier = notifier; } public void Renew(Policy policy) { policy.Renew(); _notifier.ScheduleAuditFor(policy); } The word service is a highly overloaded term in the developer world. Sometimes I think of service as in service-oriented architecture (SOA). Other times I think of services as little classes that don’t represent a particular person, place, or thing in my application, but that tend to embody processes. Domain services usually fall in this latter category. They tend to be named after verbs or business activities that domain experts introduce into the Ubiquitous Language. Application services, on the other hand, are a great way to introduce a layered architecture. They can be used for mapping data inside the domain model to a shape required by a client application. For example, maybe you need to display tabular data in a DataGrid, but you want to maintain a granular and jagged object graph in your model. Application services are also quite useful for integrating multiple models—for example, translating between policy auditing and core policy workflow. Similarly, I use them to bring infrastructure dependencies into the mix. Imagine a common scenario where you want to expose your domain model with Windows Communication Foundation (WCF). I’d use an application service decorated with the WCF attributes to make this happen rather than letting WCF leak into my pure domain model. Application services tend to be very broad and shallow, embodying cohesive functionality. Consider the interface and partial implementation you see in the code in Figure 4 as a good example of an application service. Repositories Save and Dispense Aggregate Roots Where do you go to retrieve entities? How do you store them? These questions are answered by the Repository pattern. Repositories represent an in-memory collection, and the conventional wisdom is that you end up with one repository per aggregate root. Repositories are a good candidate for a super class or what Martin Fowler refers to as the Layer Supertype pattern. Using generics DDD resources The Official DDD Site domaindrivendesign.org Dan North on How to Structure User Stories dannorth.net/whats-in-a-story The Big Ball of Mud Architectural Style laputan.org/mud Greg Young’s Blog on CodeBetter codebetter.com/blogs/gregyoung Robert C. Martin’s Paper on Single Responsibility Principle objectmentor.com/resources/articles/srp.pdf Brad Appleton on Law of Demeter cmcrossroads.com/bradapp/docs/demeter-intro.html Martin Fowler Describes the Layer Supertype Pattern martinfowler.com/eaaCatalog/layerSupertype.html Robert C. Martin on the S.O.L.I.D. Principles butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod Domain-Driven Design } 52 msdn magazine http://www.domaindrivendesign.org http://www.dannorth.net/whats-in-a-story http://www.laputan.org/mud http://www.codebetter.com/blogs/gregyoung http://objectmentor.com/resources/articles/srp.pdf http://cmcrossroads.com/bradapp/docs/demeter-intro.html http://martinfowler.com/eaaCatalog/layerSupertype.html http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod
Table of Contents Feed for the Digital Edition of MSDN Magazine - February 2009 MSDN Magazine - February 2009 Contents Toolbox CLR Inside Out Data Points Cutting Edge Patterns In Practice Best Practices .Net Interop "Oslo" Basics Patterns Silverlight Under The Table Foundations Windows With C++ .NET Matters Going Places { End Bracket } MSDN Magazine - February 2009 MSDN Magazine - February 2009 - (Page Splash1) MSDN Magazine - February 2009 - Contents (Page Cover1) MSDN Magazine - February 2009 - Contents (Page Cover2) MSDN Magazine - February 2009 - Contents (Page 1) MSDN Magazine - February 2009 - Contents (Page 2) MSDN Magazine - February 2009 - Contents (Page 3) MSDN Magazine - February 2009 - Contents (Page 4) MSDN Magazine - February 2009 - Contents (Page 5) MSDN Magazine - February 2009 - Contents (Page 6) MSDN Magazine - February 2009 - Contents (Page 7) MSDN Magazine - February 2009 - Contents (Page 8) MSDN Magazine - February 2009 - Contents (Page 9) MSDN Magazine - February 2009 - Contents (Page 10) MSDN Magazine - February 2009 - Toolbox (Page 11) MSDN Magazine - February 2009 - Toolbox (Page 12) MSDN Magazine - February 2009 - Toolbox (Page 13) MSDN Magazine - February 2009 - Toolbox (Page 14) MSDN Magazine - February 2009 - CLR Inside Out (Page 15) MSDN Magazine - February 2009 - CLR Inside Out (Page 16) MSDN Magazine - February 2009 - CLR Inside Out (Page 17) MSDN Magazine - February 2009 - CLR Inside Out (Page 18) MSDN Magazine - February 2009 - CLR Inside Out (Page 19) MSDN Magazine - February 2009 - CLR Inside Out (Page 20) MSDN Magazine - February 2009 - CLR Inside Out (Page 21) MSDN Magazine - February 2009 - CLR Inside Out (Page 22) MSDN Magazine - February 2009 - Data Points (Page 23) MSDN Magazine - February 2009 - Data Points (Page 24) MSDN Magazine - February 2009 - Data Points (Page 25) MSDN Magazine - February 2009 - Data Points (Page 26) MSDN Magazine - February 2009 - Data Points (Page 27) MSDN Magazine - February 2009 - Data Points (Page 28) MSDN Magazine - February 2009 - Data Points (Page 29) MSDN Magazine - February 2009 - Data Points (Page 30) MSDN Magazine - February 2009 - Cutting Edge (Page 31) MSDN Magazine - February 2009 - Cutting Edge (Page 32) MSDN Magazine - February 2009 - Cutting Edge (Page 33) MSDN Magazine - February 2009 - Cutting Edge (Page 34) MSDN Magazine - February 2009 - Cutting Edge (Page 35) MSDN Magazine - February 2009 - Cutting Edge (Page 36) MSDN Magazine - February 2009 - Cutting Edge (Page 37) MSDN Magazine - February 2009 - Cutting Edge (Page 38) MSDN Magazine - February 2009 - Patterns In Practice (Page 39) MSDN Magazine - February 2009 - Patterns In Practice (Page 40) MSDN Magazine - February 2009 - Patterns In Practice (Page 41) MSDN Magazine - February 2009 - Patterns In Practice (Page 42) MSDN Magazine - February 2009 - Patterns In Practice (Page 43) MSDN Magazine - February 2009 - Patterns In Practice (Page 44) MSDN Magazine - February 2009 - Patterns In Practice (Page 45) MSDN Magazine - February 2009 - Best Practices (Page 46) MSDN Magazine - February 2009 - Best Practices (Page 47) MSDN Magazine - February 2009 - Best Practices (Page 48) MSDN Magazine - February 2009 - Best Practices (Page 49) MSDN Magazine - February 2009 - Best Practices (Page 50) MSDN Magazine - February 2009 - Best Practices (Page 51) MSDN Magazine - February 2009 - Best Practices (Page 52) MSDN Magazine - February 2009 - Best Practices (Page 53) MSDN Magazine - February 2009 - Best Practices (Page 54) MSDN Magazine - February 2009 - Best Practices (Page 55) MSDN Magazine - February 2009 - Best Practices (Page 56) MSDN Magazine - February 2009 - .Net Interop (Page 57) MSDN Magazine - February 2009 - .Net Interop (Page 58) MSDN Magazine - February 2009 - .Net Interop (Page 59) MSDN Magazine - February 2009 - .Net Interop (Page 60) MSDN Magazine - February 2009 - .Net Interop (Page 61) MSDN Magazine - February 2009 - .Net Interop (Page 62) MSDN Magazine - February 2009 - "Oslo" Basics (Page 63) MSDN Magazine - February 2009 - "Oslo" Basics (Page 64) MSDN Magazine - February 2009 - "Oslo" Basics (Page 65) MSDN Magazine - February 2009 - "Oslo" Basics (Page 66) MSDN Magazine - February 2009 - "Oslo" Basics (Page 67) MSDN Magazine - February 2009 - "Oslo" Basics (Page 68) MSDN Magazine - February 2009 - "Oslo" Basics (Page 69) MSDN Magazine - February 2009 - "Oslo" Basics (Page 70) MSDN Magazine - February 2009 - "Oslo" Basics (Page 71) MSDN Magazine - February 2009 - Patterns (Page 72) MSDN Magazine - February 2009 - Patterns (Page 73) MSDN Magazine - February 2009 - Patterns (Page 74) MSDN Magazine - February 2009 - Patterns (Page 75) MSDN Magazine - February 2009 - Patterns (Page 76) MSDN Magazine - February 2009 - Patterns (Page 77) MSDN Magazine - February 2009 - Patterns (Page 78) MSDN Magazine - February 2009 - Patterns (Page 79) MSDN Magazine - February 2009 - Patterns (Page 80) MSDN Magazine - February 2009 - Patterns (Page 81) MSDN Magazine - February 2009 - Patterns (Page 82) MSDN Magazine - February 2009 - Patterns (Page 83) MSDN Magazine - February 2009 - Silverlight (Page 84) MSDN Magazine - February 2009 - Silverlight (Page 85) MSDN Magazine - February 2009 - Silverlight (Page 86) MSDN Magazine - February 2009 - Silverlight (Page 87) MSDN Magazine - February 2009 - Silverlight (Page 88) MSDN Magazine - February 2009 - Silverlight (Page 89) MSDN Magazine - February 2009 - Silverlight (Page 90) MSDN Magazine - February 2009 - Silverlight (Page 91) MSDN Magazine - February 2009 - Silverlight (Page 92) MSDN Magazine - February 2009 - Silverlight (Page 93) MSDN Magazine - February 2009 - Silverlight (Page 94) MSDN Magazine - February 2009 - Under The Table (Page 95) MSDN Magazine - February 2009 - Under The Table (Page 96) MSDN Magazine - February 2009 - Under The Table (Page 97) MSDN Magazine - February 2009 - Under The Table (Page 98) MSDN Magazine - February 2009 - Under The Table (Page 99) MSDN Magazine - February 2009 - Under The Table (Page 100) MSDN Magazine - February 2009 - Foundations (Page 101) MSDN Magazine - February 2009 - Foundations (Page 102) MSDN Magazine - February 2009 - Foundations (Page 103) MSDN Magazine - February 2009 - Foundations (Page 104) MSDN Magazine - February 2009 - Foundations (Page 105) MSDN Magazine - February 2009 - Foundations (Page 106) MSDN Magazine - February 2009 - Windows With C++ (Page 107) MSDN Magazine - February 2009 - Windows With C++ (Page 108) MSDN Magazine - February 2009 - Windows With C++ (Page 109) MSDN Magazine - February 2009 - Windows With C++ (Page 110) MSDN Magazine - February 2009 - .NET Matters (Page 111) MSDN Magazine - February 2009 - .NET Matters (Page 112) MSDN Magazine - February 2009 - .NET Matters (Page 113) MSDN Magazine - February 2009 - .NET Matters (Page 114) MSDN Magazine - February 2009 - Going Places (Page 115) MSDN Magazine - February 2009 - Going Places (Page 116) MSDN Magazine - February 2009 - Going Places (Page 117) MSDN Magazine - February 2009 - Going Places (Page 118) MSDN Magazine - February 2009 - Going Places (Page 119) MSDN Magazine - February 2009 - { End Bracket } (Page 120) MSDN Magazine - February 2009 - { End Bracket } (Page Cover3) MSDN Magazine - February 2009 - { End Bracket } (Page Cover4)
For optimal viewing of this digital publication, please enable JavaScript and then refresh the page. If you would like to try to load the digital publication without using Flash Player detection, please click here.