<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/rss2full.xsl" type="text/xsl" media="screen"?><?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/itemcontent.css" type="text/css" media="screen"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">

<channel>
	<title>The Disco Blog</title>
	
	<link>http://thediscoblog.com</link>
	<description>Can you dig it man?</description>
	<pubDate>Tue, 22 Jul 2008 18:49:48 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6</generator>
	<language>en</language>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/TheDiscoBlog" type="application/rss+xml" /><item>
		<title>RESTful services without the sweat</title>
		<link>http://thediscoblog.com/2008/07/22/restful-services-without-the-sweat/</link>
		<comments>http://thediscoblog.com/2008/07/22/restful-services-without-the-sweat/#comments</comments>
		<pubDate>Tue, 22 Jul 2008 18:42:12 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
		
		<category><![CDATA[Articles]]></category>

		<category><![CDATA[java]]></category>

		<category><![CDATA[rest]]></category>

		<category><![CDATA[restlets]]></category>

		<guid isPermaLink="false">http://thediscoblog.com/?p=230</guid>
		<description><![CDATA[Representational state transfer (also known as REST, baby) is an approach to designing loosely coupled applications that rely on named resources rather than messages. As it turns out, the most involved part of building a RESTful application is deciding on the resources you want to expose. Once you&#8217;ve done that, building RESTful Web services a [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://en.wikipedia.org/wiki/Representational_State_Transfer">Representational state transfer</a> (also known as <a href="http://thediscoblog.com/2008/07/16/resting-at-ease-with-jsr-311/">REST</a>, baby) is an approach to designing loosely coupled applications that rely on named resources <em>rather than</em> messages. As it turns out, the most involved part of building a RESTful application is deciding on the resources you want to expose. Once you&#8217;ve done that, building RESTful Web services a snap, especially if you use the <a href="http://www.restlet.org/">Restlet framework</a>, which greatly simplifies the task of defining and implementing RESTful services.  </p>
<p>Check out IBM <a href="http://www.ibm.com/developerworks/">developerWorks</a>&#8216; tutorial dubbed &#8220;<a href="http://www.ibm.com/developerworks/edu/j-dw-java-rest-i.html">Build a RESTful Web service</a>&#8220;&#8211; in it, you&#8217;ll get to know what REST is and how to build RESTful applications with Restlets, plus, you&#8217;ll see how to deploy and test them while you are at it!</p>
<p><center>Have a listen to <a href="http://www.javaworld.com/podcasts/jtech/">JavaWorld's Java Technology Insider</a></center></p>]]></content:encoded>
			<wfw:commentRss>http://thediscoblog.com/2008/07/22/restful-services-without-the-sweat/feed/</wfw:commentRss>
		</item>
		<item>
		<title>The weekly bag– July 18</title>
		<link>http://thediscoblog.com/2008/07/18/the-weekly-bag-july-18/</link>
		<comments>http://thediscoblog.com/2008/07/18/the-weekly-bag-july-18/#comments</comments>
		<pubDate>Fri, 18 Jul 2008 21:12:12 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
		
		<category><![CDATA[Weekly Bag]]></category>

		<category><![CDATA[Agile]]></category>

		<category><![CDATA[ci]]></category>

		<category><![CDATA[citcon]]></category>

		<category><![CDATA[code coverage]]></category>

		<category><![CDATA[code review]]></category>

		<category><![CDATA[guice]]></category>

		<category><![CDATA[lean]]></category>

		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://thediscoblog.com/?p=228</guid>
		<description><![CDATA[Enjoy the reading, baby:

Continuous Integration at Agile 2008&#8211; boy, there are a lot of CI talks at Agile 2008 this year.
Top 10 Things I do on Every Project- #9 is using Google&#8217;s Guice! Oh wait, he works for Google.
An Introduction to Lean Thinking for Software- this is a good read&#8211; it reminds me of a [...]]]></description>
			<content:encoded><![CDATA[<p>Enjoy the reading, baby:</p>
<ul>
<li><a href="http://ericlefevre.net/wordpress/2008/07/17/continuous-integration-at-agile-2008/">Continuous Integration at Agile 2008</a>&#8211; boy, there are a lot of CI talks at Agile 2008 this year.</li>
<li><a href="http://misko.hevery.com/2008/07/16/top-10-things-i-do-on-every-project/">Top 10 Things I do on Every Project</a>- #9 is using <a href="http://code.google.com/p/google-guice/">Google&#8217;s Guice</a>! Oh wait, he works for Google.</li>
<li><a href="http://www.infoq.com/articles/lean-thinking-software">An Introduction to Lean Thinking for Software</a>- this is a good read&#8211; it reminds me of a classic quote from <a href="http://citconf.com/denver2008/">CITCON in Denver</a> a few months back. My friend <a href="http://upcoming.yahoo.com/event/639434/">Jeffrey Fredrick</a> mused that &#8220;source code is inventory&#8221; &#8212; essentially meaning it&#8217;s excess baggage until in binary form and in production. </li>
<li><a href="http://memeagora.blogspot.com/2008/07/finally-treeware.html">Finally Treeware</a>- my friend Neal Ford&#8217;s book is finally available! I received mine the other day&#8211; it promises to be an excellent read. </li>
<li><a href="http://codetojoy.blogspot.com/2008/07/code-reviews.html">Code Reviews</a>- he has some good points&#8211; do you do code reviews?</li>
<li><a href="http://jasonrudolph.com/blog/2008/07/08/testing-anti-patterns-underspecification/">Testing Anti-Patterns: Underspecification</a>- my friend Jason Rudolph explores <a href="http://www.ibm.com/developerworks/java/library/j-cq01316/index.html">code coverage</a> quite nicely.</li>
</ul>
<p><center>Have a listen to <a href="http://www.javaworld.com/podcasts/jtech/">JavaWorld's Java Technology Insider</a></center></p>]]></content:encoded>
			<wfw:commentRss>http://thediscoblog.com/2008/07/18/the-weekly-bag-july-18/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Reality checking the tools market</title>
		<link>http://thediscoblog.com/2008/07/16/reality-checking-the-tools-market/</link>
		<comments>http://thediscoblog.com/2008/07/16/reality-checking-the-tools-market/#comments</comments>
		<pubDate>Wed, 16 Jul 2008 23:00:21 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
		
		<category><![CDATA[Software Development]]></category>

		<category><![CDATA[agitar]]></category>

		<category><![CDATA[codegear]]></category>

		<category><![CDATA[free]]></category>

		<category><![CDATA[java]]></category>

		<category><![CDATA[mccabe]]></category>

		<category><![CDATA[open source]]></category>

		<category><![CDATA[sdtimes]]></category>

		<guid isPermaLink="false">http://thediscoblog.com/2008/07/16/reality-checking-the-tools-market/</guid>
		<description><![CDATA[
Albert Einstein once mused: 

&#8220;Reality is merely an illusion, albeit a very persistent one.&#8221;

Unfortunately for the vast majority of commercial players in the Java tools market, he may be incorrect&#8211; reality isn&#8217;t an illusion. It&#8217;s a harsh (and rather persistent) truth. You need only scan the various development tools you use on a daily basis [...]]]></description>
			<content:encoded><![CDATA[<p><img style="PADDING-LEFT: 1.0em; PADDING-RIGHT: 0.5em; PADDING-TOP: 0.1em; FLOAT: RIGHT; PADDING-BOTTOM: 0.5em" src="http://thediscoblog.com/images/reality-check-sm.jpg" alt="ahhh!" width="424" height="282"/><br />
Albert Einstein once mused: </p>
<blockquote><p>
&#8220;Reality is merely an illusion, albeit a very persistent one.&#8221;
</p></blockquote>
<p>Unfortunately for the vast majority of commercial players in the Java tools market, he may be incorrect&#8211; reality isn&#8217;t an illusion. It&#8217;s a harsh (and rather persistent) truth. You need only scan the various development tools you use on a daily basis to see that free, for the most part, is king these days. </p>
<p>Two recent <a href="http://www.sdtimes.com/index.aspx">SDTimes</a> articles do a great job of highlighting this reality: first, <a href="http://binstock.blogspot.com/">Andrew Binstock</a> wrote an article dubbed &#8220;<a href="http://sdtimes.com/content/article.aspx?ArticleID=32397">Java tool market disintegrating</a>&#8221; in which he states that the market for selling tools to Java developers</p>
<blockquote><p>
has been unhealthy for years. It is hard to think of a single Java-only tools company that has grown and prospered. One exception is KLGroup, which later became Sitraka and sold for a small fortune to Quest Software during the Internet bubble. Beyond it, though, things drop off quickly. Small companies struggle, living out their bets on Java.
</p></blockquote>
<p>He goes on to highlight three recent events such as <a href="http://thediscoblog.com/2008/05/29/the-business-model-or-lack-thereof-of-selling-unit-testing/">Agitar&#8217;s demise</a>, <a href="http://java.dzone.com/articles/why-enerjy-tools-are-now-free">Enerjy&#8217;s freebee spree</a> and lastly, <a href="http://www.sdtimes.com/content/article.aspx?ArticleID=32238">CodeGear&#8217;s mercy acquisition</a> (one can argue Embarcadero received an 85% discount on the purported $150 million value of CodeGear). Each of the aforementioned affairs do suggest the market for selling tools to Java developers (keep in mind that the CodeGear acquisition included non-Java tools and the support revenue associated with them i.e. Delphi) is rather limited. </p>
<p>Second, SDTimes was quick to release the news that <a href="http://sdtimes.com/content/article.aspx?ArticleID=32515">McCabe Software is acquiring Agitar&#8217;s assets</a>.  On the surface, that could be good news, except for the fact that a Gartner analyst is purported to have said that Agitar&#8217;s product</p>
<blockquote><p><em>might</em> be a good fit within larger suite or a family of QA technologies.
</p></blockquote>
<p>Because it&#8217;s my bag, using the word <em>might</em> in the same story regarding an acquisition is not exactly positive. It&#8217;s like having the word <em>disappointing</em> show up on your resume or during a reference check, man. What&#8217;s more, no dollar figure was highlighted in the article nor the <a href="http://www.prweb.com/releases/mccabe/agitar/prweb1086684.htm">official press release</a>, suggesting Agitar&#8217;s IP was picked up for peanuts (do you think McCabe received an 85% discount like Embarcadero? $5 million? It&#8217;s hard to believe they would pay even that much). </p>
<p>It remains to be seen if McCabe can attain a reasonable market share with the purchased assets; suffice to say, history (and don&#8217;t forget reality, baby!) are working against them. </p>
<p>That&#8217;s not to say that all commercial tools are doomed&#8211; in fact, you need only go to a <a href="http://www.nofluffjuststuff.com/">Java oriented conference</a> to see that <a href="http://www.javaworld.com/podcasts/jtech/2007/121807jtech007.html">IntelliJ</a> continues to impress legions of smart people, who do pay for the copasetic tool even in the face of free competition from the likes of <a href="http://ask.slashdot.org/article.pl?sid=06/01/15/023259">Eclipse</a>.  Plus, <a href="http://www.atlassian.com/">Atlassian</a> continues to wow developers across the globe (they sell various products, however, like <a href="http://www.atlassian.com/software/jira/">JIRA</a>, which isn&#8217;t necessarily a tool marketed to and used by Java developers <em>alone</em>). </p>
<p>It seems a more apt mechanism for describing reality for the majority of commercial tool players in the Java market is, as <a href="http://en.wikipedia.org/wiki/Jane_Wagner">Jane Wagner</a> eloquently stated,</p>
<blockquote><p>
&#8220;Reality is the leading cause of stress amongst those in touch with it.&#8221;
</p></blockquote>
<p>Indeed, as <a href="http://sdtimes.com/content/article.aspx?ArticleID=32397">Andrew Binstock pointed out in his article</a> and as Atlassian is currently demonstrating, the actuality of the Java tools market is that those companies that wish to prosper selling tools to developers must offer a cornucopia of products to a wide range of audiences. That is, they must sell tools not only to developers but to other stakeholders in the application life cycle&#8211; and even then, success (i.e. healthy revenues) is no guarantee. Plus, in this Age of Aquarius, it helps if the company is <a href="http://www.investopedia.com/terms/b/bootstrap.asp">bootstrapped</a> and thus isn&#8217;t required to provide exponential returns in a short timeframe. Can you dig it?</p>
<p><center>Have a listen to <a href="http://www.javaworld.com/podcasts/jtech/">JavaWorld's Java Technology Insider</a></center></p>]]></content:encoded>
			<wfw:commentRss>http://thediscoblog.com/2008/07/16/reality-checking-the-tools-market/feed/</wfw:commentRss>
		</item>
		<item>
		<title>RESTing at ease with JSR 311</title>
		<link>http://thediscoblog.com/2008/07/16/resting-at-ease-with-jsr-311/</link>
		<comments>http://thediscoblog.com/2008/07/16/resting-at-ease-with-jsr-311/#comments</comments>
		<pubDate>Wed, 16 Jul 2008 02:11:39 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
		
		<category><![CDATA[Software Development]]></category>

		<category><![CDATA[java]]></category>

		<category><![CDATA[jersey]]></category>

		<category><![CDATA[jsr]]></category>

		<category><![CDATA[jsr 311]]></category>

		<category><![CDATA[rest]]></category>

		<category><![CDATA[restlets]]></category>

		<category><![CDATA[web services]]></category>

		<guid isPermaLink="false">http://thediscoblog.com/2008/07/16/resting-at-ease-with-jsr-311/</guid>
		<description><![CDATA[REST is a style of designing loosely coupled Web applications that rely on named resources rather than messages. Ingeniously, REST piggybacks on the already validated (and successful, don&#8217;t you think, man?) infrastructure of the Web&#8211; HTTP. That is, REST leverages aspects of the HTTP protocol such as GET and POST requests. Because it&#8217;s REST&#8217;s bag, [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://en.wikipedia.org/wiki/Representational_State_Transfer">REST</a> is a style of designing loosely coupled Web applications that rely on named resources rather than messages. Ingeniously, <a href="http://www.infoq.com/articles/rest-introduction">REST</a> piggybacks on the already validated (and successful, don&#8217;t you think, man?) infrastructure of the Web&#8211; HTTP. That is, <a href="http://www.infoq.com/news/2007/05/is-rest-winning">REST</a> leverages aspects of the HTTP protocol such as GET and POST requests. Because it&#8217;s REST&#8217;s bag, <a href="http://www.infoq.com/articles/tilkov-rest-doubts">RESTful applications</a> turn out to be quite clean in their API as you don&#8217;t spend a lot of time reinventing the wheel&#8211; you get a lot for free when leveraging HTTP. </p>
<p>I&#8217;ve been keeping my eye on <a href="https://jsr311.dev.java.net/">JSR 311</a> as it seemed to make a lot of sense to leverage attributes given the template-like pattern employed by the <a href="http://www.restlet.org/">Restlet framework</a>. For instance, without attributes (and by correlation, JSR 311, which is <a href="http://wiki.restlet.org/docs_1.1/g1/13-restlet/28-restlet/57-restlet.html">supported by a developmental version of the Restlet framework</a>), you are forced to override specific methods in the base framework&#8217;s hip <code>Resource</code> class associated with HTTP verbs&#8211; <code>public void post(Representation representation)</code> handles HTTP POSTs; what&#8217;s more, given that the framework doesn&#8217;t actually know if a subclass has implemented a particular method, you must also override the <code>allowPost</code> method in the case of POST. </p>
<p>In fact, leveraging attributes in the case of JSR 311 (or, as previously mentioned, the 1.1 snapshot version of the Restlet framework) is a lot like comparing JUnit 3.8.1 to <a href="http://www.ibm.com/developerworks/edu/j-dw-java-junit4.html">JUnit 4</a>&#8211; the entire framework paradigm is shifted, which has the result of a lot less noise (a.k.a code). </p>
<p>For instance, implementing a GET request via <a href="https://jsr311.dev.java.net/drafts/spec20080627.pdf">JSR 311</a> is as easy as leveraging the <code>GET</code> attribute:</p>
<pre><code>@GET
@ProduceMime("text/xml")
public String get() {
 Collection&lt;Race&gt; races = Race.findAll();
 return this.reporter.racesToXml(races);
}</code></pre>
<p>Note, this code is leveraging <a href="https://jersey.dev.java.net/">Jersey</a>, Sun&#8217;s reference implementation of JSR 311 (which <a href="http://blogs.sun.com/sandoz/entry/jersey_0_8_is_released">recently released version 0.8</a>). What&#8217;s more, JSR 311 specifies <a href="http://www.mhonarc.org/~ehood/MIME/">mime</a> annotations for both requests and responses &#8212; for instance, the <code>get</code> method above responds with a mime type of &#8220;text/xml&#8221; &#8212; you can easily specify JSON, etc too.  </p>
<p>Handling other requests, such as a POST request is just as easy&#8211; just use the corresponding copasetic annotation (for instance <code>@POST</code>). Note too, with mime types, you can specify accepted request types. In the case below, the <code>post</code> method will only accept &#8220;text/xml&#8221;. </p>
<pre><code>@POST
@ConsumeMime("text/xml")
public Response post(String xml) throws Exception {
 long id = this.consumer.createRace(xml);
 return Response.created(uriInfo.getBaseUriBuilder().
    path(Long.toString(id)).build()).build();
}</code></pre>
<p>Of course, the two method above are related to a particular path or URI&#8211; JSR 311 supports the <code>@Path</code> annotation, which interestingly enough, is inheritable such that a method can expand upon a base path specified at the class level. For instance, the method above live in class defined as follows:</p>
<pre><code>@Path("/race")
public class RacesResource {
  //...
}</code></pre>
<p>Thus, all exposed <a href="http://www.xfront.com/REST-Web-Services.html">RESTful</a> methods will respond to the <code>/race</code> URI (i.e. a HTTP GET to <code>/race</code> will be handled by the <code>get</code> method and a HTTP POST to the <code>/race</code> URI will be handled by the <code>post</code> method (provided the request be of mime type &#8220;text/xml&#8221;, don&#8217;t forget!)). Methods can expand upon the <code>/race</code> URI by providing their own <code>@Path</code> annotation, which will effectively append the specified URI to the base URI. </p>
<p>There are certainly more than a few ways to skin the REST cat in Java, baby&#8211; you&#8217;ve got, to name a few, Restlets, <a href="http://grails.org/doc/1.0.x/guide/13.%20Web%20Services.html">Grails</a>, <a href="http://www.1060.org/">1060 NetKernel</a>, and now JSR 311 via Sun&#8217;s Jersey. Each framework comes with its own bells and whistles; nevertheless, JSR 311 and Jersey definitely lower the barrier for building (and deploying) RESTful applications even if they are fairly late to the party.</p>
<p><center>Have a listen to <a href="http://www.javaworld.com/podcasts/jtech/">JavaWorld's Java Technology Insider</a></center></p>]]></content:encoded>
			<wfw:commentRss>http://thediscoblog.com/2008/07/16/resting-at-ease-with-jsr-311/feed/</wfw:commentRss>
		</item>
		<item>
		<title>It’s ok to wet yourself every once in awhile</title>
		<link>http://thediscoblog.com/2008/07/02/its-ok-to-wet-yourself-every-once-in-awhile/</link>
		<comments>http://thediscoblog.com/2008/07/02/its-ok-to-wet-yourself-every-once-in-awhile/#comments</comments>
		<pubDate>Wed, 02 Jul 2008 02:09:57 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
		
		<category><![CDATA[Developer Testing]]></category>

		<category><![CDATA[Software Development]]></category>

		<category><![CDATA[Agile]]></category>

		<category><![CDATA[bdd]]></category>

		<category><![CDATA[dry]]></category>

		<category><![CDATA[easyb]]></category>

		<category><![CDATA[TDD]]></category>

		<guid isPermaLink="false">http://thediscoblog.com/2008/07/02/its-ok-to-wet-yourself-every-once-in-awhile/</guid>
		<description><![CDATA[Dan North, the veritable progenitor of behavior driven development (or BDD), recently blogged about unnecessary DRYness (meaning don&#8217;t repeat yourself) with respect to clarity of intent when it comes to testing (in generic terms of the word). Essentially, in the case of a JUnit test, for example, by utilizing a setUp method and  possibly [...]]]></description>
			<content:encoded><![CDATA[<p>Dan North, the veritable progenitor of <a href="http://dannorth.net/introducing-bdd">behavior driven development</a> (or BDD), <a href="http://dannorth.net/2008/06/let-your-examples-flow">recently blogged</a> about unnecessary <a href="http://en.wikipedia.org/wiki/Don't_repeat_yourself">DRY</a>ness (meaning don&#8217;t repeat yourself) with respect to <em>clarity of intent</em> when it comes to testing (in generic terms of the word). Essentially, in the case of a <a href="http://www.junit.org/">JUnit</a> test, for example, by utilizing a <code>setUp</code> method and  possibly other helper methods, the test itself becomes somewhat cluttered&#8211; one must jump around the code to truly understand the intention of the test in the first place. <img style="PADDING-LEFT: 0.5em; PADDING-RIGHT: 1.0em; PADDING-TOP: 1.0em; FLOAT: LEFT; PADDING-BOTTOM: 1.0em" src="http://thediscoblog.com/images/shhh.jpg" alt="shh!" width="384" height="263"/></p>
<p>In fact, Dan says it quite nicely&#8211; tests (or stories, baby) are:</p>
<blockquote><p>
&#8220;examples [that] tell a story about what the code does&#8230; [and] clarity of intent is found in the quality of the narrative, not necessarily in minimising duplication.&#8221;
</p></blockquote>
<p>Thus, over <em>utilizing</em> the DRY principle can be ineffective when it comes to testing; indeed, he makes a great point! If tests or stories are intended to serve as &#8220;executable documention&#8221; doesn&#8217;t it make sense to make them as easy to read and understand as possible?  </p>
<p>As such, because it&#8217;s my bag, I took the liberty of pondering the depth of favored term DRY and decided that when it comes to clearly expressing intent with respect to stories (as in the case of <a href="http://easyb.org/">easyb</a>) or tests, it often pays to be <em>WET</em>&#8211; that is, <u>w</u>holly <u>e</u>xpress your <u>t</u>actics, baby. </p>
<p>You see, applying WET to, say, an <a href="http://easyb.org/howtos.html">easyb story</a> then yields perhaps more <em>text</em>, but it leaves no room for misinterpretation, man. For example, imagine a story regarding discounts (this is my touchstone example that is in danger of itself becoming dry&#8211; no pun intended either, man). The high level story is such that VIP customers receive varying discounts depending on the amount of money a particular order has&#8211; you could even require a minimum number of items too (if you were attempting to move inventory). Thus, one scenario could be:</p>
<pre><code>scenario "VIP customer with 3 items, over $30 receiving 10% discount", {
  given "a VIP customer"
  and "given they have at least 3 items totaling over $30"
  when "they proceed to checkout"
  then "they should receive a 10% discount"
} </code></pre>
<p>Of course, from here, stakeholders, through a collaborative effort, realize more scenarios are possible&#8211; for instance, the VIP customer has 3 items totaling over $100&#8211; thus, a higher discount is applied. A first stab of staying WET (that is, <u>w</u>holly <u>e</u>xpressing your <u>t</u>actics, man) yields this scenario: </p>
<pre><code>scenario "VIP customer with 3 items, over $100 receiving 15% discount", {
  given "a VIP customer"
  and "given they have at least 3 items totaling over $100"
  when "they proceed to checkout"
  then "they should receive a 15% discount"
} </code></pre>
<p>Reading these scenarios (which are executable, by the way!) leaves no room for missing the boat&#8211; the tactics involved are wholly expressed!!&#8211; reading them is somewhat effortless from the standpoint that you don&#8217;t necessarily need to jump around the file to gain a clear understanding of context. </p>
<p>If you prefer staying DRY, the story can become more concise&#8211; </p>
<pre><code>before_each "a VIP customer with 3 items is assumed", {
  given "a VIP customer"
  and "given they have at least 3 items"
}

scenario "VIP customer with 3 items, over $30 receiving 10% discount", {
  given "the 3 items total at least $30"
  when "they proceed to checkout"
  then "they should receive a 10% discount"
} 

scenario "VIP customer with 3 items, over $100 receiving 15% discount", {
  given "the 3 items total at least $100"
  when "they proceed to checkout"
  then "they should receive a 15% discount"
} </code></pre>
<p>Both stories convey intent&#8211; it is just that the WET one is more clearly expressed&#8211; in the DRY example, as more and more scenarios are added (and they surely will), one needs to jump to the top to gain an understanding of the underlying assumption (that is, a VIP customer with 3 items in their shopping cart). </p>
<p>DRY is fundamentally a sound principle&#8211; I&#8217;m not here to deny that; however, like all good things, it can be overused without regard for a particular situation. In fact, <a href="http://en.wikipedia.org/wiki/Goethe">Johann Wolfgang von Goethe</a> (of Faust fame, baby) is quoted thus: </p>
<blockquote><p>
&#8220;The phrases that men hear or repeat continually, end by becoming convictions and ossify the organs of intelligence.&#8221;
</p></blockquote>
<p>Because it is everyone&#8217;s bag, baby, think through DRYness from time to time and realize that in some cases, it is perfectly acceptable to WET yourself (I mean, to practice WET).  Can you dig it, man?</p>
<p><center>Have a listen to <a href="http://www.javaworld.com/podcasts/jtech/">JavaWorld's Java Technology Insider</a></center></p>]]></content:encoded>
			<wfw:commentRss>http://thediscoblog.com/2008/07/02/its-ok-to-wet-yourself-every-once-in-awhile/feed/</wfw:commentRss>
		</item>
		<item>
		<title>easyb 0.9 hits the streets</title>
		<link>http://thediscoblog.com/2008/07/01/easyb-09-hits-the-streets/</link>
		<comments>http://thediscoblog.com/2008/07/01/easyb-09-hits-the-streets/#comments</comments>
		<pubDate>Tue, 01 Jul 2008 01:38:24 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
		
		<category><![CDATA[Developer Testing]]></category>

		<category><![CDATA[Groovy]]></category>

		<category><![CDATA[bdd]]></category>

		<category><![CDATA[dsl]]></category>

		<category><![CDATA[easyb]]></category>

		<category><![CDATA[java]]></category>

		<category><![CDATA[TDD]]></category>

		<guid isPermaLink="false">http://thediscoblog.com/2008/07/01/easyb-09-hits-the-streets/</guid>
		<description><![CDATA[
The easyb team is pleased to announce the release of easyb 0.9, baby!
The 0.9 release has:

Numerous IntelliJ plug-in improvements

The easyb plugin for IntelliJ can now be downloaded directly from within IntelliJ! See http://plugins.intellij.net/plugin/?id=2916

Various fixes and improvements addressed from issue tracking system
Fixtures!
More enhanced error reporting
narrative support
description support

easyb supports capturing additional hip information regarding stories, such as [...]]]></description>
			<content:encoded><![CDATA[<p><img style="PADDING-LEFT: 1.0em; PADDING-RIGHT: 0.5em; PADDING-TOP: 0.0em; FLOAT: RIGHT; PADDING-BOTTOM: 1.0em" src="http://thediscoblog.com/images/Bullhorn-713752.jpg" alt="announcement!" width="277" height="350"/><br />
The <a href="http://code.google.com/p/easyb/">easyb team</a> is pleased to announce the release of <a href="http://easyb.googlecode.com/files/easyb-0.9.tar.gz">easyb 0.9</a>, baby!</p>
<p>The 0.9 release has:</p>
<ul>
<li>Numerous IntelliJ plug-in improvements</li>
<ul>
<li>The <a href="http://easyb.googlecode.com/files/intellij-plugin-0.9-dist.zip">easyb plugin for IntelliJ</a> can now be downloaded directly from within IntelliJ! See <a href="">http://plugins.intellij.net/plugin/?id=2916</a></li>
</ul>
<li><a href="http://code.google.com/p/easyb/issues/list?q=status%3AFixed&#038;can=1">Various fixes and improvements</a> addressed from issue tracking system</li>
<li><a href="http://thediscoblog.com/2008/05/16/easy-fixtures-easyb-style/">Fixtures</a>!</li>
<li>More enhanced error reporting</li>
<li><code>narrative</code> support</li>
<li><code>description</code> support</li>
</ul>
<p><a href="http://www.easyb.org">easyb</a> supports capturing additional hip information regarding stories, such as a story&#8217;s description and some detail regarding the features, benefits, and roles of a persona related to a story. For instance, the <a href="http://www.easyb.org/dsls.html">DSL now supports</a> a description syntax that takes a <code>String</code> value &#8212; single quote or Groovy&#8217;s triple quote trick.</p>
<pre><code>description "some description"
scenario "text"</code></pre>
<p>or</p>
<pre><code>description """some long description that requires
multiple lines, etc
"""
scenario "text"</code></pre>
<p>What&#8217;s more, you can provide additional details of a story via the narrative syntax:</p>
<pre><code>description "text"

narrative "description", {
 as_a "role"
 i_want "feature"
 so_that "benefit"
}

scenario "text"</code></pre>
<p>Both the <code>narrative</code> and <code>description</code> keywords are optional and they don&#8217;t have to be used together&#8211; i.e. you can use the <code>narrative</code> one without providing a <code>description</code>. These aspects will be captured in the output (i.e. story report) of an easyb run too.</p>
<p>From a fixture standpoint, easyb supports both one time fixtures (<code>before</code>) and for each scenario (<code>before_each</code>). Of course, you can add <code>tearDown</code>-like behavior in <code>after</code> and <code>after_each</code>.</p>
<p>You can download the latest release from <a href="http://code.google.com/p/easyb/">easyb&#8217;s Google code page</a>.</p>
<p><center>Have a listen to <a href="http://www.javaworld.com/podcasts/jtech/">JavaWorld's Java Technology Insider</a></center></p>]]></content:encoded>
			<wfw:commentRss>http://thediscoblog.com/2008/07/01/easyb-09-hits-the-streets/feed/</wfw:commentRss>
		</item>
		<item>
		<title>The weekly bag– June 27</title>
		<link>http://thediscoblog.com/2008/06/29/the-weekly-bag-june-27/</link>
		<comments>http://thediscoblog.com/2008/06/29/the-weekly-bag-june-27/#comments</comments>
		<pubDate>Sun, 29 Jun 2008 20:41:37 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
		
		<category><![CDATA[Weekly Bag]]></category>

		<category><![CDATA[Agile]]></category>

		<category><![CDATA[java]]></category>

		<category><![CDATA[lean]]></category>

		<category><![CDATA[links]]></category>

		<category><![CDATA[MDD]]></category>

		<category><![CDATA[resources]]></category>

		<category><![CDATA[TDD]]></category>

		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://thediscoblog.com/2008/06/29/the-weekly-bag-june-27/</guid>
		<description><![CDATA[
Agile Smells: Don&#8217;t Let This Happen To You!- I wonder how we went from &#8220;Individuals and interactions over processes and tools&#8221; to cataloging the manifold ways to practice Agile?
Agile Versus Lean- Speaking of Agile, man, Martin&#8217;s got something to say.
RSpec-1.1.4- Yeah, I&#8217;m a month late to this party; nevertheless, way to go team!
Article: Best Practices [...]]]></description>
			<content:encoded><![CDATA[<ul>
<li><a href="http://www.infoq.com/news/2008/06/agile-smells">Agile Smells: Don&#8217;t Let This Happen To You!</a>- I wonder how we went from &#8220;<a href="http://agilemanifesto.org/">Individuals and interactions over processes and tools</a>&#8221; to cataloging the manifold ways to practice Agile?</li>
<li><a href="http://martinfowler.com/bliki/AgileVersusLean.html">Agile Versus Lean</a>- Speaking of Agile, man, Martin&#8217;s got something to say.</li>
<li><a href="http://blog.davidchelimsky.net/articles/2008/05/27/rspec-1-1-4">RSpec-1.1.4</a>- Yeah, I&#8217;m a month late to this party; nevertheless, way to go team!</li>
<li><a href="http://www.infoq.com/news/2008/06/MDD-best-practices">Article: Best Practices for Model-Driven Software Development</a>- Apparently, MDD &#8220;no longer belongs to the fringes of the industry but is being applied in more and more software projects with great success.&#8221; That&#8217;s super news, baby.</li>
<li><a href="http://hamletdarcy.blogspot.com/2008/06/java-private-constructor-cleverness.html">Java Private Constructor Cleverness?</a>- My friend, Hamlet has a clever format of this blog&#8211; well done, friend!</li>
<li><a href="http://www.infoq.com/news/2008/06/hill-microtesting">My &#8220;Unit Test&#8221; Aint Your &#8220;Unit Test&#8221;</a>- Great read!</li>
</ul>
<p><center>Have a listen to <a href="http://www.javaworld.com/podcasts/jtech/">JavaWorld's Java Technology Insider</a></center></p>]]></content:encoded>
			<wfw:commentRss>http://thediscoblog.com/2008/06/29/the-weekly-bag-june-27/feed/</wfw:commentRss>
		</item>
		<item>
		<title>What happened to the applet?</title>
		<link>http://thediscoblog.com/2008/06/25/what-happened-to-the-applet/</link>
		<comments>http://thediscoblog.com/2008/06/25/what-happened-to-the-applet/#comments</comments>
		<pubDate>Wed, 25 Jun 2008 20:44:52 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
		
		<category><![CDATA[Software Development]]></category>

		<category><![CDATA[applet]]></category>

		<category><![CDATA[browser]]></category>

		<category><![CDATA[ie]]></category>

		<category><![CDATA[java]]></category>

		<category><![CDATA[Java 6]]></category>

		<category><![CDATA[java plug-in]]></category>

		<category><![CDATA[jvm]]></category>

		<category><![CDATA[netscape]]></category>

		<guid isPermaLink="false">http://thediscoblog.com/2008/06/25/what-happened-to-the-applet/</guid>
		<description><![CDATA[It&#8217;s clear that the initial bogue bet on Java&#8217;s ubiquity in the browser, in the form of applets, never paid off&#8211; history, however, has shown that Java found its foothold on the server-side. Nevertheless, because it&#8217;s everyone&#8217;s bag, applets are still around as I run into them from time to time. Interestingly, Sun has been [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s clear that the initial bogue bet on Java&#8217;s ubiquity in the browser, in the form of <a href="http://java.sun.com/applets/">applets</a>, never paid off&#8211; history, however, has shown that Java found its foothold on the server-side. Nevertheless, because it&#8217;s everyone&#8217;s bag, applets are still around as I run into them from time to time. Interestingly, Sun has been putting some effort into underlying engine that runs applets (the <a href="http://java.sun.com/products/plugin/">Java plug-in</a>), which begs the question&#8211; are applets still alive? What&#8217;s more, if they aren&#8217;t (or are on life support as some have suggested), what happened to them? </p>
<p><a href="http://www.nofluffjuststuff.com/blog_detail.jsp?rssItemId=123885">Richard Monson-Haefel recently pointed</a> me to an <a href="http://www.sparklingclient.com/welcome-to-1997/">hip conversation</a> with everyone&#8217;s favorite disco superstar, <a href="http://blogs.tedneward.com/">Ted Neward</a> (who you may have <a href="http://thediscoblog.com/2008/06/20/scala-pimpin-with-ted-neward/">heard blather</a> on and on (and on!) about <a href="http://www.scala-lang.org/">Scala</a> recently) who yammers (on and on and on&#8211; in reality, only 15 minutes but they do cut him off as he&#8217;s chattering on and on and on!) about why he thinks applets effectively kicked the bucket. </p>
<p>Just the same, Sun hasn&#8217;t thrown in the towel! In fact, not long ago, I had the privilege of <a href="http://www.javaworld.com/podcasts/jtech/2008/051308jtech.html">conducting a dialog with Ken Russell</a>, a Sun engineer focused on rebuilding the Java plug-in. According to Ken, applets aren&#8217;t dead yet and are a compelling platform for building <a href="http://en.wikipedia.org/wiki/Rich_Internet_application">Rich Internet Applications</a>. </p>
<p>Both conversations are appealing in that they shed some light on the lessons learned about Sun&#8217;s initial applet bet and where the future may be headed (regardless if applets will be with us or not). For me, I&#8217;m not sure applets are dead just yet&#8211; Ken gave me reason to believe otherwise. Have a listen to both <a href="http://www.sparklingclient.com/welcome-to-1997/">Ted Neward</a> and <a href="http://www.javaworld.com/podcasts/jtech/2008/051308jtech.html">Ken Russell</a> and decide for yourself, man!</p>
<p><center>Have a listen to <a href="http://www.javaworld.com/podcasts/jtech/">JavaWorld's Java Technology Insider</a></center></p>]]></content:encoded>
			<wfw:commentRss>http://thediscoblog.com/2008/06/25/what-happened-to-the-applet/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Scala pimpin’ with Ted Neward</title>
		<link>http://thediscoblog.com/2008/06/20/scala-pimpin-with-ted-neward/</link>
		<comments>http://thediscoblog.com/2008/06/20/scala-pimpin-with-ted-neward/#comments</comments>
		<pubDate>Fri, 20 Jun 2008 00:29:33 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
		
		<category><![CDATA[Software Development]]></category>

		<category><![CDATA[alternate language]]></category>

		<category><![CDATA[java]]></category>

		<category><![CDATA[javaworld]]></category>

		<category><![CDATA[jvm]]></category>

		<category><![CDATA[podcast]]></category>

		<category><![CDATA[scala]]></category>

		<category><![CDATA[ted neward]]></category>

		<guid isPermaLink="false">http://thediscoblog.com/2008/06/20/scala-pimpin-with-ted-neward/</guid>
		<description><![CDATA[I recently had the opportunity to discuss Scala with my friend Ted Neward for JavaWorld&#8217;s Java Technology Insider. Ted&#8217;s been talking about Scala for quite some time now and he&#8217;s the person who turned me on to this compelling functional language. 
In this conversation, Ted explains what functional programming is and why people should care&#8211; [...]]]></description>
			<content:encoded><![CDATA[<p>I recently had the <a href="http://www.javaworld.com/podcasts/jtech/2008/061008jtech.html">opportunity to discuss Scala</a> with my friend <a href="http://blogs.tedneward.com/">Ted Neward</a> for <a href="http://www.javaworld.com/podcasts/jtech/">JavaWorld&#8217;s Java Technology Insider</a>. Ted&#8217;s been talking about <a href="http://www.scala-lang.org/">Scala</a> for quite some time now and he&#8217;s the person who turned me on to this compelling functional language. </p>
<p>In this conversation, Ted explains what functional programming is and why people should care&#8211; he&#8217;s got some interesting thoughts regarding OO languages versus functional languages and more importantly, where each paradigm is a good fit. Scala&#8217;s definitely got some interesting features&#8211; if you are curious to hear them, <a href="http://www.javaworld.com/podcasts/jtech/2008/061008jtech.html">then have a listen</a>, man!     </p>
<p><center>Have a listen to <a href="http://www.javaworld.com/podcasts/jtech/">JavaWorld's Java Technology Insider</a></center></p>]]></content:encoded>
			<wfw:commentRss>http://thediscoblog.com/2008/06/20/scala-pimpin-with-ted-neward/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Rethinking the traditional DAO pattern</title>
		<link>http://thediscoblog.com/2008/06/17/rethinking-the-traditional-dao-pattern/</link>
		<comments>http://thediscoblog.com/2008/06/17/rethinking-the-traditional-dao-pattern/#comments</comments>
		<pubDate>Tue, 17 Jun 2008 15:39:12 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
		
		<category><![CDATA[Groovy]]></category>

		<category><![CDATA[Software Development]]></category>

		<category><![CDATA[dao]]></category>

		<category><![CDATA[hibernate]]></category>

		<category><![CDATA[java]]></category>

		<category><![CDATA[rails]]></category>

		<category><![CDATA[Ruby]]></category>

		<category><![CDATA[spring]]></category>

		<guid isPermaLink="false">http://thediscoblog.com/2008/06/17/rethinking-the-traditional-dao-pattern/</guid>
		<description><![CDATA[Back in the Age of Aquarius, a popular pattern emerged in the Java world dubbed &#8220;the data access object&#8220;, which essentially 
&#8220;separates a data resource&#8217;s [hip] client interface from its data access mechanisms&#8221;
meaning that clients to a particular domain object were shielded from the actual implementation of communicating with a particular database. Provided that clients [...]]]></description>
			<content:encoded><![CDATA[<p>Back in the Age of Aquarius, a popular pattern emerged in the Java world dubbed &#8220;<a href="http://java.sun.com/blueprints/patterns/DAO.html">the data access object</a>&#8220;, which essentially </p>
<blockquote><p>&#8220;separates a data resource&#8217;s [hip] client interface from its data access mechanisms&#8221;</p></blockquote>
<p>meaning that clients to a particular domain object were <a href="http://www.ibm.com/developerworks/java/library/j-cq05227/index.html">shielded from the actual implementation</a> of communicating with a particular database. Provided that clients worked with the interface type, implementations could be switched out (the database could migrate from <a href="http://www.ibm.com/db2">DB2</a> to <a href="http://en.wikipedia.org/wiki/Oracle_database">Oracle</a>, for instance or one DAO type could leverage <a href="http://www.hibernate.org/">Hibernate</a>, another <a href="http://ibatis.apache.org/">IBATIS</a>). This pattern had the bogue consequence, though, of logically dividing up a data layer into two types&#8211; DAOs and individual domain objects. </p>
<p><img style="PADDING-LEFT: 1.0em; PADDING-RIGHT: 0.5em; PADDING-TOP: 0.0em; FLOAT: RIGHT; PADDING-BOTTOM: 1.0em" src="http://thediscoblog.com/images/think-poobear.jpg" alt="think!" width="261" height="350"/></p>
<p>For instance, if you had a copasetic <code>Customer</code> domain object, you would also have a <code>CustomerDAO</code> interface type&#8211; your <code>Customer</code> object would essentially be a struct and the DAO type would handle CRUD (create, read, update, delete) operations. If you needed to find a particular customer, you&#8217;d ask the DAO type, for example, invoking the <code>findCustomer(long id)</code> method on the <code>CustomerDAO</code> object, which would return a fully populated <code>Customer</code> object. </p>
<p>This pattern seemed well and good at the time&#8211; I admit to using it extensively on a large project ages ago (<em>after</em> disco though); however, after a while it seemed to be a lot of work&#8211; if, because it was my bag, I wanted a <code>Customer</code> object, why did I have to ask the <code>CustomerDAO</code> for it? Why couldn&#8217;t I just ask the <code>Customer</code> itself? On top of that, if I wanted to create a new <code>Customer</code>, I had to first populate a <code>Customer</code> object <em>and then</em> pass it to the DAO type and invoke the <code>create</code> method. </p>
<p>I&#8217;m sure at the time a lot of smart people eschewed this uptight pattern and designed more natural domain objects; but for me, the tides changed when I read an interesting article about <a href="http://today.java.net/pub/a/today/2003/07/15/nakedaddress.html">Naked Objects</a> and then looked deeply at <a href="http://www.rubyonrails.org/">Rails</a> (and subsequently, <a href="http://grails.org/">Grails</a>) as they came to mature&#8211; these frameworks have <em>no notion of a DAO type</em>&#8211; your domain object (<code>Customer</code>) does everything for you&#8211; you can create new <code>Customer</code>s, save instances, find instance, etc. </p>
<p>I recently found myself building a domain model in Java without the luxury of Grails or GORM; however, I did employ <a href="http://www.hibernate.org/">Hibernate</a> and <a href="http://www.springframework.org/">Spring</a>. My initial effort starting going down the traditional DAO-domain object pairing but I quickly found myself disgusted&#8211; as a result I started playing around with combining the duo into something as hip (and polished) as what Grails/Rails would give you. My goal, of course, to provide a domain object that handled everything rather than having clients of the domain object have to work with two different trippin&#8217; objects. </p>
<p>In the end, I still have two different objects and an interface type to link them (via Spring); however, clients need only work with one hip type&#8211; the domain object. My domain objects support instance methods like <code>create</code>, <code>remove</code>, and <code>update</code> and class methods for find-like methods. </p>
<p>I nonetheless <em>still</em> have a DAO object&#8211; it&#8217;s essentially a Spring wired <code><a href="http://static.springframework.org/spring/docs/1.1.5/api/org/springframework/orm/hibernate/HibernateTemplate.html">HibernateTemplate</a></code>&#8211; this object supports the true <a href="http://en.wikipedia.org/wiki/Create,_read,_update_and_delete">CRUD</a> logic and is directly bound to Hibernate. For example, given a <code>Race</code> domain object, the DAO looks like this (minus some instance and class methods, but you&#8217;ll get the point):</p>
<pre><code>class RaceDAOImpl implements RaceDAO {
 private SessionFactory sessionFactory;

 public RaceDAOImpl() {
  super();
 }

 public void setSessionFactory(final SessionFactory sessionFactory) {
  this.sessionFactory = sessionFactory;
 }

 public void create(final Race race) {
  final HibernateTemplate tmplte =
     new HibernateTemplate(this.sessionFactory);
  tmplte.save(race);
}

//...

public Race findByName(final String name) {
 final HibernateTemplate hibernateTemplate = new HibernateTemplate(this.sessionFactory);
 return (Race) hibernateTemplate.execute(new HibernateCallback() {
   public Object doInHibernate(Session session) throws HibernateException {
    return session.createQuery(
    "from ... name = ?")
    .setString(0, name.trim())
    .uniqueResult();
   }
  });
 }

//...
}</code></pre>
<p>Note that this class isn&#8217;t <code>public</code>&#8211; it isn&#8217;t intended for outside consumption&#8211; the only client to this class (which will be shown shortly) is the domain object (which lives in the same package). </p>
<p>With this DAO object, I extracted an interface type&#8211; <code>RaceDAO</code>. This interface is the link between the domain object (<code>Race</code>) and the DAO (that is, the domain object will work with the interface type <em>not</em> the implementation or because it&#8217;s everyone&#8217;s bag to describe things in terms of coupling&#8211; the domain object is loosely coupled to the DAO implementation). </p>
<pre><code>interface RaceDAO {
 Collection&lt;Race&gt; findAll();
 Race findById(long id);
 Race findByName(String name);
 //...other finders...
 void create(Race race);
 void update(Race race);
 void remove(Race race);
}</code></pre>
<p>The domain object (which clients rely on) then relies on Spring (which basically acts as a <a href="http://en.wikipedia.org/wiki/Factory_method_pattern">factory</a>) and <a href="http://en.wikipedia.org/wiki/Object_composition">composition</a> to expose instance and class methods that indirectly (i.e. delegate via composition) leverage Hibernate to manipulate persistence. </p>
<p>For instance, the <code>Race</code> domain object looks like a normal, hip domain object&#8211; it contains various properties (and consequentially getters and setters) related to races (races have runners and results, etc) like so:</p>
<pre><code>public class Race {
 private long id;
 private String name;
 private Date date;
 private double distance;
 private Set&lt;Runner&gt; participants;
 private Set&lt;Result&gt; results;
 private String description;

 //.....more to come
}</code></pre>
<p>The next step could have unfolded in a number of different ways; however, I kept on truckin&#8217; and ended up with something that works&#8211; there are certainly pros and cons associated with my choices though (I will point those out shortly). </p>
<p>The DAO interface is linked via Spring in a <a href="http://www.jguru.com/faq/view.jsp?EID=249930">static block</a> in the domain object like so:</p>
<pre><code>private final static RaceDAO dao;

static {
 ApplicationContext context =
   new ClassPathXmlApplicationContext("spring-config.xml");
 dao = (RaceDAO) context.getBean("race_dao");
}</code></pre>
<p>Note that the type in the domain object is the interface (<code>RaceDAO</code>) not the implementation &#8212; Spring is returning <em>some</em> type that is bound to the <code>String</code> <code>race_dao</code>, which in my case is the Hibernate template type shown earlier. </p>
<p>Thus, because the <code>RaceDAO</code> is a static type, I can then expose a series of class methods on the domain object for finding particular race instances like so:</p>
<pre><code>public static Collection&lt;Race&gt; findAll(){
 return dao.findAll();
}

public static Race findById(long id) {
 return dao.findById(id);
}
//...others...</code></pre>
<p>Plus, instance methods on the domain object also delegate to the interface type:</p>
<pre><code>public void create() {
 dao.create(this);
}</code></pre>
<p>Now clients of a particular domain object don&#8217;t need to handle or work with various copasetic objects&#8211; they work exclusively with a domain object (much like you would in Grails, for instance). For example, the following <a href="http://easyb.org/">easyb</a> <a href="http://easyb.org/howtos.html">scenario</a> demonstrates the <a href="http://www.ibm.com/developerworks/java/library/j-cq09187/index.html">behavior</a> of a <code>Race</code> instance:</p>
<pre><code>scenario "Race should support finding races by name", {

 when "the find by name method is called", {
  race = Race.findByName("Leesburg Marathon")
 }

 then "the race should have 100 runners", {
  race.participants.size().shouldBe 100
 }
}</code></pre>
<p>As you see in the <a href="http://www.ibm.com/developerworks/edu/j-dw-java-jgroovy-i.html">Groovy code</a> above, the <code>findByName</code> method is a class method&#8211; it returns a <code>Race</code> instance, which clients can then work with. </p>
<p>Instance methods on the domain object work too, for example, creating a new race instance and persisting it is as easy as invoking the <code>create</code> method:</p>
<pre><code>scenario "the domain object should faciliate creating new instances", {
 given "a new race is created", {
  new Race("SML 10K", new Date(), 6.2,
     "race the hills of Smith Mountain lake").create()
 }
 then "the domain class should actually find it by name", {
  race = Race.findByName("SML 10K")
  race.description.shouldBe "race the hills of Smith Mountain lake"
 }
}</code></pre>
<p>As I mentioned earlier, there are some bogue disadvantages to this strategy&#8211; that is, because it&#8217;s its bag, the static block forces clients to load <em>some</em> instance of the DAO&#8211; without mocking that instance out, the domain object becomes somewhat heavy. For instance, loading the <code>Race</code> class with a Hibernate wired DAO means that a database must be up and running. Thus, without some mocking of the DAO interface type (and subsequent wiring of Spring) these domain objects can be hard to <a href="http://www.ibm.com/developerworks/java/library/j-cq10316/index.html">truly <em>unit</em> test</a>.</p>
<p>The advantage of this strategy is that clients don&#8217;t have to deal with a DAO type&#8211; they have a more neat-o-natural interface to work with&#8211; that being the business object itself (i.e. <code>Customer</code> or <code>Race</code> or <code>Runner</code>, etc). There are still two objects (and a binding type) to work with; however, the <em>DAO is hidden</em>. And in keeping with the spirit of the original DAO pattern, implementers are free to create varying instances of the DAO (should they actually need more than one&#8211; unit testing certainly comes to mind for a need to create at least one other instance). </p>
<p>The data models offered by frameworks like Grails and Rails are pretty hippingly sophisticated as well as elegant; what&#8217;s more they are easy to learn and natural to use. At this point, however, GORM (Grails magic data layer sauce) isn&#8217;t available as a stand alone project for Java developers; consequently, hip developers are left to rolling their own models (which leverage Hibernate, JDBC, IBATIS, etc), modeled after said project&#8217;s elegance. </p>
<p>The DAO pattern as it was authored (and implemented) back in the day is heavy, man; however, by applying a bit of Spring (or some other IOC framework) and leveraging a restrictive class modifier (to thus hide objects from clients), you can create more natural domain objects that still live up to the promised flexibility of the DAO pattern. Can you dig it, baby?</p>
<p><center>Have a listen to <a href="http://www.javaworld.com/podcasts/jtech/">JavaWorld's Java Technology Insider</a></center></p>]]></content:encoded>
			<wfw:commentRss>http://thediscoblog.com/2008/06/17/rethinking-the-traditional-dao-pattern/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
