tag:blogger.com,1999:blog-326094502018-05-13T09:54:29.524+01:00Colin Jack's BlogTechnical blog.Colin Jackhttp://www.blogger.com/profile/01403166737046938219noreply@blogger.comBlogger156125tag:blogger.com,1999:blog-32609450.post-24459164489253848322009-10-26T22:45:00.002+00:002009-10-26T22:57:48.262+00:00SOA Manifesto<p>I've just gotten through reading the <a href="http://soa-manifesto.org/">SOA Manifesto</a> and reactions from (among others) <a href="http://jim.webber.name/2009/10/24/95bf2681-9a7a-4f94-94d6-2156a3a46411.aspx">Jim Webber</a> and <a href="http://www.innoq.com/blog/st/2009/10/comments_on_the_soa_manifesto.html">Stefan Tilkov</a> and I can't help feeling the whole thing is a missed opportunity. </p> <p>In particular you'll notice is that the manifesto doesn't deal with the "what is a service" issue and so fails to deal with the <a href="http://martinfowler.com/bliki/ServiceOrientedAmbiguity.html">Service Oriented Ambiguity</a> issue. Although Martin Fowler covers multiple ways of viewing services in his post I think two are probably most relevant when considering the manifesto:</p> <ol> <li><strong>Business Level SOA (B-SOA)</strong> - Services for business capabilities/functions (think <a href="http://www.infoq.com/minibooks/domain-driven-design-quickly">Strategic Design in DDD</a>, <a href="http://www.infoq.com/minibooks/enterprise-soa">Enterprise SOA</a>). This approach focuses on bringing IT and the business together and in my view should lead to large and loosely coupled autonomous services. </li> <li><strong>Technical Level SOA (T-SOA)</strong> - Services here are the individual endpoints. These end-points could be Web Services (RPC/WS-*), they could be resources (REST), they could be messaging endpoints, or they could be something else.Each B-SOA service exposes one or more T-SOA services. </li> </ol> <p><a href="http://www.innoq.com/blog/st/2007/09/27/faq_entry_whats_this_rest_vs_soa_debate_about.html">Stefan Tilkov</a> has a good blog entry about the two which is worth a read, and with these two types of SOA in mind its worth looking at the values in the manifesto to see how each apply in each context (context is king).</p> <p><strong>Values In Context</strong></p> <p>Whether considering T-SOA or B-SOA I agree with the first and last values, favouring business value and <a href="http://www.infoq.com/news/2008/09/EvolutionarySOA">evolutionary refinement</a> are difficult to argue with. Intrinsic interoperability also makes sense in either case, especially as it is so vague, which leaves us with three other values:</p> <ol> <li><strong>Strategic goals</strong> over project-specific benefits - At the B-SOA level this is certainly true but at the T-SOA level its a tradeoff as <a href="http://www.innoq.com/blog/st/2009/10/comments_on_the_soa_manifesto.html">Stefan points out</a>. </li> <li><b>Shared services</b> over specific-purpose implementations - From a T-SOA angle this could be taken to refer to the argument that you should design your endpoints to be reusable in different contexts, such as when you go for an <a href="http://www.infoq.com/news/2007/06/entity-services">entity service</a> based approach. However there are <a href="http://www.udidahan.com/2009/06/07/the-fallacy-of-reuse/">arguments against</a> too much premature focus on reuse and use is far more important than reuse. I also think that reuse becomes less key if you view each T-SOA service as being within the context of a B-SOA service. In addition I'm not really sure what this value means when considering the B-SOA services themselves, probably not much. </li> <li><b>Flexibility</b> over optimization - This one is very vague. You could read it about designing your T-SOA services to handle real variations in behaviour/data (patterns like <a href="http://www.manning.com/rotem/">Workflodize</a> come to mind) and if so it is obviously entirely valid. However I think this is coming back to reuse again, specifically designing each T-SOA service to support reuse by making them more general purpose/agnostic. In addition at the T-SOA level optimisation does have to be considered because it is at this level that QOS becomes a consideration, but in many cases considering optimizations of individual T-SOA services won't involved sacrificing flexibility. So I'm not sure how to take this one, in addition I'm unclear as to what this statement means in terms of B-SOA, again probably not much. </li> </ol> <p>So although I can nod my head to most of the points in the manifesto someone with a completely different views on SOA could do exactly the same, and even if we did have the same views we'd need to be clear which type of SOA we were considering when thinking about the manifesto. </p> <p>That's is a pity and I can't help feeling that maybe <a href="http://martinfowler.com/bliki/ServiceOrientedAmbiguity.html">Martin Fowler had it right in 2005</a>:</p> <blockquote> <p>So what do we do? For a start we have to remember all the time about how many different (and mostly incompatible) ideas fall under the SOA camp. These do need to be properly described (and named) independently of SOA. I think SOA has turned into a semantics-free concept that can join 'components' and 'architecture'. It's beyond saving - so the concrete ideas that do have some substance need to get an independent life.</p> </blockquote> <p>With this in mind I actually think that <a href="http://service-architecture.blogspot.com/2007/10/business-service-architecture-is-it.html">Steve Jones could be right</a>, the term SOA is overloaded and too often used just for T-SOA so maybe its time to separate out the notion of B-SOA completely by using a term like Business Service Architecture.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?a=1iYHaN5X42I:Omdhxq4yqM8:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?a=1iYHaN5X42I:Omdhxq4yqM8:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?i=1iYHaN5X42I:Omdhxq4yqM8:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?a=1iYHaN5X42I:Omdhxq4yqM8:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?i=1iYHaN5X42I:Omdhxq4yqM8:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?a=1iYHaN5X42I:Omdhxq4yqM8:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?i=1iYHaN5X42I:Omdhxq4yqM8:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/netDomainDrivenDesign/~4/1iYHaN5X42I" height="1" width="1" alt=""/>Colin Jackhttp://www.blogger.com/profile/01403166737046938219noreply@blogger.com0tag:blogger.com,1999:blog-32609450.post-47858847974434029412009-09-22T22:05:00.001+01:002009-09-22T22:05:29.050+01:00RESTful Web Services Cookbook - Review of Rough Cut<p>I've just finished reading the rough cut of <a href="http://www.restful-webservices-cookbook.org/">RESTful Web Services Cookbook</a> by <a href="http://www.subbu.org/">Subbu Allamaraju</a> and <a href="http://www.amundsen.com/blog/">Mike Amundsen</a> and thought I'd write a very quick review. </p> <p>Ultimately the book fills a gap in the market by providing practical advice on designing high quality HTTP/REST solutions and I found the recipe approach really accessible. </p> <p>Its also an easy read so if you've been toying with REST but haven't found it very easy to get your head around then I'd definitely recommend having a look. I know that when I started learning REST I wasted large amounts of time reading unhelpful and downright misleading content so its good to have a book that should help you avoid falling into any obvious traps.</p> <p>In summary, highly recommended.</p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?a=4EgVzMovD-8:1kVqxKQqt_g:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?a=4EgVzMovD-8:1kVqxKQqt_g:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?i=4EgVzMovD-8:1kVqxKQqt_g:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?a=4EgVzMovD-8:1kVqxKQqt_g:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?i=4EgVzMovD-8:1kVqxKQqt_g:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?a=4EgVzMovD-8:1kVqxKQqt_g:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?i=4EgVzMovD-8:1kVqxKQqt_g:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/netDomainDrivenDesign/~4/4EgVzMovD-8" height="1" width="1" alt=""/>Colin Jackhttp://www.blogger.com/profile/01403166737046938219noreply@blogger.com0tag:blogger.com,1999:blog-32609450.post-49774362795268185272009-09-12T12:53:00.002+01:002009-09-13T18:25:35.631+01:00WCF and REST<p>I'm on a project that was using WCF and we've managed to make the transition to using REST (well, to be honest so far its just POX). </p><p>REST is a joy and I really find it such a pleasant experience compared to RPC let alone WS-*. </p><p>However WCF and REST just are not good bed fellows. Some of the problems are that it doesn't support linking out of the box, content negotiation isn't there, no support for common HTTP/REST patterns, it limits the design/granularity of your resource handlers (think MVC controllers), and the REST starter kit (at least when I looked at it) was appalling.</p><p>There are also lots of annoyances that you only discover when you come to use it and unfortunately, as <a href="http://serialseb.blogspot.com/">Seb</a> discovered when he developed our REST framework on top of WCF, WCF lacks some key extension points meaning you end up having an extremely painful time getting the functionally you need.</p><p>The point of this post isn't to beat up on WCF, its just to make you aware of the issues. If all you want to be able to do is a bit of simple CRUD then you might find WCF to be a good solution, however just be aware that it isn't designed to scale out to handle more interesting problems or more RESTful solutions.</p><p>On the bright side the WCF team did contact me and Seb and we did give feedback which apparently will feed into a release post-WCF 4. My feeling is that if they don't make massive improvements then WCF will lose out on the REST battle, especially as there are some great REST frameworks appearing in .NET-land. </p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?a=f6iqQHfYuNw:mz3yqEWWePc:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?a=f6iqQHfYuNw:mz3yqEWWePc:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?i=f6iqQHfYuNw:mz3yqEWWePc:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?a=f6iqQHfYuNw:mz3yqEWWePc:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?i=f6iqQHfYuNw:mz3yqEWWePc:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?a=f6iqQHfYuNw:mz3yqEWWePc:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?i=f6iqQHfYuNw:mz3yqEWWePc:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/netDomainDrivenDesign/~4/f6iqQHfYuNw" height="1" width="1" alt=""/>Colin Jackhttp://www.blogger.com/profile/01403166737046938219noreply@blogger.com1tag:blogger.com,1999:blog-32609450.post-16224189220540161372009-07-11T22:13:00.001+01:002009-07-11T22:13:58.072+01:00E-VAN Blog and Videos<p>Jan has already posted about it but we have a new <a href="http://europevan.blogspot.com/">E-VAN blog</a> which includes links to the recording of the <a href="http://europevan.blogspot.com/2009/07/recording-of-alan-dean-on-rest-e-van-06.html">excellent presentation</a> Alan Dean gave on REST and a <a href="http://europevan.blogspot.com/2009/07/ian-robinson-and-jim-webber-on-20th.html">link to the next one that Ian Robinson and Jim Webber are giving</a> (please submit questions/topics for this one, it's going to be superb).</p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?a=CDizR6z5WoA:rZUJy_peRRE:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?a=CDizR6z5WoA:rZUJy_peRRE:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?i=CDizR6z5WoA:rZUJy_peRRE:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?a=CDizR6z5WoA:rZUJy_peRRE:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?i=CDizR6z5WoA:rZUJy_peRRE:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?a=CDizR6z5WoA:rZUJy_peRRE:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?i=CDizR6z5WoA:rZUJy_peRRE:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/netDomainDrivenDesign/~4/CDizR6z5WoA" height="1" width="1" alt=""/>Colin Jackhttp://www.blogger.com/profile/01403166737046938219noreply@blogger.com0tag:blogger.com,1999:blog-32609450.post-85451649879906076642009-06-24T21:10:00.003+01:002009-07-05T18:22:20.833+01:00E-VAN - Alan Dean talking on REST (6th July 2009)<p>First off if you didn't watch <a href="http://www.udidahan.com/?blog=true">Udi Dahan</a> talk on the SOA then you missed a treat, a real pro speaking on a topic that he and a very few others in the .NET space are way ahead of the rest of us on. Brilliant stuff and the <a href="http://vimeo.com/5022174">video is now online at Vimeo</a>.</p><h3><strong>Next E-VAN</strong></h3><p>We've also now planned the next couple of E-VANs which will focus on REST, the first will be with Alan Dean where he will cover facts and fallacies related to REST.</p><p><a href="http://alandean.blogspot.com/">Alan</a> is a real authority on REST and he's got a great talk ready so this is a great chance to find out more about REST. In addition if you have any particular questions for Alan, or topics you'd like to discuss in detail, then you can add them to the existing topic on the <a href="http://groups.google.com/group/europevan/browse_thread/thread/8afe38a99d204e52#">google group</a>.</p><p><strong>Start Time on Monday July 06 (7:00PM GMT)</strong></p><p>In France/Germany/Belgium: 9:00PM<br/>In UK is: 8:00PM<br/>EST in the US is: 3:00PM (EST)<br/>PST in the US is: 12:00PM (Midday)<br/><br/>The session will last around 90 minutes and on timings see this <a href="http://www.timeanddate.com/worldclock/">world clock site</a> or more information.</p><p><b>Attendee URL</b></p><p><a href="http://snipr.com/virtualaltnet">http://snipr.com/virtualaltnet</a> (Live Meeting) </p><h3><strong>Future E-VANs</strong></h3><p><a href="http://www.innoq.com/blog/st/">Stefan Tilkov</a> has kindly agreed to do another E-VAN one on REST at the start of August. In addition we are going to see if we can organize another one for mid-July, creating a bit of a REST theme for the next month or so which we hope you'll enjoy.</p><p>We've also got a couple of people in mind that we want to get on looking further into August and beyond, more to come on that once myself and <a href="http://vanryswyckjan.blogspot.com/">Jan</a> contact the people :P</p><h3><strong>Feedback - Tell us how to do better</strong></h3><p>So far I think the E-VAN is going well, great people talking about interesting topics. Live Meeting has been a bit flaky and time zones are a pain but other than that I'm pretty happy with it. </p><p>However we want to know where you guys think things can improve so if you get a chance we'd be interested in hearing your feedback using the new <a href="http://groups.google.com/group/europevan/topics?start=">google group</a>. I'm interested to see if we can get more open discussions going and to explore whether an online book club is a good idea...</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?a=5g22cudx_gY:ZKZKhs8AG2k:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?a=5g22cudx_gY:ZKZKhs8AG2k:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?i=5g22cudx_gY:ZKZKhs8AG2k:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?a=5g22cudx_gY:ZKZKhs8AG2k:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?i=5g22cudx_gY:ZKZKhs8AG2k:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?a=5g22cudx_gY:ZKZKhs8AG2k:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?i=5g22cudx_gY:ZKZKhs8AG2k:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/netDomainDrivenDesign/~4/5g22cudx_gY" height="1" width="1" alt=""/>Colin Jackhttp://www.blogger.com/profile/01403166737046938219noreply@blogger.com14tag:blogger.com,1999:blog-32609450.post-62321596707817955082009-05-24T13:29:00.001+01:002009-05-24T13:29:20.451+01:00Book Review - SOA Patterns (First 5 Chapters)<p>I'll cut straight to the chase, I definitely recommend <a href="http://www.manning.com/rotem/">SOA Patterns</a> to anyone interested in SOA. </p> <p>Even though its currently only available in MEAP, and is a bit rough and ready, and isn't complete, it's still great stuff and well worth your time.</p> <p>Now I've said that I'll give a quick run through. Essentially the author, <a href="http://www.rgoarchitects.com/nblog/default.aspx">Arnon Rotem-Gal-Oz</a>, has decided to focus on the practical aspects of SOA and in particular with a focus on the software architecture aspects of SOA. It thus doesn't cover the business aspects of SOA, which is fine with me as those topics are covered elsewhere.</p> <p>With that tight focus in mind Arnon has already managed to pack in a range of very interesting and valuable patterns. Each pattern includes the problem, solution, technology mapping and quality attributes. There is already the feeling of a pattern language about it which I think will evolve as later chapters are added, this should allow you to describe a complex system with just a few high level patterns or to dig into more detail by discussing the lower level patterns they compose.</p> <p>You can actually read a few of the patterns online, see the <a href="http://www.rgoarchitects.com/SOAPatterns/">linked PDFs</a> and also the <a href="http://www.rgoarchitects.com/nblog/2009/04/30/SOAPatternsNdashBlogjectingWatchdog.aspx">Blogjecting Watchdog</a> pattern, and the anti-pattern called <a href="http://www.rgoarchitects.com/Files/SOAPatterns/TheKnot.pdf">The Knot</a> is also worth a read. </p> <p>In addition <a href="http://vanryswyckjan.blogspot.com/2009/04/half-book-review-soa-patterns.html">Jan has posted a review</a> of the book.</p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?a=KnHVndKEvH4:yQW1Cq9HU9o:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?a=KnHVndKEvH4:yQW1Cq9HU9o:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?i=KnHVndKEvH4:yQW1Cq9HU9o:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?a=KnHVndKEvH4:yQW1Cq9HU9o:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?i=KnHVndKEvH4:yQW1Cq9HU9o:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?a=KnHVndKEvH4:yQW1Cq9HU9o:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?i=KnHVndKEvH4:yQW1Cq9HU9o:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/netDomainDrivenDesign/~4/KnHVndKEvH4" height="1" width="1" alt=""/>Colin Jackhttp://www.blogger.com/profile/01403166737046938219noreply@blogger.com26tag:blogger.com,1999:blog-32609450.post-66190610466162116042009-05-17T20:06:00.001+01:002009-05-18T00:16:00.062+01:00Next Europe VAN - 1st June 2009 - Questions for Udi Dahan<p><a href="http://www.udidahan.com/?blog=true">Udi Dahan</a> has been kind enough to agree to do the next Europe VAN and suggested that we all put forward our questions for him to answer. </p> <p>Its a great chance to ask him about DDD/SOA/CQS/messaging/<a href="http://www.nservicebus.com/">NServiceBus</a>, or any other topic, so if you have any questions post them here or on the associated thread on the <a href="http://tech.groups.yahoo.com/group/domaindrivendesign/message/13099">DDD</a>/<a href="http://tech.groups.yahoo.com/group/altdotnet/message/21931">ALT.NET</a> forums.</p> <p><a href="http://vanryswyckjan.blogspot.com/2009/05/next-european-van-on-1st-june-2009.html">Jan</a> and I will aggregate the questions on the 25th May (after adding our own!) and then submit them to Udi so make sure you've submitted yours before then. <em>Just to confirm, you need to get your questions to us no later than Monday the 25th May or we'll ignore them</em>.</p> <h4><strong>Details</strong></h4> <p>Here's the details of the live meeting:</p> <p><strong>Start Time:</strong> Monday, June 01, 2009 07:00 PM GMT </p> <p><strong>End Time:</strong> Monday, June 01, 2009 08:30 PM GMT </p> <p><b>Attendee URL:</b> <a href="http://snipr.com/virtualaltnet">http://snipr.com/virtualaltnet</a> (Live Meeting) </p> <h4><strong>Calendar</strong></h4> <p>This meeting should also be in the <a href="http://www.virtualaltnet.com/van/Home/Calendar">VAN Calendar</a>, this allows Google calendar users to get a reminder before the big event.</p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?a=twkIQFZVECc:ULh8N1tA6I0:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?a=twkIQFZVECc:ULh8N1tA6I0:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?i=twkIQFZVECc:ULh8N1tA6I0:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?a=twkIQFZVECc:ULh8N1tA6I0:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?i=twkIQFZVECc:ULh8N1tA6I0:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?a=twkIQFZVECc:ULh8N1tA6I0:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?i=twkIQFZVECc:ULh8N1tA6I0:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/netDomainDrivenDesign/~4/twkIQFZVECc" height="1" width="1" alt=""/>Colin Jackhttp://www.blogger.com/profile/01403166737046938219noreply@blogger.com16tag:blogger.com,1999:blog-32609450.post-36607701608192552222009-05-10T21:53:00.001+01:002009-05-10T21:53:04.580+01:00Book Review - RESTful .NET<p>Since we are using REST on top of WCF on my current project I was glad to see that this book had been written as I was hoping it would answer some questions I had. </p> <p>However my first issue with this book was the title. As I say we're using WCF but WCF isn't the only way to implement REST in .NET, however the book does not take the time to evaluate alternatives (including building RESTful applications on top of ASP.NET MVC) so <em>RESTful WCF</em> would have been a more accurate title. </p> <p>In fact if we wanted to truly represent the books focus I think we would call it <em>WCF REST</em> because the primary focus is on WCF. There was a lot of WCF detail in here, starting from chapter 2, and personally I found some if quite boring especially where the author has chosen to put in property listings of some key WCF classes. I just don't find that sort of content all that useful and I'd have expected a lot of it to be in an appendix at best. </p> <p>However the WCF focus has some other implications. Take HATEOS which is an important part of REST, my company has been lucky enough to have <a href="http://serialseb.blogspot.com/">Sebastien Lambla</a> and <a href="http://alandean.blogspot.com/">Alan Dean</a> in our office and both emphasized its importance. However there is almost no discussion of it in the book, and the reason for this becomes clear on page 246 where the author states that although hypermedia is important in REST it isn't covered in the book because WCF has poor support for it. As I say we're using WCF so I knew that WCF's support for links in normal representations was non-existent, but I do consider it a flaw of the book and in my view the author would have been better stating this big problem up-front or tried to add framework to make linking a lot easier (something Seb did for us). </p> <p>Strangely the author actually states that he actually avoids discussing custom infrastructure code because it takes away from learning about the technology (page 97). Personally I would prefer the book if had a focus on REST and how to get the advantages of REST using WCF, low level WCF plumbing/architecture is a necessary evil not something I want to read much about and more importantly if we need extra framework then I'd like to see it discussed.</p> <p>I also thought it was doubly odd that chapter 9 discussed &quot;Using Workflow to Deliver REST Services&quot;, all centred around Windows Workflow, when to me when I see the words workflow in a REST book I'm again thinking of HATEOS (the <a href="http://www.infoq.com/articles/webber-rest-workflow">RESTbucks example at InfoQ</a> shows this approach brilliantly and will form part of a rival book).</p> <p>Before wrapping up I also wanted to identify one bit of the book where the advice is very questionable. Chapter 10 is called &quot;Consuming RESTful XML Services Using WCF&quot; and one approach described is to take the interface attributed with <em><a href="http://msdn.microsoft.com/en-us/library/system.servicemodel.servicecontractattribute.aspx">ServiceContract</a></em> and use it client side. Just to be clear we're talking about making class like <em>channel.CreateAuthority(authority) </em>and then letting WCF work out what HTTP request to make. You won't want to be doing that.</p> <p>Anyway I personally wouldn't recommend this to anyone wanting to learn about REST, instead I'd recommend (for now) <a href="http://www.amazon.co.uk/RESTful-Web-Services-Leonard-Richardson/dp/0596529260/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1241987182&amp;sr=8-1">RESTful Web Services</a>. If however you are using WCF and REST, and feel you already understand REST, then this book will give you some insight into support for REST in WCF.</p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?a=d06v71q7rq8:lgB5nhnFA7E:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?a=d06v71q7rq8:lgB5nhnFA7E:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?i=d06v71q7rq8:lgB5nhnFA7E:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?a=d06v71q7rq8:lgB5nhnFA7E:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?i=d06v71q7rq8:lgB5nhnFA7E:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?a=d06v71q7rq8:lgB5nhnFA7E:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?i=d06v71q7rq8:lgB5nhnFA7E:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/netDomainDrivenDesign/~4/d06v71q7rq8" height="1" width="1" alt=""/>Colin Jackhttp://www.blogger.com/profile/01403166737046938219noreply@blogger.com14tag:blogger.com,1999:blog-32609450.post-51431090672378757482009-05-06T19:49:00.001+01:002009-05-06T19:49:37.212+01:00E-VAN Videos Reminder<p>Just to remind people that Jan has put the videos for the first two E-VAN presentations online: </p> <p><a href="http://www.vimeo.com/user1286822">http://www.vimeo.com/user1286822</a> </p> <p>Mark Nijhof's excellent presentation on FubuMVC will be up as soon as its available and we'll announce the next presentation as soon as we organize it :P </p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?a=K7nwuxq-zno:ay2W8zPvU-E:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?a=K7nwuxq-zno:ay2W8zPvU-E:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?i=K7nwuxq-zno:ay2W8zPvU-E:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?a=K7nwuxq-zno:ay2W8zPvU-E:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?i=K7nwuxq-zno:ay2W8zPvU-E:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?a=K7nwuxq-zno:ay2W8zPvU-E:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/netDomainDrivenDesign?i=K7nwuxq-zno:ay2W8zPvU-E:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/netDomainDrivenDesign/~4/K7nwuxq-zno" height="1" width="1" alt=""/>Colin Jackhttp://www.blogger.com/profile/01403166737046938219noreply@blogger.com16tag:blogger.com,1999:blog-32609450.post-30527534349155862562009-02-15T17:44:00.001+00:002009-02-15T17:44:08.073+00:00Next Europe VAN - 25th February 2009<p>After a bit of discussion <a href="http://elegantcode.com/about/jan-van-ryswyck/">Jan</a> and I have decided that for now it seems to make sense to run the Europe VAN every two weeks, we have discussed having more open discussions on alternate weeks but we'll have to see if there is an appetite for that. </p> <p><a href="http://serialseb.blogspot.com/">Seb</a> has agreed to do the next one on REST and his <a href="http://serialseb.blogspot.com/2008/04/using-rasta-1-introduction.html">OpenRasta</a> framework. </p> <p><strong>Start Time:</strong> Wednesday Feb 25, 2009 7:00 PM GMT </p> <p><strong>End Time:</strong> Wednesday, Feb 25, 2009 09:00 PM GMT </p> <p><b>Attendee URL:</b> <a href="http://snipr.com/virtualaltnet">http://snipr.com/virtualaltnet</a> (Live Meeting)&#160;&#160; </p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=6AGuSvB7"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?d=41" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=OVyg29q1"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?i=OVyg29q1" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=eW0bZCpo"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?i=eW0bZCpo" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=38LQAG8c"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?i=38LQAG8c" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/netDomainDrivenDesign/~4/nWPkZy3xCoY" height="1" width="1" alt=""/>Colin Jackhttp://www.blogger.com/profile/01403166737046938219noreply@blogger.com17tag:blogger.com,1999:blog-32609450.post-73069964440821868162009-02-09T19:03:00.003+00:002009-02-09T21:06:10.771+00:00Europe VAN - DDD with Greg Young (9th Feb)<p>The delayed first E-VAN is on now with Greg Young, discussing DDD and CQS. The URL is: <a href="http://snipr.com/virtualaltnet">http://snipr.com/virtualaltnet</a> (Live Meeting).</p><p><strong>NOTE:</strong> This one was a success and Greg did a superb job explaining DDD and messaging, really enjoyable stuff.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=3xgNPtx9"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?d=41" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=kEKuC2jV"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?i=kEKuC2jV" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=t4xPGg0f"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?i=t4xPGg0f" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=8kMrsczy"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?i=8kMrsczy" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/netDomainDrivenDesign/~4/fLMBxw6RM04" height="1" width="1" alt=""/>Colin Jackhttp://www.blogger.com/profile/01403166737046938219noreply@blogger.com18tag:blogger.com,1999:blog-32609450.post-3276446241339556532009-02-08T20:39:00.003+00:002009-02-08T20:55:59.892+00:00P&P Guidance - Positive Progress<p>I put up a post a while back about the P&amp;P REST guidance which I considered to be quite flawed. The reaction from the P&amp;P team was superb and <a href="http://codebetter.com/blogs/gregyoung/">Greg Young</a>, <a href="http://serialseb.blogspot.com/">Sebastien Lambla</a> and myself immediately got involved in an e-mail exchange with them regarding this and other guidance. </p><p>They've shown they are incredibly open to feedback and we're still involved in this exchange but it looks like the result may be changes to the existing article and/or new articles.</p><p>One thing I hadn't realized before this started is that P&amp;P actually have three different sites:</p><ol><li>Guide – <a href="http://www.codeplex.com/AppArchGuide">http://www.codeplex.com/AppArchGuide</a> </li><li>Knowledge Base – <a href="http://www.codeplex.com/AppArch">http://www.codeplex.com/AppArch</a> </li><li>Community Site – <a href="http://www.codeplex.com/AppArchContrib">http://www.codeplex.com/AppArchContrib</a> </li></ol><p>The community site is quite open so even if our examples use open source frameworks they can still be published on it. I'm therefore planning on writing one example using WCF, NHibernate and Castle where the two primary areas covered will be:</p><ol><li><strong>REST</strong> - Although the current example says its using REST I think this is arguable. </li><li><strong>Domain Model</strong> - I'll be using DDD patterns but I've tried to explain that DDD isn't always appropriate (e.g. if you don't have access to domain experts). Regardless I'm obviously a big fan of object-oriented domain models and the barrier to entry is so low with modern ORM's that I think its a no-brainer to use one in the example. </li></ol><p>I'm not saying I've chosen the best technologies, in particular using WCF is highly questionable, but since I'm not trying to say this is the "best" way to do things I'm comfortable with the choices especially as I'd expect other guidance to be given over other approaches (perhaps using an MVC style approach).</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=S0KhJoHR"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?d=41" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=x2gUl0sn"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?i=x2gUl0sn" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=8TCIfKEb"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?i=8TCIfKEb" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=AwnMpULB"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?i=AwnMpULB" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/netDomainDrivenDesign/~4/L8m3TSUyuxs" height="1" width="1" alt=""/>Colin Jackhttp://www.blogger.com/profile/01403166737046938219noreply@blogger.com18tag:blogger.com,1999:blog-32609450.post-49902652821337000202009-02-02T19:58:00.001+00:002009-02-02T19:58:38.211+00:00First Europe VAN<p>The first Europe VAN went off without a hitch and was an amazing success. Ha, yeah sorry about that. </p> <p>Good news is next one is BOUND to be better and we are trying again very soon. Next time we'll come armed with a backup plan too, possibly involving one us loading up the Dark Knight DVD so we can all watch it for an hour or two.</p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=cfxH7Gmf"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?d=41" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=9Perqp63"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?i=9Perqp63" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=TudnYYQS"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?i=TudnYYQS" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=4RK5fU2n"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?i=4RK5fU2n" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/netDomainDrivenDesign/~4/wd38uMCvESw" height="1" width="1" alt=""/>Colin Jackhttp://www.blogger.com/profile/01403166737046938219noreply@blogger.com0tag:blogger.com,1999:blog-32609450.post-61648476030705062622009-02-01T10:10:00.001+00:002009-02-01T10:10:40.447+00:00First Europe VANJust a reminder that the first Europe VAN is tomorrow: <p><strong>Start Time:</strong> Monday, Feb 02, 2009 7:00 PM GMT</p> <p><strong>End Time:</strong> Monday, Feb 02, 2009 09:00 PM GMT</p> <p><strong>Attendee URL:</strong> <a href="http://snipr.com/virtualaltnet">http://snipr.com/virtualaltnet</a> (Live Meeting)</p> <p>Greg Young has been kind enough to agree to speak and I'm hopeful it'll go well as we've had a couple of dry runs so it's looking good, even if I was perturbed to found out <a href="http://elegantcode.com/2009/01/29/european-virtual-altnet-meeting-on-02022009/">Jan</a> speaks better English than me. </p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=E1b87nqP"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?d=41" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=BLTtP43o"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?i=BLTtP43o" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=oXjPl9hP"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?i=oXjPl9hP" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=1h4hFuLn"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?i=1h4hFuLn" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/netDomainDrivenDesign/~4/ONzuRfCSrIg" height="1" width="1" alt=""/>Colin Jackhttp://www.blogger.com/profile/01403166737046938219noreply@blogger.com0tag:blogger.com,1999:blog-32609450.post-72866166353654089262009-01-22T20:09:00.001+00:002009-01-22T21:43:57.429+00:00P&P - Web Service with REST Application Pattern<p>It was interesting that all the fuss over Oxite had a positive impact. Unfortunately Microsoft are also now giving us their views on REST (WCF REST starter kit, argh) and more recently REST with a domain model in <a href="http://www.codeplex.com/AppArch/Wiki/View.aspx?title=App%20Pattern%20-%20Two-Tier%20Service%20Application%20Scenario%20%28REST%29&amp;referringTitle=Application%20Patterns">Two-Tier Service Application Scenario (REST)</a> which J.D. Meier calls the <a href="http://blogs.msdn.com/jmeier/archive/2009/01/21/application-patterns.aspx">Web Service with REST Application Pattern</a>.</p> <p>If you understand REST/DDD, or like Fowlers original meanings for his patterns, or believe that &quot;Business Process Objects&quot; with methods like &quot;Promote (object[] data)&quot; could be improved on then you might want to look away now. Come on though I've piqued your interest, have a look, it makes you feel dirty but yet at the same time makes you glad you now realize that perhaps there are other ways to build applications.</p> <p>Might be interesting to see how this relates to the old design documents MS used to pass out, pretty sure its not that different except resource is now used in some places instead of service. Service + procedural code + database, rock on.</p> <p>Anyway I'm going to go back to writing my own comments on it to put on the page, its going to take me a while...</p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=vn5hn8Ec"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?d=41" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=G9bG78fw"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?i=G9bG78fw" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=d1iwrRWd"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?i=d1iwrRWd" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=QRz8duTn"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?i=QRz8duTn" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/netDomainDrivenDesign/~4/q9xit1x8HLI" height="1" width="1" alt=""/>Colin Jackhttp://www.blogger.com/profile/01403166737046938219noreply@blogger.com2tag:blogger.com,1999:blog-32609450.post-54469046315648207632008-12-28T15:31:00.001+00:002008-12-28T15:31:21.689+00:00SOA Principles of Service Design<p>I've been learning a lot more about SOA and REST recently and so have been doing a lot of reading including <a href="http://www.amazon.co.uk/Principles-Service-Prentice-Service-Oriented-Computing/dp/0132344823/ref=cm_lmf_tit_3_rsrsrs0">SOA Principles of Service Design</a> and I thought I should write a short review.</p> <p>Short version, this is one of the worst technical books I've read and I wouldn't recommend it to anyone. My main gripes are:</p> <ul> <li><strong>Style</strong> - Although there are lots of colour diagrams they don't tell you much and don't take away from the fact that the text is dry, repetitive and at times very boring. Since I've read one of Erl's previous books, well read about half of it because I just couldn't face the rest, I should have known what to expect but it was still a big big struggle to finish it.</li> <li><strong>Ideas</strong> - Reusable <a href="http://www.infoq.com/news/2007/06/entity-services">entity services</a> (Customer/Order) shared throughout the enterprise might sound sensible but I'm not at all convinced by that approach and the focus on it has always blunted my interest in SOA. Unfortunately that style of layered SOA is key to this book so I found a lot of it pretty un-inspiring. </li> <li><strong>Single Viewpoint</strong> - There is more to SOA than RPC services but this book doesn't really talk about anything else. REST gets no coverage (as an alternative to aspects of SOA), EDM/messaging doesn't really come into it, business focused SOA (analysis/design with business experts) is hardly discussed...it just all feels too narrowly focused on the one approach the author uses and so there is little discussion of alternatives and tradeoffs.</li> <li><strong>Book Assembly Line Approach</strong> - Having one book on <a href="http://www.amazon.co.uk/Principles-Service-Prentice-Service-Oriented-Computing/dp/0132344823/ref=cm_lmf_tit_3_rsrsrs0">SOA principles</a> and another on the <a href="http://www.amazon.co.uk/Design-Patterns-Prentice-Service-Oriented-Computing/dp/0136135161/ref=cm_lmf_tit_5_rsrsrs0">patterns</a>, with references from the principles book to the patterns one, seems overkill. I know SOA is a big topic but do we really need an <a href="http://www.amazon.co.uk/Service-Oriented-Architecture/lm/R1Z498Y9GVOVZS/ref=cm_lmt_srch_f_1_rsrsrs0">eight book SOA series</a>? In my view you could easily have cut 30% of the content in this book (including most of the diagrams) and merged it with the patterns book. </li> </ul> <p>Some might take this as me saying I don't rate SOA but that is not true at all, I just don't rate this book and don't think the ideas behind it are what I'm interested in. However I still think SOA has a lot of value and in fact the next two books I plan to read/finish are both about SOA:</p> <ul> <li><strong><a href="http://www.manning.com/rotem/">SOA Patterns</a></strong> - Not the SOA patterns book by Erl (which I'll admit from it's <a href="http://www.soapatterns.org/">site</a> looks interesting), this one is by <a href="http://www.rgoarchitects.com/nblog%5Cdefault.aspx">Arnon</a> and from the Manning EAP version I've read it's going to be superb. </li> <li><a href="http://www.infoq.com/minibooks/enterprise-soa">Enterprise SOA Adoption Strategies</a> - I learned about this book because I enjoyed reading <a href="http://service-architecture.blogspot.com/">Steve Jones'</a> posts on the <a href="http://tech.groups.yahoo.com/group/service-orientated-architecture/?yguid=300479819">SOA forum</a> and it seems to focus on the business oriented side of SOA, something which doesn't seem to get discussed nearly enough.</li> </ul> <p>Since I'm far more interested in business focused services each wrapping one or more domain models and exposing multiple end-points, instead of entity services first approach, I'm looking forward to reading these two as from the looks of it&#160; they'll give me lots of new ideas.</p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=wMpAwBKW"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?d=41" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=YNt0FNwf"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?i=YNt0FNwf" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=Vw0VmwM6"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?i=Vw0VmwM6" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=xLKmOB5O"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?i=xLKmOB5O" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/netDomainDrivenDesign/~4/q0t5uW1Bw14" height="1" width="1" alt=""/>Colin Jackhttp://www.blogger.com/profile/01403166737046938219noreply@blogger.com1tag:blogger.com,1999:blog-32609450.post-53472506207272980172008-11-19T21:16:00.004+00:002008-12-28T21:46:51.449+00:00BDD - Available Frameworks<p>I've been using the <a href="http://blog.daveastels.com/files/BDD_Intro.pdf">Astels style of BDD</a> for a while now but so far I've just done it using MSTest/NUnit and a few custom base classes. I think that's a good way to start out, as with so many good things in life it doesn't require a new whizzy tool/framework.</p><p>However I've just joined a new project and we've been looking at different frameworks that are available for unit testing and for BDD so I thought I'd post about what I've seen so far. Any opinions would be gladly received.<br /><br /><a href="http://codebetter.com/blogs/aaron.jensen/archive/2008/05/08/introducing-machine-specifications-or-mspec-for-short.aspx"><span style="FONT-WEIGHT: bold">MSpec</span></a><br />This project is very cool, not only does it allow you to create superb specifications but you also get some nice reporting. Here's a simple example of a sample spec:<br /></p><pre class="code"><p></p><pre class="code"><span style="color:blue;">public class </span><span style="COLOR: rgb(43,145,175)">When_adding_a_contact_to_a_user_with_no_existing_contacts<br /></span>{<br /> <span style="color:blue;">private static </span><span style="COLOR: rgb(43,145,175)">User </span>_user;<br /> <span style="color:blue;">private static </span><span style="COLOR: rgb(43,145,175)">Contact </span>_contact;<br /><br /> <span style="COLOR: rgb(43,145,175)">Establish </span>context_once =()=&gt;<br /> {<br /> _user = <span style="color:blue;">new </span><span style="COLOR: rgb(43,145,175)">TestUserBuilder</span>().Build();<br /> _contact = <span style="color:blue;">new </span><span style="COLOR: rgb(43,145,175)">ContactBuilder</span>().Build();<br /> };<br /><br /> <span style="COLOR: rgb(43,145,175)">Because </span>a_context_is_added =()=&gt;<br /> _user.Contacts.Add(_contact);<br /><br /> <span style="color:blue;">private </span><span style="COLOR: rgb(43,145,175)">It </span>should_associate_the_contact_with_the_user = () =&gt;<br /> _user.Contacts.Contains(_contact).ShouldBeTrue();<br /> <br />}</pre><a href="http://11011.net/software/vspaste"></a><p></p></pre>One thing to note is if your planning to look at MSpec then you'll probably want to download the <a href="http://codebetter.com/blogs/aaron.jensen/archive/2008/10/22/machine-has-moved.aspx">Machine codebase</a> since there aren't many examples of using <a href="http://codebetter.com/blogs/aaron.jensen/archive/2008/05/08/introducing-machine-specifications-or-mspec-for-short.aspx">MSpec</a> on the Web the examples with Machine are a good starting point.<br /><p>So far there's no R# integration but that doesn't worry me at all as if needed it will come and this is still a very early version. </p>The reporting seems to work well, but we primarily use this style for unit/integration tests and so we are unlikely to present the reports outside the development team. Having said that <a href="http://codebetter.com/blogs/aaron.jensen/archive/2008/10/19/bdd-consider-your-audience.aspx">Aaron pointed out</a> that they can be useful within the development team, which makes a lot of sense.<br /><p>Overall my main worry is the syntax could be a bit much for some people, in particular if you go for the compact style:<br /><br /><span style="FONT-WEIGHT: bold">NUnit</span><br />I think there's a good argument for just using a base class, especially when you are getting going with the approach: </p><pre class="code"><span style="color:blue;">public class </span><span style="COLOR: rgb(43,145,175)">When_adding_a_contact_to_a_user_with_no_existing_contacts </span>: <span style="COLOR: rgb(43,145,175)">SpecificationBaseNUnit<br /></span>{<br /> <span style="color:blue;">private </span><span style="COLOR: rgb(43,145,175)">User </span>_user;<br /> <span style="color:blue;">private </span><span style="COLOR: rgb(43,145,175)">Contact </span>_contact;<br /><br /> <span style="color:blue;">protected override void </span>EstablishContext()<br /> {<br /> _user = <span style="color:blue;">new </span><span style="COLOR: rgb(43,145,175)">TestUserBuilder</span>().Build();<br /> _contact = <span style="color:blue;">new </span><span style="COLOR: rgb(43,145,175)">ContactBuilder</span>().Build();<br /> }<br /><br /> <span style="color:blue;">protected override void </span>Act()<br /> {<br /> _user.Contacts.Add(_contact);<br /> }<br /><br /> [<span style="COLOR: rgb(43,145,175)">Test</span>]<br /> <span style="color:blue;">public void </span>should_associate_the_contact_with_the_user()<br /> {<br /> _user.Contacts.Contains(_contact).ShouldBeTrue();<br /> }<br />}</pre>This is a hopelessly naive example but you get the idea. You lose some of the syntax niceness, suddenly the specs themselves take up multiple lines because of all the curlies. You've also lost reporting, unless you put in some work yourself. However it is a little easier to understand and when introducing TDD/BDD that could be important.<br /><p><span style="FONT-WEIGHT: bold">XUnit.net</span><br />I'm no XUnit.net expert but Ben Hall convinced us to give it a shot by recommending it and it is very nice. You can read about an approach that works <a href="http://www.bjoernrochel.de/2008/10/04/introducing-xunitbddextensions/">here</a>. If you use the specification base class described in that post you might end up with this:</p><pre class="code"><span style="color:green;">// Using base class influenced by http://www.bjoernrochel.de/2008/10/04/introducing-xunitbddextensions/<br /></span><span style="color:blue;">public class </span><span style="COLOR: rgb(43,145,175)">When_adding_a_contact_to_a_user_with_no_existing_contacts </span>: <span style="COLOR: rgb(43,145,175)">SpecificationBase<br /></span>{<br /> <span style="color:blue;">private </span><span style="COLOR: rgb(43,145,175)">User </span>_user;<br /> <span style="color:blue;">private </span><span style="COLOR: rgb(43,145,175)">Contact </span>_contact;<br /><br /> <span style="color:blue;">protected override void </span>EstablishContext()<br /> {<br /> _user = <span style="color:blue;">new </span><span style="COLOR: rgb(43,145,175)">TestUserBuilder</span>().Build();<br /> _contact = <span style="color:blue;">new </span><span style="COLOR: rgb(43,145,175)">ContactBuilder</span>().Build();<br /> }<br /><br /> <span style="color:blue;">protected override void </span>Because()<br /> {<br /> _user.Contacts.Add(_contact);<br /> }<br /><br /> [<span style="COLOR: rgb(43,145,175)">Observation</span>]<br /> <span style="color:blue;">public void </span>should_associate_the_contact_with_the_user()<br /> {<br /> _user.Contacts.Contains(_contact).ShouldBeTrue();<br /> }<br />}</pre>One aspect of XUnit that might throw you is how <a href="http://www.codeplex.com/xunit/Wiki/View.aspx?title=Comparisons">opinionated</a> it is, which could be an advantage or a disadvantage. An example is that it's aiming for each test to run in isolation, so the fixture class is re-created each time and if you really want to reuse the fixture you implement <span id="ctl00_ctl00_MasterContent_TabContentPanel_Content_wikiSourceLabel" style="FONT-STYLE: italic"><span class="codeInline">IUseFixture. </span></span><span id="ctl00_ctl00_MasterContent_TabContentPanel_Content_wikiSourceLabel"><span class="codeInline">I guess this is a very safe approach because it means tests/specs are extremely unlikely to affect each other, but it actually seems over-kill if you're using a style where the specification methods only assert (no side-effects).<br /><br /></span></span><span id="ctl00_ctl00_MasterContent_TabContentPanel_Content_wikiSourceLabel"><span class="codeInline">The lack of messages on assertions seems sensible, and it is for small focused BDD specifications, but if you use it for integration testing you would want the option of adding a message in.</span></span><br /><span id="ctl00_ctl00_MasterContent_TabContentPanel_Content_wikiSourceLabel"><span class="codeInline"><br />On the syntax front we could always go for more flexibility:<br /><pre class="code"><span style="color:blue;">public class </span><span style="COLOR: rgb(43,145,175)">When_a_user_has_no_contacts </span>: <span style="COLOR: rgb(43,145,175)">FlexibileGrammarSpecificationBase<br /></span>{<br /> <span style="color:blue;">private </span><span style="COLOR: rgb(43,145,175)">User </span>_user;<br /> <span style="color:blue;">private </span><span style="COLOR: rgb(43,145,175)">Contact </span>_contact;<br /><br /> <span style="color:blue;">protected override void </span>EstablishContext()<br /> {<br /> _user = <span style="color:blue;">new </span><span style="COLOR: rgb(43,145,175)">TestUserBuilder</span>().Build();<br /> _contact = <span style="color:blue;">new </span><span style="COLOR: rgb(43,145,175)">ContactBuilder</span>().Build();<br /> }<br /><br /> [<span style="COLOR: rgb(43,145,175)">Because</span>]<br /> <span style="color:blue;">protected void </span>and_we_give_them_a_new_contact()<br /> {<br /> _user.Contacts.Add(_contact);<br /> }<br /><br /> [<span style="COLOR: rgb(43,145,175)">Observation</span>]<br /> <span style="color:blue;">public void </span>the_contact_should_be_associated_with_the_user()<br /> {<br /> _user.Contacts.Contains(_contact).ShouldBeTrue();<br /> }<br />}</pre>However this seems a little pointless to me so I've dumped the idea.<br /><span style="FONT-WEIGHT: bold"><br />Summary</span><br />We decided to go with XUnit.net but we also plan to look at Ruby based solutions including RSpec and Cucumber. <a href="http://github.com/aslakhellesoy/cucumber/wikis">Cucumber</a> seems exciting as it lets you specify <a href="http://github.com/aslakhellesoy/cucumber/wikis/using-fit-tables-in-a-feature">table based specifications</a>, theoretically allowing us to get the advantages of a FIT style approach without having to use FIT (or <a href="http://blog.objectmentor.com/articles/2008/10/02/slim">SLIM</a>) itself.<br /><br />Ultimately there is a lot going on in the BDD space in Ruby-land (and a <a href="http://www.pragprog.com/titles/achbd/the-rspec-book">book</a> on the way) and the language does suit it quite well so we intend to do some playing. </span></span><div class="feedflare">
<a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=fP3klC8a"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?d=41" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=8l2s5MKh"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?i=8l2s5MKh" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=84hAaXVz"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?i=84hAaXVz" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=NzqNtnpt"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?i=NzqNtnpt" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/netDomainDrivenDesign/~4/BiZPINHBzWk" height="1" width="1" alt=""/>Colin Jackhttp://www.blogger.com/profile/01403166737046938219noreply@blogger.com1tag:blogger.com,1999:blog-32609450.post-22703575817548126352008-11-19T20:58:00.004+00:002008-12-28T21:48:39.322+00:00BDD and Parameterized testing<p></p><p>Although I really like <a href="http://blog.daveastels.com/files/BDD_Intro.pdf">Astels style BDD</a> (to me a constrained/enhanced style of TDD) I still use a lot of <a href="http://xunitpatterns.com/Parameterized%20Test.html">parameterized testing</a> and though I should give you an example why, using XUnit.net. </p><p>Lets say we're testing simple SPECIFICATION style rules, we might write:</p><pre class="code">[<span style="COLOR: rgb(43,145,175)">Concerning</span>(<span style="color:blue;">typeof</span>(<span style="COLOR: rgb(43,145,175)">ValidEmailRule</span>&lt;<span style="COLOR: rgb(43,145,175)">TestEntity</span>&gt;))]<br /><span style="color:blue;">public class </span><span style="COLOR: rgb(43,145,175)">When_using_rule_on_a_null_string </span>: <span style="COLOR: rgb(43,145,175)">SpecificationBase<br /></span>{<br /> <span style="color:blue;">protected </span><span style="COLOR: rgb(43,145,175)">TestEntity </span>_testEntity;<br /> <span style="color:blue;">private bool </span>_isSatisfied;<br /><br /> <span style="color:blue;">protected override void </span>EstablishContext()<br /> {<br /> _testEntity = <span style="COLOR: rgb(43,145,175)">ContextSetup</span>.CreateTestEntityWithValue(<span style="color:blue;">null</span>);<br /> }<br /><br /> <span style="color:blue;">protected override void </span>Act()<br /> {<br /> _isSatisfied = <span style="color:blue;">new </span><span style="COLOR: rgb(43,145,175)">ValidEmailRule</span>&lt;<span style="COLOR: rgb(43,145,175)">TestEntity</span>&gt;(_testEntity, x =&gt; x.Value).IsSatisfied();<br /> }<br /><br /> [<span style="COLOR: rgb(43,145,175)">Observation</span>]<br /> <span style="color:blue;">public void </span>is_satisfied()<br /> {<br /> _isSatisfied.ShouldBeTrue();<br /> }<br />}</pre><p>This just tests how the rule handles a null value, but we'd then want to test with all sorts of other values (valid and invalid). To compare lets thus look at how easy it is to test a variety of invalid e-mail address using one of <a href="http://www.codeplex.com/xunit">XUnit.net</a>'s parameterized testing approaches (see <a href="http://blog.benhall.me.uk/labels/XUnit.html">Ben Hall</a> for more options):</p><pre class="code">[<span style="COLOR: rgb(43,145,175)">Concerning</span>(<span style="color:blue;">typeof</span>(<span style="COLOR: rgb(43,145,175)">ValidEmailRule</span>&lt;<span style="COLOR: rgb(43,145,175)">TestEntity</span>&gt;))]<br /><span style="color:blue;">public class </span><span style="COLOR: rgb(43,145,175)">When_evaluating_invalid_email_addresses<br /></span>{<br /> [<span style="COLOR: rgb(43,145,175)">Theory</span>]<br /> [<span style="COLOR: rgb(43,145,175)">InlineData</span>(<span style="COLOR: rgb(163,21,21)">"sddas.com"</span>)]<br /> [<span style="COLOR: rgb(43,145,175)">InlineData</span>(<span style="COLOR: rgb(163,21,21)">"sddas@"</span>)]<br /> [<span style="COLOR: rgb(43,145,175)">InlineData</span>(<span style="COLOR: rgb(163,21,21)">"@"</span>)]<br /> [<span style="COLOR: rgb(43,145,175)">InlineData</span>(<span style="COLOR: rgb(163,21,21)">"@blah.com"</span>)]<br /> [<span style="COLOR: rgb(43,145,175)">InlineData</span>(<span style="COLOR: rgb(163,21,21)">"sddas@@blah.com"</span>)]<br /> [<span style="COLOR: rgb(43,145,175)">InlineData</span>(<span style="COLOR: rgb(163,21,21)">"1213231"</span>)]<br /> <span style="color:blue;">public void </span>is_not_satisfied(<span style="color:blue;">string </span>invalidEmailAddress)<br /> {<br /> <span style="color:blue;">var </span>testEntity = <span style="COLOR: rgb(43,145,175)">ContextSetup</span>.CreateTestEntityWithValue(invalidEmailAddress);<br /><br /> <span style="color:blue;">var </span>isSatisfied = <span style="color:blue;">new </span><span style="COLOR: rgb(43,145,175)">ValidEmailRule</span>&lt;<span style="COLOR: rgb(43,145,175)">TestEntity</span>&gt;(testEntity, x =&gt; x.Value).IsSatisfied();<br /><br /> isSatisfied.ShouldBeFalse();<br /> }<br />}</pre><p><a href="http://11011.net/software/vspaste"></a><a href="http://11011.net/software/vspaste"></a><a href="http://11011.net/software/vspaste"></a>Now you may disagree with my approach here, this isn't as readable as it could be, but I think you can see why you'd use this approach if you have a lot of values to validate.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=5XCAXK2D"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?d=41" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=br3grIK6"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?i=br3grIK6" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=vnu2oRso"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?i=vnu2oRso" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=m5aCPMX8"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?i=m5aCPMX8" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/netDomainDrivenDesign/~4/kUZVh7UJstM" height="1" width="1" alt=""/>Colin Jackhttp://www.blogger.com/profile/01403166737046938219noreply@blogger.com3tag:blogger.com,1999:blog-32609450.post-13562238628792911332008-10-28T22:43:00.001+00:002008-11-09T14:57:06.921+00:00DDD - Making meaningful relationships<p>A recent <a href="http://tech.groups.yahoo.com/group/domaindrivendesign/message/8276">discussion on the DDD forum</a> made me want to post about what I consider to be an under-appreciated aspect of domain modelling, namely relationships. In the <a href="http://tech.groups.yahoo.com/group/domaindrivendesign/message/8276">thread</a> Randy Stafford said the following:</p> <blockquote> <p>Note that RoleRegistration is an example of a Relationship Object &#8211; arguably a fourth archetype of domain object alongside Entity, Value Object, and Aggregate.</p> </blockquote> <p>I couldn't agree more with this, in a domain model I worked on recently we had a stack of very useful and very meaningful relationship objects that served a range of purposes. </p> <p>For example if a <span class="Apple-style-span" style="font-style: italic">Client </span>has <span class="Apple-style-span" style="font-style: italic">Accounts </span>then it is possible that you can get away with just having that as a direct relationship but its equally possible that the relationship itself is meaningful and carries its own data/behavior. In this case you might have a type association with the relationship that would explain if the <span class="Apple-style-span" style="font-style: italic">Client </span>owns the <span class="Apple-style-span" style="font-style: italic">Account</span><span class="Apple-style-span" style="font-style: italic">,</span> or whethery just manage it, or whether they are actually just one of several owners.</p> <div><span class="Apple-style-span" style="font-weight: bold">Aggregates</span></div> <p>You need to consider aggregate boundaries especially carefully when using Relationship Objects.</p> <p>In the case of an association between a <span class="Apple-style-span" style="font-style: italic">Client </span>and an <span class="Apple-style-span" style="font-style: italic">Account </span>the relationship<span class="Apple-style-span" style="font-style: italic">&#160;</span>probably belongs to the <span class="Apple-style-span" style="font-style: italic">Client </span>aggregate. </p> <p>Then again if you choose to model the association between a <span class="Apple-style-span" style="font-style: italic">Client </span>and <span class="Apple-style-span" style="font-style: italic">SalesAdvisor </span>using a full blown <a href="http://www.amazon.co.uk/Enterprise-Patterns-MDA-Archetype-Technology/dp/032111230X/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1225226806&amp;sr=8-1">party/role/relationship</a> approach then things become a big more complex. Are all parties and roles and relationships different aggregates or does a relationship own the two roles it composes?</p> <p>If its the latter then you may be breaking an aggregate design rule because the party now refers to a piece of the relationship aggregate other than root. </p> <div> <p><strong>Temporal Associations</strong></p> <p>Another common case is that the relationship is temporal which brings with it a lot of complexity and should only be done with extreme care.&#160; If your sure you need temporal associations then you will find <a href="http://martinfowler.com/ap2/timeNarrative.html">Martin Fowlers patterns</a> invaluable.</p> </div> <p><span class="Apple-style-span" style="font-weight: bold"></span></p> <div><span class="Apple-style-span" style="font-weight: bold">Encapsulating Relationships</span></div> <div></div> <p>Most of the relationships have real meaning in their own right but sometimes they are just an artifact of the design, in those cases you can demote the associations to being just an encapsulated detail.</p> <p>Take the association between <span class="Apple-style-span" style="font-style: italic">Client </span>and <span class="Apple-style-span" style="font-style: italic">Account</span>, maybe when you ask for the <span class="Apple-style-span" style="font-style: italic">Accounts </span>for a <span class="Apple-style-span" style="font-style: italic">Client</span> you want to get the <span class="Apple-style-span" style="font-style: italic">Account </span>objects rather than the <span class="Apple-style-span" style="font-style: italic">ClientAccountRelationship </span>objects. </p> <p>If this were the case you could keep the <span class="Apple-style-span" style="font-style: italic">ClientAccountRelationship </span>class, which has its own data/behaviour and makes mapping easier, but entirely hide it from users of the domain. One way to do this is to create <a href="http://colinjack.blogspot.com/2008/09/nhibernate-mapping-custom-collections.html">custom collection</a> called <span class="Apple-style-span" style="font-style: italic">ClientAccounts <span class="Apple-style-span" style="font-style: normal">and have it </span><span class="Apple-style-span" style="font-style: normal">wrap an </span></span><span style="color: #2b91af">IList</span>&lt;ClientAccountRelationship&gt;<span class="Apple-style-span" style="font-style: italic"><span class="Apple-style-span" style="font-style: normal"> whilst acting like it is just a simple </span></span><span style="color: #2b91af">IList</span>&lt;Account&gt;<span class="Apple-style-span" style="font-style: italic"><span class="Apple-style-span" style="font-style: normal">, it can also provide helpful methods like <span class="Apple-style-span" style="font-style: italic">FindPrimaryOwner.</span></span></span></p> <div><span class="Apple-style-span" style="font-weight: bold">Summary</span></div> <div></div> <p>I mention all of this because when I got started with DDD relationship objects bothered me especially as we were working with a legacy database and I saw the relationship objects as being a problem caused by the number of join tables. At the time my plan was to get rid of a lot of them by taking advantage of NHibernate magic. </p> <p>However as I got a bit more experience I realized that they were key and although we encapsulated some (when they <span class="Apple-style-span" style="font-style: italic">were</span> just an artifact of the design) we made others totally key parts of the design. In both cases the relationships themselves were very useful.</p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=cg2zaXqL"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?d=41" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=AXnWXxs4"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?i=AXnWXxs4" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=XpqLFy70"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?i=XpqLFy70" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=WlM55s7w"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?i=WlM55s7w" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/netDomainDrivenDesign/~4/HAQMmTdKX_4" height="1" width="1" alt=""/>Colin Jackhttp://www.blogger.com/profile/01403166737046938219noreply@blogger.com3tag:blogger.com,1999:blog-32609450.post-7838475971047714062008-10-28T22:18:00.002+00:002008-10-28T22:23:11.380+00:00Domain Driven Design - Knowledge Level<p>A recent thread on the <a href="http://tech.groups.yahoo.com/group/altdotnet/message/16491">ALT.NET forum</a> got me thinking about KNOWLEDGE LEVEL, a seldom discussed but useful pattern from domain driven design. As with many patterns near the end of the book its a pattern that isn't going to suit every situation but it is a pattern that I think has a lot of value. In summary we aim to explicitly split our model into:</p> <ol> <li><strong>Operations Level</strong> - The place that we do our day-to-day business. For example <em>Shipment</em>, <em>Account</em>. </li> <li><strong>Knowledge Level</strong> - Objects that describe/constrain the objects in the basic (operations) level. For example <em>EmployeeType</em>, <em>RebatePaymentMethod</em>, <em>ShipmentMethod</em>. </li> </ol> <p>I'm not a big fan of just repeating what's already in books and to my mind if you want to understand DDD then I'd suggest you read the <a href="http://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215">DDD bible</a>. I'm thus not going to go over the pattern, but I did think it was worth a post about what I've found when coming to the detailed design and implementation of classes in a knowledge layer. I thought I'd start by discussing how you can persist/load/model objects in the KNOWLEDGE LEVEL, moving on to other topics in later posts. Two caveats:</p> <ol> <li><strong>Simple Example</strong> - Rather than using a real example I've chosen to use the shipping method example from the thread, I've never worked in that domain so this may be a bad idea but it felt right... </li> <li><strong>Might seem obvious </strong>- If you are an object/behaviour first type of developer then you'll be looking at using OO techniques and so some of this will just be waffle. However I've seen situations where people used data-driven techniques when approaching their KNOWLEDGE LEVEL and so I wanted to explain why I think it's a bad idea. </li> </ol> <h3><strong></strong></h3> <h3><br /></h3><h3><strong>Option 1 - Data First Approach</strong></h3> <p>Since we store our operational objects in the database why not do the same for our KNOWLEDGE LEVEL? If we go down this path then we'd have a <em>ShippingMethod</em> table with one row for each shipping method we support. Of course each shipping method has different characteristics, perhaps certain shipping methods are only available to long standing customers or customers in certain countries. To support this we'll end up with extra columns in the <em>ShippingMethod</em> table and maybe even associations to other tables. To get the <em>ShippingMethods</em> from the database we'd probably use a REPOSITORY, probably making sure that the REPOSITORY is read-only (maybe not always, see pattern for information on modifying the KNOWLEDGE LEVEL).</p> <p><strong>Disadvantages</strong></p> <p>This approach obviously has disadvantages:</p> <ol> <li><strong>Loss of clarity</strong> - Our ubiquitous language might refer to a "local carrier shipping method" but it won't be visible in the domain model and in fact to see details about this shipping method you need to look at the appropriate row in the <em>ShippingMethod</em> table. Even if you don't value the ubiquitous language this is a problem because as a developer you'll end up switching between the code and database in order to understand even simple aspects of the behaviour. </li> <li><strong>Goodbye OO, hello procedural</strong> - Since there is no <em>LocalCarrierShippingMethod</em> class I have nowhere to put its behaviour, instead I have to fall back on a procedural style of program where we load in the data about the <em>ShippingMethod</em> with an ID of 3 (which happens to be the local carrier shipping method) and then look at its <em>SupportsInternationalDelivery</em> boolean flag before deciding how to proceed (hopelessly naive example alert). We can encapsulate this logic in a service, perhaps a <em>ShippingMethodSelectionService</em> but its still more than a little smelly. </li> <li><strong>No explicit associations</strong> - Imagine if we know that the local carrier shipping method is only available for certain types of <em>Orders</em> and that the decision making also takes into account the <em>Customer</em> placing the <em>Order</em>. If we're using the database-driven approach then managing this becomes very difficult, we can't just look at our <em>LocalCarrierShippingMethod</em> class or at some code that sets up the associations. Instead we fall back and run a database query involving all sorts of joins. </li> </ol> <p><strong>Advantages</strong></p> <p>Those are, as I see it, the primary disadvantages of hiding this important information in the database. Ofcourse its not all bad:</p> <ol> <li><strong>Consistency</strong> - Our KNOWLEDGE LEVEL is handled in the same was the rest of the domain model, loaded from the database as required. Not sure its a massive advantage though because we've explicitly chosen break out the KNOWLEDGE LEVEL its fair enough to say that the consistency has limited value. </li> <li><strong>Flexibility</strong> - If we want to add a new kind of <em>ShippingMethod</em> we just add a row to the <em>ShippingMethod</em> table, no need to redeploy. That's the idea anyway, but its not always going to work especially when the related procedural code has to change. </li> </ol> <p>Its also fair to say that the KNOWLEDGE LEVEL changes at a different pace to the rest of the model, we probably don't add <em>ShippingMethods</em> too often. However we might want to be able to change characteristics of existing <em>ShipmentMethod's</em>, such as changing their price (remember this probably only affects future <em>Shipments</em>) or changing what <em>Countries</em> they can be used in. So on the flexibility angle you've actually got a couple of types of changes:</p> <ol> <li><strong>Adding/removing concepts</strong> - Perhaps adding a donkey based shipment method, to me its safe to require a redeploy for this sort of change and in any case without some serious thought we're not necessarily going to be able to do just by modifying a table anyway. </li> <li><strong>Changing configuration/associations - </strong>Its maybe fair enough to expect to be able to ban using donkey based shipping for all future orders in Spain without requiring the code to be redeployed. As I'll show below this can work even if you go for an object-oriented approach and I also think this is a case where a DSL would really add value (not tried that though). </li> </ol> <p>Those are the main advantages I've heard about, and as I say I'm not sold on them. That brings me on to how I think you should go about it...</p> <h3> </h3> <h3>Option 2 - Object Oriented Approach</h3> <p>Take that "local carrier shipping method" concept and turn it into a <em>LocalCarrierShippingMethod</em> class, probably inheriting from a <em>ShippingMethod</em> base class. There's only one instance of this class and since its read-only (at least as far as normal usage goes) it's totally safe to share it. The <em>ShippingMethod</em> has any data it needs to support the behaviour it contains and to support the interface that it exposes, so for example you might have an <em>IsApplicableForSending(Shipment)</em> with each subclass providing their own implementation.</p> <p><strong>Implementation</strong></p> <p>How does this look in practice, well one approach I've used is to a variant of the <a href="http://msmvps.com/blogs/jon_skeet/archive/2006/01/05/classenum.aspx">typesafe enum</a> pattern. The following is just pseudo code to show the idea:</p> <pre class="code"><span style="color:blue;">public abstract class </span><span style="color:#2b91af;">ShipmentMethod<br /></span>{<br /> <span style="color:blue;">private static </span><span style="color:#2b91af;">Dictionary</span>&lt;<span style="color:#2b91af;">ShipmentMethodKind</span>, <span style="color:#2b91af;">ShipmentMethod</span>&gt; _shippingMethods = <span style="color:blue;">new </span><span style="color:#2b91af;">Dictionary</span>&lt;<span style="color:#2b91af;">ShipmentMethodKind</span>, <span style="color:#2b91af;">ShipmentMethod</span>&gt;();<br /><br /> <span style="color:blue;">static </span>ShipmentMethod()<br /> {<br /> <span style="color:green;">// NOTE: In practice you wouldn't do it like this but it is just an example....<br /> </span>_shippingMethods.Add(<span style="color:#2b91af;">ShipmentMethodKind</span>.LocalCarrier, <span style="color:blue;">new </span><span style="color:#2b91af;">LocalCarrierShippingMethod</span>());<br /> _shippingMethods.Add(<span style="color:#2b91af;">ShipmentMethodKind</span>.DonkeyBased, <span style="color:blue;">new </span><span style="color:#2b91af;">DonkeyBasedShippingMethod</span>());<br /> }<br /><br /> <span style="color:blue;">public </span><span style="color:#2b91af;">IEnumerable</span>&lt;<span style="color:#2b91af;">ShipmentMethod</span>&gt; GetAll()<br /> {<br /> <span style="color:blue;">return </span>_shippingMethods.Values;<br /> }<br /><br /> <span style="color:blue;">public </span><span style="color:#2b91af;">ShipmentMethod </span>GetByKey(<span style="color:#2b91af;">ShipmentMethodKind </span>key)<br /> {<br /> <span style="color:blue;">return </span>_shippingMethods[key];<br /> }<br /><br /> <span style="color:blue;">public abstract bool </span>IsApplicableFor(<span style="color:#2b91af;">Shipment </span>toEvaluate);<br />}<br /><br /><span style="color:blue;">public enum </span><span style="color:#2b91af;">ShipmentMethodKind<br /></span>{<br /> LocalCarrier = 0,<br /> DonkeyBased = 1<br />}<br /><br /><span style="color:blue;">public class </span><span style="color:#2b91af;">LocalCarrierShippingMethod </span>: <span style="color:#2b91af;">ShipmentMethod<br /></span>{<br /> <span style="color:blue;">public override bool </span>IsApplicableFor(<span style="color:#2b91af;">Shipment </span>toEvaluate)<br /> {</pre><p>Don't get too hung up on the implementation, some of it is optional (e.g. <em>ShipmentMethodKind</em>) and it could be refractored quite a bit, I'm really just trying to show the idea not to show how to actually implement a solution.<br /></p><p>You can see that in this case <em>ShipmentMethod</em> is really just a SPECIFICATION but in real situations a <em>ShipmentMethod</em> might well have more behaviour and data. The base class gives us an easy way to access all the <em>ShipmentMethods</em> that the system handles, this can be useful because it could easy provide useful methods like <em>GetAllShipmentMethodsThatCanHandle(Shipment)</em>.</p><p>In reality there are multiple ways of implementing this, in particular you might want to load in the configuration for each <em>ShipmentMethod</em> from a database or other data source. This is more flexible than including it in the code but slightly more complicated to implement.</p><p><strong>Referential Integrity</strong></p><p>If you choose not to load the data from the database then we might seem to have a problem, how do we associate this <em>ShipmentMethod</em> with other objects in the KNOWLEDGE LEVEL and operational level?</p><p>It would seem that we've lost referential integrity but we have choices:</p><ol> <li><strong>Generate tables</strong> - The code in the static constructor in <em>ShipmentMethod</em> can be used to generate a table in the database.</li> <li><strong>Use enum value as key</strong> - We can instead treat the value of the <em>ShipmentMethodKind</em> as a "key" in the database, automated tests will make spotting any issues really quick.</li> <li><strong>Have separate config table</strong> - As I said earlier we may want to load the configuration information for each <em>ShipmentMethod</em> from the database, if so we have a ShipmentMethod table which resolves the problem.</li></ol><p>In any case I haven't found this to be a major issue, by and large I don't care that my <em>ShipmentTable</em> has a <em>ShipmentMethodId</em> table which doesn't lead me anywhere as if I want to understand what's going on I go back to the domain model.</p><h3><br /></h3><h3>In Closing</h3><p>Not sure this topic needed as much details I've put in here, really its the KNOWLEDGE LEVEL pattern that's key but I hoped that by enumerating some of the implementation choices that I've seen I'd help you make an informed decision.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=7lIFfrVC"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?d=41" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=adbwB2JG"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?i=adbwB2JG" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=eHdTDzxL"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?i=eHdTDzxL" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=aE6BXmLl"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?i=aE6BXmLl" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/netDomainDrivenDesign/~4/Gxl9Rcyig0o" height="1" width="1" alt=""/>Colin Jackhttp://www.blogger.com/profile/01403166737046938219noreply@blogger.com0tag:blogger.com,1999:blog-32609450.post-16863291993041698422008-10-28T21:34:00.003+00:002008-10-28T22:35:19.946+00:00Biztalk and WCF - When two big beasts collide<p>I spent the entirety of last week trying to create a ridiculously simple Biztalk orchestration and trying to get it to talk to a simple WCF service and I thought I should describe what I &quot;learned&quot;.</p> <p><strong>Biztalk</strong></p> <p>If you follow me on <a href="http://twitter.com/colin_jack">Twitter</a> you'll know how unbelievably annoyed the results made me and although I didn't learn much from the experience I thought I should put down some tips:</p> <ol> <li>If Biztalk gives you an error DO NOT read it, the message itself is bound to be utter jibberish and the correct response is to put it straight into Google. </li> <li>If Biztalk behaves like a problem is with step N don't assume that step N-1 passed especially if step N-1 is a transformation. You can test the transformation in isolation within the IDE using a sample document so do it, </li> <li>If you are having real problems working out why Biztalk and WCF aren't playing ball then it might well be XML namespaces that are the issue. </li> <li>If you're thinking of renaming the orchestration or anything in it be careful and take a backup first. </li> </ol> <p><strong>WCF</strong></p> <p>Whilst Biztalk left me cold the WCF side of it was a joy, mainly because <a href="http://www.johnnyhall.co.uk/">Johnny Hall</a> pointed me at the <a href="http://www.castleproject.org/container/facilities/trunk/wcf/index.html">Castle WCF Facility</a> and his own usages of it. Using the WCF Facility configuring your services is an utter joy, definitely when compared to the XML based approach that you get with bog-standard WCF. The documentation isn't great but the tests that you get with the Castle <a href="http://svn.castleproject.org:8080/svn/castle/trunk/">source code</a> are the real way to see how to use its fluent interface.</p> <p>Johnny also suggested we use a console application to host the service when testing and a Windows Service when deploying for a real. The console application makes testing locally a lot easier, just CTRL+F5 and your host is loaded and ready for you to fire requests at it. </p> <p>If only Biztalk was as enjoyable to use...</p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=Kt83cY9R"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?d=41" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=QUUTKeKn"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?i=QUUTKeKn" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=U6dM95tg"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?i=U6dM95tg" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=3uizuTO0"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?i=3uizuTO0" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/netDomainDrivenDesign/~4/TiBaPV3J5Sk" height="1" width="1" alt=""/>Colin Jackhttp://www.blogger.com/profile/01403166737046938219noreply@blogger.com5tag:blogger.com,1999:blog-32609450.post-65161837766471116662008-10-28T17:11:00.001+00:002008-12-28T21:49:47.825+00:00BDD - Files/Folders/Namespaces (BDD)<span style="FONT-WEIGHT: bold">Files/Folders</span><br />One thing that can be troublesome when moving from TDD to BDD is how to organize your files and folders, so far I've tried two approaches: <ol><li><span style="FONT-WEIGHT: bold">One class in each file</span> - So if you have <span style="FONT-STYLE: italic">Whe</span><span style="FONT-STYLE: italic">n_associating_an_order_with_a_customer </span>and <span style="FONT-STYLE: italic">When_associating_an_order_with_a_preferred_customer</span> then they'd be in seperate files even though they are very closely related. If they share a base class, or a class they both compose, then that would be in yet another class (presumably).<br /></li><li><span style="FONT-WEIGHT: bold">Multiple classes per file</span> - As an example you might group the <span style="FONT-STYLE: italic">Order</span> addition contexts into a file called <span style="FONT-STYLE: italic">OrderPlacementSpecifications</span>, the file could also contain the shared base class (if you went down that road). </li></ol>To me the second approach has a couple of advantages: <ol><li><span class="Apple-style-span" style="FONT-WEIGHT: bold">Gives the reader extra information</span> - By grouping the two order placement classes we tell the reader that they are quite closely related.<br /></li><li><span style="FONT-WEIGHT: bold">Simplifies folder structure</span> - If we go for the other approach, one class in each file, then we're probably going to have to have more folders. The addition of the extra files and folders definitely makes the solution file harder to structure.</li></ol>To give you an idea here's a screen shot of a part of the folder structure for a sample app we're doing:<br /><br /><div style="TEXT-ALIGN: left"><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_DTvjK44dn8U/SPdvGtdZY8I/AAAAAAAAAHs/Li5AAFMIZt4/s1600-h/BDDFolder.JPG"><img id="BLOGGER_PHOTO_ID_5257793251051135938" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: pointer; TEXT-ALIGN: center" alt="" src="http://1.bp.blogspot.com/_DTvjK44dn8U/SPdvGtdZY8I/AAAAAAAAAHs/Li5AAFMIZt4/s320/BDDFolder.JPG" border="0" /></a><span style="FONT-WEIGHT: bold">Namespaces</span><br /></div>In addition to files/folders I've tried a few approaches to structuring namespaces but the approach I'm trying now groups related artifacts. For example:<br /><ol><li>Specifications.Users.Domain</li><li>Specifications.Users.Domain.Contacts</li><li>Specifications.Users.Services</li><li>Specifications.Users.Domain.Repositories</li><li>Specifications.Users.UI.Controllers</li></ol>The "Specifications" bit adds very little but I think grouping all specifications related to users is useful, not least as R# makes it easy to run all the specifications in a namespace. This can be useful if you have a big solution and only want to run the specifications for the area your working on. Its also worth saying that its "Users" to avoid clashing with the "User" class.<br /><br />Folder wise however we're using a standard approach where your Repositories are in a completely seperate folder from your controllers, even though they might both relate to a particular entity. To me the lack of relationship between our folders and namespaces isn't a problem though, with R# its easy to find a file/type and in addition the folder/namespace tell you two different things about your codebase (one by "layer", one by "feature").<br /><br />So I'm interested in peoples views? I'm guessing you'll all dislike it though because from what I've seen no matter what you do people will be unhappy with your file/folder/namespace scheme. Pluse we'll probably turn against this approach next week....<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=zBZtuNow"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?d=41" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=J6cZ6XXp"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?i=J6cZ6XXp" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=LajMce0a"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?i=LajMce0a" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=vHDaV3fY"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?i=vHDaV3fY" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/netDomainDrivenDesign/~4/r9oHnFcZlKo" height="1" width="1" alt=""/>Colin Jackhttp://www.blogger.com/profile/01403166737046938219noreply@blogger.com2tag:blogger.com,1999:blog-32609450.post-14143446917755258052008-10-23T19:58:00.001+01:002008-10-23T19:58:19.455+01:00What I want from an ORM<p>Thought I'd blog about some of the things I'd like to see in an ORM in the future, particularly to support DDD cleanly:</p> <ol> <li><strong>No enforced associations</strong> - I never want to create an association in the model just to support persistence, regardless of where keys are stored. So if I want to use uni-directional associations then I should be able to do that without having to go <a href="http://colinjack.blogspot.com/2007/08/nhibernate-gotchas-living-with-legacy.html">for workarounds</a>.</li> <li><strong>Aggregate locking </strong>- Currently, with NHibernate at least, its difficult to lock an entire aggregate. For example NHibernate's optimistic concurrency approach involves applying a version to rows, however aggregates can span tables so we really want to be able to give each aggregate a shared version (<a href="http://colinjack.blogspot.com/2007/05/nhibernate-and-coarse-grained-locking.html">coarse-grained locking approach</a>). See <a href="http://martinfowler.com/eaaCatalog/coarseGrainedLock.html">coarse-grained lock pattern</a>.</li> <li><strong>Validating before saving</strong> - I'd like hooks to automatically and cleanly validate an entire aggregate before persistence. </li> <li><strong>Disabling unit of work</strong> - I'd like to be able to disable my unit of work, in many cases when working with DDD the UOW becomes more of a hindrance than anything else. I really want to be 100% sure that the only way to save a <em>Customer</em> is through a <em>CustomerRepository</em>.</li> <li><strong>Revalidate value objects when reloading</strong> - Value objects only validate their data in their constructors, if your ORM does not ensure that a constructor that performs the validation is also used when reloading the object then its possible to end up with an invalid Value object. This is something you definitely want to avoid. Greg Young has raised this issue a few times, including in the <a href="http://groups.google.com/group/nhusers/browse_thread/thread/f10a2328dd4b11eb/938bb50c534e8fee?lnk=gst&amp;q=Greg+Young#938bb50c534e8fee">NHibernate forum</a>, and made some very good points.</li> <li><strong>Value objects</strong> - Choosing to view something as a value object is a design decision that you make irrespective of the underlying DB design, so whilst the NHibernate component mapping is useful it should be as powerful as the mappings used elsewhere. Unfortunately with NHibernate <a href="http://colinjack.blogspot.com/2007/08/nhibernate-gotchas-living-with-legacy.html">components don't support inheritance</a> <a href="http://colinjack.blogspot.com/2008/03/nhibernate-working-around-lack-of.html">nicely</a> and if your value object is stored in a separate table <a href="http://tech.groups.yahoo.com/group/domaindrivendesign/message/5270">things get confusing</a>.</li> </ol> <p>There may be other things I'd want but those are the ones that come to mind.</p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=xVKPqqrv"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?d=41" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=PjMHWego"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?i=PjMHWego" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=o7Fbw3yr"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?i=o7Fbw3yr" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=MsA8BBPN"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?i=MsA8BBPN" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/netDomainDrivenDesign/~4/c2pXrrF_8Mk" height="1" width="1" alt=""/>Colin Jackhttp://www.blogger.com/profile/01403166737046938219noreply@blogger.com1tag:blogger.com,1999:blog-32609450.post-78428093853914190422008-10-23T12:44:00.002+01:002008-10-23T12:48:02.448+01:00New HomeJust to let you know that I'll now also be posting over at <a href="http://www.lostechies.com/blogs/colinjack/">lostechies</a>. Obviously I'll continue to post everything here though so you only need to do anything if your already subscribed to the <a href="http://feeds.feedburner.com/LosTechies">lostechies feed</a> and getting my blog entries twice is annoying you.<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=mbcKqqoM"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?d=41" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=TZCQTDHH"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?i=TZCQTDHH" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=isQqcZ6C"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?i=isQqcZ6C" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=T8QwKZEk"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?i=T8QwKZEk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/netDomainDrivenDesign/~4/w6mCSQ512ck" height="1" width="1" alt=""/>Colin Jackhttp://www.blogger.com/profile/01403166737046938219noreply@blogger.com1tag:blogger.com,1999:blog-32609450.post-20515144819502822872008-10-22T21:06:00.003+01:002008-10-22T21:59:26.920+01:00DDD and Complexity<p></p> <p>There have been some interesting and entirely valid discussions on Twitter about the validity of DDD and about deciding when its useful and when its too complex (including good comments from <a href="http://twitter.com/caseycharlton/statuses/970664982">Casey Charlton</a> and <a href="http://twitter.com/jbogard/statuses/970667578">Jimmy Bogard</a>). I full agree with Casey and Jimmy and the comments, when combined with an interesting discussion on the topic at the latest ALT.NET UK discussion, let me wanting to blog about how I think DDD can be used in different types of projects.</p> <p>First off I must admit that even for a simple business system I'd be thinking about using some of the patterns from DDD, in particular I think these usually have value:</p> <ol> <li><strong>Aggregate</strong></li> <li><strong>Repository</strong></li> <li><strong>Service</strong></li> </ol> <p>For example I find that thinking about aggregates makes me think much more carefully about how to map those classes to the database, for example how far to cascade, which in my view is a good idea as not thinking about boundaries can lead you to some fairly annoying debugging sessions. You can take these three patterns and with a good ORM and create and map a simple domain model to a green fields database very quickly.&#160; </p> <p><strong>Tradeoffs</strong></p> <p>Here's some of the tradeoffs we're making when using DDD on a system that it doesn't necessarily suit:</p> <ol> <li><strong>Analysis/Design</strong> - We map completely skip the analysis/design and in particular the discussions with the domain expert, instead starting from our requirements and letting TDD and our own design skills guides us to the correct design.</li> <li><strong>Encapsulation</strong> - We might expose everything using getters and setters and the domain may be anaemic, for example validation may be in attributes and/or use a <a href="http://www.castleproject.org/activerecord/documentation/v1rc1/usersguide/validation.html">custom framework</a>.</li> <li><strong>Design Clarity</strong> - If our primary focus is on getting going fast then we're going to have to cut some corners.&#160; We'd bind the domain to the GUI, design it to be as easy to map to the database, make it easy to create domain objects (default constructors) and generally make tradeoffs in the quality of the domain model to make our own lives easier. </li> <li><strong>Flexibility</strong> - A model that is quick to create/map/bind is not likely going to be flexible, this may or may not be a problem.</li> <li><strong>Patterns</strong> - We're ignoring half the patterns in DDD, patterns that have a lot of value in a complex domain model but may not be justified when the domain is simpler/more closely bounded.</li> </ol> <p>We make these tradeoffs to make our lives easier and in particular I wanted to cover two of the tradeoffs you may choose to make.</p> <p><strong>Design Clarity</strong></p> <p>If we want to be able to bind your GUI to the domain and map it to the database quickly then we can being to fray our domain model:</p> <ol> <li>Value objects make binding and displaying validation errors trickier.</li> <li>If our user interface uses wizards then the GUI will want to create domain objects early on in the wizard, possibly without giving us any meaningful data. We thus end up with default constructors or constructors with very few arguments.</li> <li>If we use an ORM with a unit of work it will probably fight against our need to validate aggregates before saving them.</li> <li>If we use an ORM we'll find it hard to version the entire aggregate.</li> </ol> <p>With discipline you can make these tradeoffs whilst still maintaining a comprehensible model but there is no doubt that we are making tradeoffs. </p> <p><strong>Flexibility</strong></p> <p>We're also sacrificing flexibility, for example a lot of talk about repositories right now focuses on generic repositories. For example we'd have a <em>Repository&lt;T&gt;</em> class where T is an aggregate root and you'd have query methods on this repository that would take Linq specifications. That's going to be fine for a lot of cases but in more complex models (or where we don't control our environment fully) our repository can encapsulate complex logic, for example we should be able to ensure the following:</p> <ol> <li>Instances of aggregate are never deleted or they are simply archived.</li> <li>Instances of aggregate Y are built up from multiple data sources.</li> <li>Instead of mapping aggregate Z to a (legacy) DB we map some simple DTO's and then in the repository convert them to our nicely designed aggregate.</li> <li>Query Z is very expensive and needs to be done using SQL. </li> </ol> <p>Those are all things I&#8217;ve had to be involved in when working with a moderately complex domain model and repositories helped encapsulate those details. So whilst I think generic repositories might have their place ins some systems I think you have to be aware of the choices your making.</p> <p><strong>What was the point of all this?</strong></p> <p>My point with all this is that you can get a lot of value from DDD without following it too closely, but you need to be aware of what tradeoffs your making and why. Choosing to go for a simple domain model when you have a complex problem to solve is a really bad choice and going from active record (true active record) to a real domain model is not going to be a smooth transition. </p> <p>However I don't think the choice is easy, for example there's been a lot of discussion recently on whether DDD and complex models are suitable for CRUD related problems. In general I can see why using DDD on an average CRUD system is a mistake but sometimes it is worth using. For example we used DDD on a CRM system that among other things handled parties and their associations in a temporal manner. This was a complex modelling problem solved with a complex pattern but primarily we were handling CRUD (including constraints/validation) and setting the stage for other systems to use the information. Trying to do this using active record would, in my view, have been a big mistake.</p> <p>So as Casey pointed out DDD is expensive and whilst it can pay off you need to do in with eyes open fully aware of the tradeoffs involved.</p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=ypiBRm2a"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?d=41" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=k2gLA9Ha"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?i=k2gLA9Ha" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=PZ6EbC9n"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?i=PZ6EbC9n" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/netDomainDrivenDesign?a=L4K9YUyE"><img src="http://feeds.feedburner.com/~f/netDomainDrivenDesign?i=L4K9YUyE" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/netDomainDrivenDesign/~4/MLmajuKrCG8" height="1" width="1" alt=""/>Colin Jackhttp://www.blogger.com/profile/01403166737046938219noreply@blogger.com6