<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	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"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Technical Notes &#187; software</title>
	<atom:link href="http://blog.anthonychaves.net/tag/software/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.anthonychaves.net</link>
	<description>Life is software and jujitsu</description>
	<lastBuildDate>Tue, 16 Feb 2010 22:15:16 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Spring Web MVC lists</title>
		<link>http://blog.anthonychaves.net/2008/02/13/spring-web-mvc-lists/</link>
		<comments>http://blog.anthonychaves.net/2008/02/13/spring-web-mvc-lists/#comments</comments>
		<pubDate>Wed, 13 Feb 2008 17:42:49 +0000</pubDate>
		<dc:creator>Anthony Chaves</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[spring]]></category>
		<category><![CDATA[coupling]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[frameworks]]></category>
		<category><![CDATA[lists]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[webapps]]></category>

		<guid isPermaLink="false">http://blog.anthonychaves.net/java/2008/02/13/spring-web-mvc-lists</guid>
		<description><![CDATA[I recently came across a blog post describing how *not* to use the Spring Web MVC form tag library.  Spring Web MVC is one of those things that has a high learning curve but it pays off big once you get the hang of it.  The form tag library is no exception.  [...]]]></description>
			<content:encoded><![CDATA[<p>I recently came across a blog post describing how *not* to use the Spring Web MVC form tag library.  Spring Web MVC is one of those things that has a high learning curve but it pays off big once you get the hang of it.  The form tag library is no exception.  The original blog poster seems to want to display a list of things the form user can manipulate and then send the changes back to the app server.  There are a few different ways we can do this with Spring Web MVC and some JSTL libraries so let&#8217;s take a look at the way I prefer to do it.<span id="more-47"></span></p>
<p>Spring Web MVC utilizes the ModelAndView class to encapsulate the M and V of MVC.  The model part is simply a map of objects associated with a request.  The key is the string name that you will use to access the object via the tag libraries.  Placing an object with a key of &#8220;userPrefs&#8221; into the map will make the UserPrefs object available to the HttpServletRequest and eventually part of the implicit request object that is part of JSPs.  In order to display any user data in a JSP it has to be part of the request object and it gets there by placing it in the Map used by ModelAndView.</p>
<p>In my experience with Spring Web MVC I&#8217;ve found that most form controller classes extend SimpleFormController.  SimpleFormController derives most of its lifecycle from AbstractFormController, which provides us with a few interesting methods.  There is one method in particular that is interesting.  The referenceData(HttpServletRequest request) method returns a Map and this method is called during the showForm(&#8230;) method.  showForm returns a ModelAndView object which will include whatever data is included in the Map returned by referenceData.  The default implementation of referenceData returns null, so we have to override it in our class that extends SimpleFormController.</p>
<p>Here is some example code from my controller class which extends SimpleFormController.  The point here is to provide a list of Bookmark objects to the form for a user to delete.</p>
<p><code><br />
<font color="#ffffff">  </font><font color="#646464">@Override</font><br />
<font color="#ffffff">  </font><font color="#7f0055"><strong>protected </strong></font><font color="#000000">Map referenceData</font><font color="#000000">(</font><font color="#000000">HttpServletRequest request</font><font color="#000000">) </font><font color="#7f0055"><strong>throws </strong></font><font color="#000000">Exception </font><font color="#000000">{</font><br />
<font color="#ffffff">    </font></code><code><font color="#000000"> </font></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code><font color="#000000">List userBookmarkList = </font></code><code><font color="#000000"> </font></code><code><font color="#000000"> </font></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code><font color="#000000">bookmarkService.getUserBookmarks</font><font color="#000000">(<br />
</font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code><font color="#000000">request.getUserPrincipal</font><font color="#000000">()</font><font color="#000000">.toString</font><font color="#000000">())</font><font color="#000000">;<br />
</font></code><code></code><code></code><code></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code><font color="#000000"><br />
</font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code><font color="#000000">Map model = </font><font color="#7f0055"><strong>new </strong></font><font color="#000000">HashMap</font><font color="#000000">()</font><font color="#000000">;</font><br />
<font color="#ffffff">    </font></code><code><font color="#000000"> </font></code><code><font color="#000000"> </font></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code><font color="#000000">model.put</font><font color="#000000">(</font><font color="#2a00ff">"userBookmarks"</font><font color="#000000">, userBookmarkList</font><font color="#000000">)</font><font color="#000000">;</font><br />
<font color="#ffffff">    </font></code><code><font color="#000000"> </font></code><code><font color="#000000"> </font></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code><font color="#7f0055"><strong>return </strong></font><font color="#000000">model;</font><br />
<font color="#ffffff">  </font><font color="#000000">}</font></code></p>
<p>This is pretty simple example.  It&#8217;s first getting the user from the request object.  This is an authenticated session where a user has provided a login name and password.  That name is retrieved from the request object and used to get a List of all of their bookmarks.  The List is then put into a HashMap with the key &#8220;userBookmarks&#8221;.</p>
<p>After referenceData returns the Map those entries are then passed on to the view by the showForm method.  We can use a couple JSTL tag libraries to iterate over the list and display each bookmark while building the form.  The following is an excerpt from the view (NOTE – This is pre-Spring 2.5):</p>
<table border="0">
<tr>
<td nowrap="true"><code> <font color="#000000">&lt;%</font><font color="#646464">@ </font><font color="#000000">taglib prefix=</font><font color="#2a00ff">"form" </font><font color="#000000">uri=</font><font color="#2a00ff">"http://www.springframework.org/tags/form" </font><font color="#000000">%&gt;</font><br />
<font color="#000000">&lt;%</font><font color="#646464">@ </font><font color="#000000">taglib prefix=</font><font color="#2a00ff">"c" </font><font color="#000000">uri=</font><font color="#2a00ff">"http://java.sun.com/jsp/jstl/core" </font><font color="#000000">%&gt;</font><br />
<font color="#000000">...</font><br />
<font color="#000000">&lt;form:form&gt;</font><br />
<font color="#ffffff">  </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code><font color="#000000">&lt;c:forEach items=</font><font color="#2a00ff">"${userBookmarks}" </font><font color="#000000">var=</font><font color="#2a00ff">"bookmark"</font><font color="#000000">&gt;</font><br />
<font color="#ffffff">    </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code><font color="#000000">&lt;form:checkbox path=</font><font color="#2a00ff">"bookmarkIds" </font><font color="#000000">value=</font><font color="#2a00ff">"${bookmark.id}"</font><font color="#000000">/&gt;&lt;c:out value=</font><font color="#2a00ff">"${bookmark.id}"</font><font color="#000000">/&gt; -- &lt;c:out value=</font><font color="#2a00ff">"${bookmark.title}" </font><font color="#000000">escapeXml=</font><font color="#2a00ff">"true"</font><font color="#000000">/&gt;&lt;br/&gt;</font><br />
<font color="#ffffff">  </font></code><code></code><code></code><code></code><code></code><code></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code><font color="#000000">&lt;/c:forEach&gt;</font><br />
<font color="#ffffff">  </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code><font color="#000000">&lt;input type=</font><font color="#2a00ff">"submit" </font><font color="#000000">value=</font><font color="#2a00ff">"Delete checked bookmarks"</font><font color="#000000">/&gt;</font><br />
<font color="#000000">&lt;/form:form&gt;</font></code></td>
</tr>
</table>
<p>This view uses two tag libraries, one from JSTL, the other being the Spring form tag library.  Within the form tags the JSTL forEach tag is used to iterate over the list of bookmarks.  The list is obtained via the ${userBookmarks} variable.  This calling convention takes advantage of the search order for finding request parameters used by JSTL.  Part of the search includes looking in the request object that is part of every JSP.  The items attribute is the object we want to iterate over, that being the object keyed by userBookmarks.</p>
<p>That object is the List of bookmarks we got from the business tier.  By iterating over the bookmarks we have access to each Bookmark object and each of it&#8217;s fields.  The checkbox tag is used to build up the HTML view of the each bookmark with a check box next to it for the user to click.  When the user is done selecting bookmarks to delete the onSubmit method is called back in the controller.</p>
<p>So how does Spring know which bookmarks have been checked in the form?  The form object bound to the form keeps track of the checked bookmarks.  This form object is very simple, it encapsulates an array of Strings and provides a getter and setter for the array.</p>
<p><code><br />
<font color="#7f0055"><strong>package </strong></font><font color="#000000">net.anthonychaves.bookmarks.dataobject;</font></code></p>
<p><font color="#7f0055"><strong>public class </strong></font><font color="#000000">DeleteBookmarksForm </font><font color="#000000">{</font><br />
<font color="#ffffff"> </font><br />
<font color="#ffffff">  </font><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><font color="#7f0055"><strong>private </strong></font><font color="#000000">String</font><font color="#000000">[] </font><font color="#000000">bookmarkIds;</font></p>
<p><font color="#ffffff">  </font><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code> <font color="#ffffff">  </font><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><font color="#7f0055"><strong>public </strong></font><font color="#7f0055"><strong>void </strong></font><font color="#000000">setBookmarkIds</font><font color="#000000">(</font><font color="#000000">String</font><font color="#000000">[] </font><font color="#000000">bookmarkIds</font><font color="#000000">) {</font><br />
<font color="#ffffff">  </font><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code> <font color="#ffffff">  </font><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code> <font color="#ffffff">    </font><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><font color="#7f0055"><strong>this</strong></font><font color="#000000">.bookmarkIds = bookmarkIds;</font><br />
<font color="#ffffff">  </font><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code> <font color="#ffffff">  </font><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><font color="#000000">}</font></p>
<p><font color="#ffffff">  </font><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><font color="#ffffff">  </font><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><font color="#7f0055"><strong>public </strong></font><font color="#000000">String</font><font color="#000000">[] </font><font color="#000000">getBookmarkIds</font><font color="#000000">() {</font><br />
<font color="#ffffff">  </font><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code> <font color="#ffffff">  </font><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code> <font color="#ffffff">    </font><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><font color="#7f0055"><strong>return </strong></font><font color="#000000">bookmarkIds;</font><br />
<font color="#ffffff">  </font><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code> <font color="#ffffff">  </font><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><code></code><code><font color="#000000"> </font></code><font color="#000000">}</font><br />
<font color="#000000">}</font></p>
<p>The “value” part of our checkbox contains the bookmark ID.  When the checkbox is checked and the form is submitted the Spring dispatcher servlet collects all of the checked values of the same path into an array and puts them into the DeleteBookmarksForm object.  The form object is then passed to the DeleteBookmarksController via the onSubmit method.  We don&#8217;t have to implement the entire onSubmit method, though.  The default implementation calls doSubmitAction which takes only our command object, in this case DeleteBookmarksForm, as an argument.  Once we have a list of bookmark IDs to delete we can call the business tier to remove them from the database (after appropriate error checking, of course).</p>
<p>Spring 2.5 introduces the form:checkboxes tag which eliminates the need to use the JSTL forEach tag to iterate over the list of objects.  The checkboxes tag takes care of that for you.</p>
<p>There is more to working with lists in Spring Web MVC than the material presented here.  I&#8217;ve included a few references below in case you&#8217;re interested in finding out more.  Thanks for reading and as usual let me know if you have any questions or comments!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.anthonychaves.net/2008/02/13/spring-web-mvc-lists/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Response to Web Application: To Couple or Not to Couple?</title>
		<link>http://blog.anthonychaves.net/2008/02/08/response-to-web-application-to-couple-or-not-to-couple/</link>
		<comments>http://blog.anthonychaves.net/2008/02/08/response-to-web-application-to-couple-or-not-to-couple/#comments</comments>
		<pubDate>Fri, 08 Feb 2008 20:33:24 +0000</pubDate>
		<dc:creator>Anthony Chaves</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[coupling]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[frameworks]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[webapps]]></category>

		<guid isPermaLink="false">http://blog.anthonychaves.net/personal/2008/02/08/response-to-web-application-to-couple-or-not-to-couple</guid>
		<description><![CDATA[I just read this thread on The Server Side and it makes me nervous that people still ask this kind of question.  The thread starts off by asking &#8220;An usually annoying question when designing an action-based web application is: &#8220;Should I place everything in my action or should I separate the web logic from [...]]]></description>
			<content:encoded><![CDATA[<p>I just read <a href="http://www.theserverside.com/news/thread.tss?thread_id=48304" target="_blank">this thread on The Server Side</a> and it makes me nervous that people still ask this kind of question.  The thread starts off by asking &#8220;An usually annoying question when designing an action-based web application is: &#8220;Should I place everything in my action or should I separate the web logic from the business logic?&#8221; and the alarm bells in my head are going off already.<span id="more-45"></span></p>
<p>Business logic <strong>always</strong> belongs in its own layer.  Why?  Business logic is <strong>the thing</strong> that makes your application what it is.  It doesn&#8217;t matter how it&#8217;s dressed up &#8211; web app, desktop app, web service &#8211; the business logic accomplishes the task the user wants to perform.  Business logic <strong>is</strong> your application.  Because of its importance business logic should be placed in a sacred place where it will not be disturbed by presentation logic or infrastructure underpinnings &#8211; the business tier.  Separating the business concerns from all other concerns buys a lot of benefits for the development team.</p>
<p>What if aggregate data must be displayed in multiple locations?  For example, shopping cart data could be displayed on a checkout screen and also as a side bar while the user is still shopping.  In an action-based framework this code would be duplicated in two different actions.  It would be present in the action that generated checkout screen and again in the action that assembled the shopping view screen.  Rather than duplicate the code why not make a method call into the business layer that did the same thing?  The end result is the same except it separates the concerns of web and business logic.</p>
<p>Refactoring this code into a business tier method helps make our application more loosely coupled.  Loose coupling is important for business logic because it allows for easier reuse, testability and maintanence.  If the business logic is located in the action then creating a web service around it is going to be more difficult.  The business logic will have to be decouple from the web action and pulled into a layer where both the web action and web service can use it.  A good example of this would be a web page that displays new items available to a customer.  A web page is ok but the customer would have to keep checking back for updates.  An easier way to publish this information would be to make it available as an RSS feed the customer can subscribe to.  Duplicating the logic to get the new items isn&#8217;t particularly difficult, but why make maintenance more difficult than it has to be?  The application should be refactored to have a business layer that is responsible for getting the data which can be called by two different locations in the presentation layer (the web tier and the RSS feed creator).  Testing the business logic (you&#8217;re testing, right?) and bug fixing only have to be done in one location thanks to this refactoring too.</p>
<p>Another quote from the thread is, &#8220;The other side of the story is that to have two separate classes, one dealing with the http/web layer (ex: UserAction) and one dealing with the business logic layer (ex: UserService) is bureaucratic.&#8221;  This statement shows a lack of understanding of functional decomposition.  Each module should be responsible for one and only one thing.  If the web layer is for dealing with actions then actions should only be dealt with in the web layer.  If the web layer is for dealing with actions then business logic should <strong>not</strong> be dealt with at the web layer.  Business logic belongs where it can remain undisturbed by other concerns.  Tight coupling of these concerns makes testing more difficult because it requires testing everything it once rather than testing in isolation.  Because your application is only as good as the business logic the business layer should have a test suite that can be run without depending on action or presentation logic.</p>
<p>There are plenty of other reasons you should keep business and web logic separate.  This is in no way an exhaustive list, but it&#8217;s certainly something to think about.  If you&#8217;re building any professional application then business logic should always be in its own layer.  Not only will your boss/team/successor thank you for it, it&#8217;s good software development and you&#8217;ll thank yourself for it too.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.anthonychaves.net/2008/02/08/response-to-web-application-to-couple-or-not-to-couple/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Too Many Bugs &#8211; Part 2</title>
		<link>http://blog.anthonychaves.net/2008/01/24/too-many-bugs-part-2/</link>
		<comments>http://blog.anthonychaves.net/2008/01/24/too-many-bugs-part-2/#comments</comments>
		<pubDate>Thu, 24 Jan 2008 14:02:11 +0000</pubDate>
		<dc:creator>Anthony Chaves</dc:creator>
				<category><![CDATA[career]]></category>
		<category><![CDATA[work]]></category>
		<category><![CDATA[developer]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[qe]]></category>
		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://blog.anthonychaves.net/work/2008/01/24/too-many-bugs-part-2</guid>
		<description><![CDATA[This is part two of a paper I&#8217;ve written on making bug triage meetings more manageable and becoming a leader in a cross functional team.   You might want to check out part one before reading on.
The reason we have bug triage sessions in the first place is no one has bothered to talk [...]]]></description>
			<content:encoded><![CDATA[<p>This is part two of a paper I&#8217;ve written on making bug triage meetings more manageable and becoming a leader in a cross functional team.   You might want to <a href="http://blog.anthonychaves.net/work/2008/01/23/too-many-bugs">check out part one</a> before reading on.</p>
<p>The reason we have bug triage sessions in the first place is no one has bothered to talk about these bugs before dealing with the entire list became a high priority.  Everyone pays the high price of brutally long bug triage sessions because the low price of communicating on a consistent basis hasn&#8217;t been a priority right along.  In order to make triage sessions more valuable you have to make it your top priority to get to the meeting with <span id="more-40"></span> the fewest, highest quality bugs possible.  This doesn&#8217;t mean close all the small bugs before the meeting and hope no one notices or to assign them all to someone else.  It means effectively dealing with bugs while they&#8217;re incoming.  In order to do this right you&#8217;ll need to build a relationship with someone in QE.  Yes I know QE and developers are supposed to be like cats and dogs or water and oil.  In this case the relationship needs to be more like peanut butter and jelly.  Or peanut butter and chocolate.  Or peanut butter and whatever else you like since it goes well with just about everything.  You need to be like peanut butter.</p>
<p>Part of the beauty in doing this is that your chosen QE co-conspirator doesn&#8217;t even need to know they are a co-conspirator, though eventually they will realize their job has become much, much easier to do effectively.  One of your goals is to stop bugs from coming in by stopping them at the source, which means you need to get QE to reduce the number of bugs filed on your software.  There are a few ways to go about this and not all of them are good.  Some can even get you in trouble with HR.  If you want to reduce the number of incoming bugs you have to first find out what software QE is testing.  If you&#8217;re late to the game then you should start just after the code is released to QE, though starting any time is better than not starting at all.  In order to find out what&#8217;s going on in QE you have to, gasp, talk to someone in QE!  It&#8217;s true, they know how to communicate using spoken language, not just Bugzilla.  You can ask your QE person, &#8220;hey, how&#8217;s it going?&#8221; and they will tell you everything is going fine, testing is going fine, day to day tasks are going fine and then move on to filing more bug reports on your software.  Or you could ask, &#8220;hey &lt;QE person&gt;, have you had a chance to look at &lt;my software module in question&gt;?  If you have a chance I&#8217;d like to go over the work I&#8217;ve done with you in order to answer any questions you have on it.&#8221;  The second way always gets better results than the first and it&#8217;s surprising how very few software engineers are capable of doing this.  Asking the question in this way sets up a discussion by showing the QE person that you are open to questions and feedback.  It gives them assurance that their input is valuable because it is!  If they&#8217;re testing software and they don&#8217;t understand what it&#8217;s doing they&#8217;re not going to be responsive to the first question of &#8220;how&#8217;s it going&#8221; unless they have an ax to grind.  You&#8217;re not going to get anything useful out of that question because it gives no indication that questions or constructive criticism are welcome even if they are.  Do you really want to reduce your bug count?  Spend a half hour going over your work with them.  Answer every question they have and go over the implementation.  Draw diagrams, play charades, do everything you can to help them understand what you&#8217;ve unleashed.  All of those bugs that are really just setup and configuration questions will be vaporized if you do this.  Ditto for the &#8220;what does this software actually do&#8221; bugs that would have been filed.  You have just taken the first step to reducing the number of low quality bugs you have to deal with.</p>
<p>I remember an iteration where I had a fairly high profile deliverable.  I felt like I nailed the business requirement.  All the features were complete and robust.  The implementation was impeccable.  This deliverable was a feature that had been lacking for a long time and I had a feeling that I&#8217;d be heralded as a hero for delivering just what everyone was begging to have for such a long time.  I didn&#8217;t think anyone would be able to open even a single bug on my project.  How could they?  They would be too busy drooling over the amazing quality of what I just delivered.</p>
<p>Imagine my surprise when QE started opening up bug after bug after bug on what most people in development considered perfection.  I watched in panic all day long as I saw my bug list get longer and longer.  And almost everyone one of the bugs was shallow.  The QE person didn&#8217;t dig very far at all for a reason to file a bug.  If they didn&#8217;t understand what was supposed to happen they filed a bug.  If they thought the software was supposed to do something and it didn&#8217;t then there was a bug.  If they thought the software should have additional features they considered nice to have there was a bug.  Needless to say that iteration&#8217;s acceptance process was very stressful for me.  That&#8217;s when I realized the value in stopping bugs at the source.</p>
<p>Almost all of the bugs were in the class that would have gone away if I just communicated what was going to happen before the release.  Fast forward to the next iteration.  Once again I was working on high profile features that should be a slam dunk as far as quality goes.  The week before it was released to QE I asked around to find out who would be testing my features.  I scheduled a meeting with them to talk about my deliverable and give them a demo.  In my meeting invite I sent a brief description of what I wanted to talk about and encouraged them to show up with questions or relevant topics to discuss.  During the meeting we went over just about every facet of every feature in great detail.  We went over how to configure the operating system environment, the topology and the application.  I wanted to do everything in my power to make sure they had all the information they needed to meaningfully test my software.  Meaningless bugs are a waste of everyone&#8217;s time.  Once the software was officially released to QE I didn&#8217;t see a single bug filed on the first day of testing.  One was filed on the second day of testing.  None on the third.  I had only a handful of bugs for that iteration&#8217;s release because I made sure to discuss my concerns with QE before they started testing it.  I also had more time to concentrate on the meaningful bugs.</p>
<p>On Monday we&#8217;ll talk about what to do with the bugs that are already in your queue.  If you found this worthwhile please forward it on to anyone else you think would find it helpful.</p>
<p><script src="http://digg.com/tools/diggthis.js" type="text/javascript"></script></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.anthonychaves.net/2008/01/24/too-many-bugs-part-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
