<?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>Basil Vandegriend: Professional Software Development &#187; requirements</title>
	<atom:link href="http://www.basilv.com/psd/blog/tag/requirements/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.basilv.com/psd</link>
	<description></description>
	<lastBuildDate>Wed, 25 Jan 2012 13:23:47 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Alternatives to Formal Traceability</title>
		<link>http://www.basilv.com/psd/blog/2011/alternatives-to-formal-traceability</link>
		<comments>http://www.basilv.com/psd/blog/2011/alternatives-to-formal-traceability#comments</comments>
		<pubDate>Mon, 17 Oct 2011 13:23:05 +0000</pubDate>
		<dc:creator>Basil Vandegriend</dc:creator>
				<category><![CDATA[quality]]></category>
		<category><![CDATA[agile]]></category>
		<category><![CDATA[project management]]></category>
		<category><![CDATA[requirements]]></category>
		<category><![CDATA[software development]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[traceability]]></category>

		<guid isPermaLink="false">http://www.basilv.com/psd/?p=713</guid>
		<description><![CDATA[In my prior post The Trouble with Traceability I discussed the problems with doing requirements traceability, especially formal traceability using approaches like a requirements traceability matrix (RTM). Despite the flaws with traceability the underlying objective is sound: ensure that everything the customer or user requires is correctly delivered. So how can we achieve this objective? [...]]]></description>
			<content:encoded><![CDATA[<p>In my prior post <a href="http://www.basilv.com/psd/blog/2011/the-trouble-with-traceability">The Trouble with Traceability</a> I discussed the problems with doing requirements traceability, especially formal traceability using approaches like a requirements traceability matrix (RTM). Despite the flaws with traceability the underlying objective is sound: ensure that everything the customer or user requires is correctly delivered. So how can we achieve this objective?</p>
<p>There are a number of pragmatic practices that address this objective while avoiding the pitfalls afflicting formal traceability. I will start with a simpler form of traceability and then move on to practices seemingly unrelated to traceability.</p>
<h3>Specification Highlighting to Track Test Coverage</h3>
<p>A tester given a written specification to verify the software against must have some way of keeping track of their progress. One simple method is to highlight each statement in the specification as they test it. This is essentially tracking test coverage of the specification. I credit <a href="http://www.satisfice.com/blog/">James Bach</a> for this idea.</p>
<h3>Testing Dashboard</h3>
<p>A testing dashboard is great at illustrating overall testing progress and can be used as part of the summary in the final test report. To produce the dashboard first divided the system under test into test areas that usually correspond to features, components, or significant non-functional requirements. Then create a grid with the test areas as rows, and the columns report testing progress for each area. Key information to report per area is an assessment of quality (is this area ready to ship?), and the thoroughness of testing (test coverage and test effort). For an example and fuller explanation see <a href="http://www.satisfice.com/presentations/dashboard.pdf">James Bach's presentation on testing dashboards</a>.</p>
<p>The testing dashboard is closest in form to a requirements traceability matrix - there's still a grid and something like requirements are listed down the grid. The big difference is that the dashboard shows a summary of testing for each area rather than listing individual tests and showing how they map.</p>
<h3>Agile User Stories with Acceptance Tests</h3>
<p>A common approach used by Agile methods is to divide requirements into fine-grained increments of business value called user stories and then define with examples or automated tests the criteria by which to accept that the story was correctly implemented. This takes a two-pronged approach to address traceability's objective. First, using fine-grained increments of functionality that are quickly developed minimizes the amount of work-in-progress that needs to be tracked and thus reduces the chance of mistakes. Second, the process produces tests for each user story early, sometimes before coding starts, so missing tests for a requirement is much less likely. Agile basically sufficiently changes how development is done to negate virtually all the sources of problems that would otherwise justify a requirements traceability matrix.</p>
<h3>Task Tracking via Task Board</h3>
<p>Popularized by <a href="http://en.wikipedia.org/wiki/Kanban_(development)">Kanban</a> but also used by many Agile teams, a task board is a practice for tracking the status of tasks. The board has multiple columns representing different status: the minimum set is usually "Not Started", "In Progress", and "Done". Tasks are placed on the board according to their status, and the team meets daily to discuss the tasks and update appropriately. I vastly prefer a physical task board on a wall, but for teams not co-located many online versions exist. Tasks are often quite fine-grained - one user story is often decomposed into multiple tasks. </p>
<p>Many teams include a status of "Testing" on the board, or use a symbol on the card to signify the completion of testing. Other quality control procedures such as code reviews can also be tracked. See the image below for an example of a task board with such states. </p>
<p><a href="http://www.basilv.com/psd/wp-content/uploads/2011/10/TaskBoard.jpg"><img src="http://www.basilv.com/psd/wp-content/uploads/2011/10/TaskBoard.jpg" alt="Example Task Board" title="Example Task Board" width="500" height="307" class="alignnone size-full wp-image-714" /></a></p>
<p>The combination of fine-grained tasks, daily updates, and tracking quality ensures that each requirement that is tackled by the team is properly developed. This achieves traceability's objective.</p>
<h3>Conclusion</h3>
<p>Despite formal traceability being too effort-intensive for too little value the underlying objective should not be ignored. I have described a variety of alternative practices that help ensure that requirements are properly developed and tested with a more modest level of effort.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.basilv.com/psd/blog/2011/alternatives-to-formal-traceability/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Trouble with Traceability</title>
		<link>http://www.basilv.com/psd/blog/2011/the-trouble-with-traceability</link>
		<comments>http://www.basilv.com/psd/blog/2011/the-trouble-with-traceability#comments</comments>
		<pubDate>Mon, 10 Oct 2011 12:23:47 +0000</pubDate>
		<dc:creator>Basil Vandegriend</dc:creator>
				<category><![CDATA[quality]]></category>
		<category><![CDATA[requirements]]></category>
		<category><![CDATA[software development]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[traceability]]></category>

		<guid isPermaLink="false">http://www.basilv.com/psd/?p=710</guid>
		<description><![CDATA[In software development traceability is the linkage of requirements to the software and/or development artifacts like design or test cases. The underlying objective is to ensure that everything the customer or user requires has been correctly delivered. I have no quibbles with this goal, but in practice the applications of traceability I have seen leave [...]]]></description>
			<content:encoded><![CDATA[<p>In software development traceability is the linkage of requirements to the software and/or development artifacts like design or test cases. The underlying objective is to ensure that everything the customer or user requires has been correctly delivered. I have no quibbles with this goal, but in practice the applications of traceability I have seen leave me feeling troubled. I often wonder whether there are sufficient benefits achieved to justify the efforts spent on traceability, especially formal traceability with defined artifacts.</p>
<h3>Formal Traceability</h3>
<p>The most frequent incarnation of formal traceability I see is the requirements traceability matrix (RTM). This is a two-dimensional table, often represented by a spreadsheet, in which the one dimension lists requirements and the other dimension lists the artifact being traced to - business objectives, test cases, or design documentation. Cells within the table are filled in with a mark when the corresponding artifact and requirement are related.</p>
<p>The example traceability matrix below lists requirements across as columns and test cases down as rows. Notice that requirement 2.2 has no corresponding related test case, which is considered a traceability gap that indicates that this requirement has not been tested.</p>
<table class="fancy" cellspacing="0">
<tr>
<th></th>
<th>Req 1.1</th>
<th>Req 1.2</th>
<th>Req 1.3</th>
<th>Req 2.1</th>
<th>Req 2.2</th>
</tr>
<tr>
<th>TC 1</th>
<td>X</td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<th>TC 2</th>
<td>X</td>
<td>X</td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<th>TC 3</th>
<td></td>
<td>X</td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<th>TC 4</th>
<td></td>
<td></td>
<td>X</td>
<td></td>
<td></td>
</tr>
<tr>
<th>TC 5</th>
<td></td>
<td></td>
<td>X</td>
<td></td>
<td></td>
</tr>
<tr>
<th>TC 6</th>
<td></td>
<td></td>
<td>X</td>
<td></td>
<td></td>
</tr>
<tr>
<th>TC 7</th>
<td>X</td>
<td>X</td>
<td>X</td>
<td>X</td>
<td></td>
</tr>
<tr>
<th>TC 8</th>
<td></td>
<td></td>
<td>X</td>
<td>X</td>
<td></td>
</tr>
</table>
<h3>Traceability Troubles</h3>
<p>Below are listed the aspects of traceability that trouble me.</p>
<ul>
<li>I have successfully developed and enhanced high quality software applications that have pleased clients and been used in production without needing formal traceability. So does it really provide value? Traceability seems like it addresses the problem of having unimplemented or untested requirements. This has rarely been a problem on the development projects I have been on. We are much more likely to struggle with ambiguous or unclear requirements, missed or new requirements, and incorrect logic in obscure special conditions.
</li>
<li>The tracing of requirements to test cases assumes they can be identified and listed which in turn limits the testing approaches that can be used. The <a href="http://www.context-driven-testing.com/">context-driven school of testing</a> would challenge these limitations. Exploratory testing in particular does not fit the confines imposed by a formal requirements traceability matrix.</li>
<li>While the value of producing the initial RTM is unclear to me at best, I am even more dubious about the value of maintaining a RTM over time. The typical claims is that for for future requirement changes (e.g. enhancements) the RTM can be used to do impact analysis and determine what tests need to be executed and/or changed. Regarding impact analysis, the RTM might get you started, but the analysis must always consider code-level dependencies not reflected in the RTM (through, for example, reuse of common functionality), and must consider other requirements and functionality that are not directly related (and thus not reflected in the RTM) but make assumptions that are no longer true under the proposed change. The idea that the RTM can be used to determine what tests to executes makes several poor assumptions. First, that the tests are manual and not automated. If you have an automated test suite, you can just rerun the whole suite to identify failing tests - you never need to worry about running a subset. Second, that reusing manual tests is a good idea. If a test is worth re-executing often, it is frequently worth automating. For those tests that are manual, much of the benefit of having human testers is lost if they simply re-run the same scripts over and over, since there is a low probability of such re-executions failing and testers are less likely to find defects when they do occur. A better approach is to let the tester come up with their own variations each time to try to creatively break the system.</li>
<li>Tracing requirements to design is conceptually flawed. It at best very indirectly addresses the objective of traceability -  ensuring the customer gets the functionality they require. Doing this mapping is in reality quite hard because the mapping from design to code (and from requirements to design) is not a strict one-to-one and is often a complex many-to-many, especially for holistic non-functional requirements like performance or security. Furthermore, the idea of tracing to design assumes that there are fine-grained pieces of design that can be identified and referenced. This presumes a certain approach to design and its documentation that is at odds with many modern methods of software development.</li>
<li>For small-scale software applications, the system is simple enough that producing a RTM is a reasonably small effort. The number of requirements and test cases is relatively small. But the chance of errors occurring that would be caught be traceability is likewise low because the system's complexity is low. For very large systems with hundreds or thousands of requirements and tests, it is far more conceivable that requirements may be forgotten to be implemented or tested. But while the benefits of formal traceability are higher, the efforts are much, much higher. For a RTM, the number of cells to complete essentially scales non-linearly with the number of requirements in the system.</li>
<li>I do not understand the obsession with testing in the context of traceability and especially RTMs. Reviews or inspections are much more effective at finding defects than testing. So why do I never hear of formal traceability from requirements to reviews?
</li>
</ul>
<h3>Conclusion</h3>
<p>Software engineering researchers and industry leaders have reached the same conclusions about traceability. Andrew Kannenberg and Dr. Hossein Saiedian in <a href="http://www.crosstalkonline.org/storage/issue-archives/2009/200907/200907-Kannenberg.pdf">Why Software Requirements Traceability Remains a Challenge</a> (PDF) are clearly big proponents of requirements traceability, but look at their conclusions:</p>
<ul>
<li>"Unfortunately, manual traceability methods are not suitable for the needs of the software engineering industry."</li>
<li>"Currently existing COTS traceability tools are not adequate for the needs of the software engineering industry."</li>
</ul>
<p>Robert Glass in his book <a href="http://www.amazon.ca/gp/product/0321117425?ie=UTF8&#038;tag=basilvandegri-20&#038;linkCode=as2&#038;camp=15121&#038;creative=330641&#038;creativeASIN=0321117425">Facts and Fallacies of Software Engineering</a><img src="http://www.assoc-amazon.ca/e/ir?t=basilvandegri-20&#038;l=as2&#038;o=15&#038;a=0321117425" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /> points out the underlying cause of troubles implementing traceability: "when a requirement commonly links to 50 or more design requirements and each of those links to some very much larger number of coding elements and coding elements may be reused to satisfy more than one requirement, we get a burgeoning complexity problem that has resisted manual solution and even tended to thwart most automated solutions" (page 78)</p>
<p>I hope the above discussion has convinced you to tread cautiously when it comes to traceability. In a future article I will look at alternatives to formal traceability that achieve the same underlying objectives.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.basilv.com/psd/blog/2011/the-trouble-with-traceability/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Example-Based Requirements</title>
		<link>http://www.basilv.com/psd/blog/2010/example-based-requirements</link>
		<comments>http://www.basilv.com/psd/blog/2010/example-based-requirements#comments</comments>
		<pubDate>Thu, 07 Oct 2010 13:55:56 +0000</pubDate>
		<dc:creator>Basil Vandegriend</dc:creator>
				<category><![CDATA[productivity]]></category>
		<category><![CDATA[requirements]]></category>
		<category><![CDATA[software development]]></category>

		<guid isPermaLink="false">http://www.basilv.com/psd/?p=559</guid>
		<description><![CDATA[Most of the requirements I deal with are in the form of documented use cases and lists of business rules. These requirements are almost always written in a generalized form. For example a business rule might be written as "Produce a warning if the last transaction in the account is more than a year ago." [...]]]></description>
			<content:encoded><![CDATA[<p>Most of the requirements I deal with are in the form of documented use cases and lists of business rules. These requirements are almost always written in a generalized form. For example a business rule might be written as "Produce a warning if the last transaction in the account is more than a year ago." </p>
<p>A common problem I encounter from the use of these generalized requirement statements is ambiguity. This has multiple negative impacts. The user representatives providing requirements and the business analysts documenting them can both review the same written requirement and agree that it is correct, based on their discussions, while actually holding differing interpretations. But it gets worse. The developers implementing the requirement who typically do not have the benefit of the interactions and discussions with user representatives can arrive at an even larger range of interpretations. And if you have a separate tester, who knows what they might come up with. </p>
<p>To illustrate the problem, here are some questions about the example business rule provided above demonstrating the amount of ambiguity in just one single sentence:</p>
<ul>
<li>By the phrase "last transaction" do you mean the last transaction chronologically? If so, which transaction date should be used to determine this – the date of posting or the date of acceptance?</li>
<li>The phrase "more than a year ago" could be based on calendar year or could be based on the corporate fiscal year. Which is it?</li>
<li>Assuming the phrase "more than a year ago" is calculated based on calendar year, how exactly should the calculation work? It could be based solely on the year – e.g. warn if the year of the transaction is two or more years less than the current year. It could be based on date – e.g. warn if the transaction date happens before the same month and day as today last year. Or it could be based on a number of days – e.g. warn if the transaction date is more than 365 days before the current date. (Note that the last two scenarios will produce different results in a leap year.)</li>
</ul>
<p>The solution to the problem of ambiguity is to use examples. And not just a few examples here and there to support particularly complex requirements – requirements should be largely based on examples, with the generalized description simply providing the higher level intent or summary. Examples should ideally be created by user representatives, or at the very least carefully reviewed by them. The benefit of examples is not just to bring greater clarity to the development team but also to ensure the users are clear on what the system will do. This helps avoid unpleasant surprises when the users first see and play with the working system. </p>
<p>The Agile community has figured this out a long time ago, thus prompting the move to very short user stories supplemented with acceptance tests instead of formally elaborated use cases. The acceptance tests function as the specific concrete examples. The user story only provides a high level summary in part because of the expectation that further face-to-face conversation will take place regarding the requirement. </p>
<p>If your environment requires more formalized requirements documentation then keep using use cases and lists of business rules, but keep the written text focused on the higher-level intent while examples provide the specifics. To provide an example :) of this, here is the example business rule rewritten to fit this new approach:</p>
<p>As the account manager I want to receive a warning when the account has no recent activity.<br />
Examples:</p>
<ul>
<li>Most recent transaction in account based on posting date of May 1, 2009 with current date May 1, 2010 produces the warning "No recent activity in account".</li>
<li>Most recent transaction in account based on posting date of May 2, 2009 with current date May 1, 2010 does not produce a warning.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.basilv.com/psd/blog/2010/example-based-requirements/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Defect Prevention Practices</title>
		<link>http://www.basilv.com/psd/blog/2010/defect-prevention-practices</link>
		<comments>http://www.basilv.com/psd/blog/2010/defect-prevention-practices#comments</comments>
		<pubDate>Wed, 08 Sep 2010 13:44:40 +0000</pubDate>
		<dc:creator>Basil Vandegriend</dc:creator>
				<category><![CDATA[productivity]]></category>
		<category><![CDATA[coding standards]]></category>
		<category><![CDATA[defects]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[lean]]></category>
		<category><![CDATA[quality]]></category>
		<category><![CDATA[requirements]]></category>
		<category><![CDATA[software development]]></category>

		<guid isPermaLink="false">http://www.basilv.com/psd/?p=549</guid>
		<description><![CDATA[I have written numerous times about defect elimination practices such as code reviews, unit testing, and static code analysis tools. From the perspective of lean thinking, however, eliminating defects, no matter how soon after they are introduced, results in waste due to rework to fix the defects. The ideal as far as lean is concerned [...]]]></description>
			<content:encoded><![CDATA[<p>I have written numerous times about defect <em>elimination</em> practices such as <a href="http://www.basilv.com/psd/blog/2007/strategies-for-effective-code-reviews">code reviews</a>, <a href="http://www.basilv.com/psd/blog/category/unit-testing/">unit testing</a>, and <a href="http://www.basilv.com/psd/blog/2009/why-you-should-be-using-findbugs">static code analysis tools</a>. From the perspective of lean thinking, however, eliminating defects, no matter how soon after they are introduced, results in waste due to rework to fix the defects. The ideal as far as lean is concerned is to prevent defects from occurring in the first place. </p>
<p>You must be careful, however, that the cost of these defect prevention practices does not become excessive. That would introduce a different type of waste – non-value adding process. The waterfall method of software development is an example of this. One of the principles behind waterfall is that careful requirements analysis and design will minimize downstream defects during coding and testing. Put another way, it is a good idea to understand what you need to build before you start building it. The problems with waterfall arise from going to extremes in applying this principle. Requirements analysis is done up front for the entire project as a big batch based on the theory that it minimizes rework due to future change, but in reality the constant pace of requirement changes plus the learning that occurs throughout the project will result in increasing amounts of change the longer the time spent doing requirements. In contrast, Scrum and Kanban apply this principle using a balanced approach – project level requirements are done at a high level, and the more detailed analysis is done on individual user stories just prior to implementing them. (See for example the article <a href="http://agile2009.agilealliance.org/files/WHI0001%20ScrumCMMI%20from%20Good%20to%20Great%201_11.PDF">Scrum and CMMI – Going from Good to Great: are you ready-ready to be done-done?</a>.)</p>
<p>In order to effectively adopt a defect prevention practice two pieces of information are needed:</p>
<ol>
<li>Specific, actionable steps to apply the practice.</li>
<li>The expected benefit. What categories of defects does the practice intend to prevent? This helps determine when to apply the practice and helps to evaluate it after adoption to assess its effectiveness.</li>
</ol>
<p>If we consider the idea of careful requirements analysis and design mentioned above as a prevention practice, the benefits are fairly clear - prevent requirement and design based errors - but specific actionable steps are missing so it does not qualify. (In fact, this is one of the contributing factors why waterfall projects can end up in the <a href="http://en.wikipedia.org/wiki/Analysis_paralysis">analysis paralysis</a> anti-pattern.)</p>
<p>Now that the groundwork has been laid I can present some specific defect prevention practices. This is not a comprehensive list – many other practices are possible. The practices I have chosen to discuss are ones that I have used and am confident that they work. </p>
<h3>Use Understood Methods Rule</h3>
<p>The basic formulation of the rule is quite simple: when coding a method only invoke other methods whose behavior you clearly understand and are confident will work the way you want. I have written a separate article providing <a href="http://www.basilv.com/psd/blog/2009/use-understood-methods-rule">specific guidance on how to apply this rule</a>.</p>
<p>This practice generally aims to prevent interface errors - which I define generally as defects between two separate pieces of code. Research suggests that a significant proportion of defects are due to these kinds of errors (See for example the paper <a href="http://users.ece.utexas.edu/~perry/work/papers/isnd.pdf">An Empirical Study of Software Interface Faults</a>.)</p>
<p>I find this rule particularly valuable when applied to the invocation of methods between classes and especially between components. In this case it helps prevent integration errors which are usually not caught by unit testing.</p>
<h3>Design by Contract</h3>
<p>The idea of design by contract is to precisely specify the behavior of methods to help ensure that they are invoked correctly by callers and that the callers receive the results they are expecting. This is done by precisely specifying the preconditions and postconditions of methods. The chief proponent of design by contract is <a href="http://bertrandmeyer.com/">Bertrand Meyer</a>, whose book <a href="http://www.amazon.ca/gp/product/0136291554?ie=UTF8&#038;tag=basilvandegri-20&#038;linkCode=as2&#038;camp=15121&#038;creative=330641&#038;creativeASIN=0136291554">Object-Oriented Software Construction</a><img src="http://www.assoc-amazon.ca/e/ir?t=basilvandegri-20&#038;l=as2&#038;o=15&#038;a=0136291554" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /> is a classic on the topic. </p>
<p>Method preconditions are conditions that must be true in order for the method to successfully execute and fulfill its postconditions. Preconditions are most commonly applied to method arguments. For example, a method to convert a string to a date might have the precondition that the string argument must not be null. Preconditions can also be applied to the state within the class or even external state. For example, a method to delete a particular object from the database might have the precondition that the object exists within the database.</p>
<p>Method postconditions are conditions that the method guarantees to be true after execution, assuming the preconditions are met. Postconditions are most commonly applied to the return value of methods, but like preconditions can also be applied to the state within the class or external state. Returning to the example of a method that converts a string to a date, such a method could have two postconditions. First, that the method will return a corresponding date object that is not null if the input is a string in a valid date format, and second that the method will throw a specified exception if the input does not correspond to a valid date format. </p>
<p>The combination of preconditions and postconditions forms in essence a contract between the method and its caller. The caller promises to fulfill the preconditions in exchange for the method guaranteeing that the postconditions will be met.</p>
<p>Despite the fact that the name of this practice contains the word "design", this approach does not require a separate up-front design of each method. The goal is to have a clear specification of behavior once the method is finished – how you arrive at it is not important to this practice. I tend to start with an initial idea for a method’s contract that I evolve as I write tests and implement the method’s logic using <a href="http://www.basilv.com/psd/blog/tag/test-driven-development">test-driven development</a>. </p>
<p>There are several options for specifying pre- and post- conditions. Some teams rely solely on their automated unit tests to serve as the specification, but I prefer a more concise specification provided as part of the method definition. In Java I typically use JavaDoc to document pre- and post- conditions and programmatically check argument preconditions at the start of the method. I typically formally specify pre- and post- conditions only on methods that are intended for use by other classes or components. In Java, this is typically public and protected methods of interfaces and classes.</p>
<p>This practice is very closely related to the Use Understood Methods Rule, and they go hand-in-hand. Knowing a method’s pre- and post- conditions is necessary to fully understanding it. As I stated above, I tend to only apply formal design by contract to methods intended for use outside the class in question, which means this practice is really aimed at preventing integration defects.</p>
<h3>Defensive Coding</h3>
<p>Defensive coding is named after the practice of <a href="http://en.wikipedia.org/wiki/Defensive_driving">defensive driving</a> and is based on the same mindset of expecting problems to occur and actively taking precautions to avoid them. Defensive coding is applied by adopting a language-specific set of idioms that minimize or prevent common coding errors when using the language. These idioms are often reflected in coding standards.</p>
<p>Here are some examples of defensive coding idioms for Java:</p>
<ul>
<li>When comparing if a variable is equal to a constant, put the constant first. This avoids a potential null-pointer exception (if the variable is null) by invoking the equals() method on the constant, which is never null.
<pre class="prettyprint">
public boolean isAdmin(String userId) {
  String constant = "admin";
  return constant.equals(userId); // Instead of userId.equals(constant)
}
</pre>
</li>
<li>Always use braces to define a block of code for an if, else, while, for, or do statement, even if the block contains only a single line of code. This avoids the problem of later adding a second line of code indented to the same level as the first and mistakenly thinking it will invoked as part of the block.
<pre class=" prettyprint">
public void addOptions(String userId) {
  if (isAdmin(userId)) {
    addAdminOptions();
  } else {
    addRegularUserOptions();
  }
}
</pre>
</li>
<li>Use the Java 5 for-each construct rather than using a loop index variable to manually iterate through a list. This avoids the problem of having an off-by-one error in constructing the loop.
<pre class="prettyprint">
public void processOptions(List<Option> options) {
  for (Option option : options) {
    option.process();
  }
}
</pre>
</li>
</ul>
<p>Defensive coding aims to minimize coding errors, both at the time of coding and in the future when the code is being modified by others. While these types of errors are typically easily detected by unit testing, I find that using these idioms (after the initial adoption) takes virtually no effort or thought on my part, making them literally a no-brainer to use.</p>
<h3>Example-Based Requirements</h3>
<p>The idea behind this practice is to express requirements as much as possible in terms of concrete examples rather than the generalized wording typically used in use cases and lists of business rules which is almost always ambiguous. I have written a separate article providing <a href="http://www.basilv.com/psd/blog/2010/example-based-requirements">further details on example-based requirements</a> which includes a specific example. :)</p>
<p>The practice of example-based requirements aims at minimizing requirement errors, particularly errors due to misunderstanding or misinterpreting. The examples should also be used as acceptance test cases, in which case they help detect design or coding errors (although unit tests should identify most of these first).</p>
<h3>Conclusion</h3>
<p>I encourage you to choose one or more of these practices to adopt in your current development work. There will be extra effort initially to understand and become comfortable with a given practice, but this will decline over time as you achieve mastery of it.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.basilv.com/psd/blog/2010/defect-prevention-practices/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Inspiring Great Design</title>
		<link>http://www.basilv.com/psd/blog/2008/inspiring-great-design</link>
		<comments>http://www.basilv.com/psd/blog/2008/inspiring-great-design#comments</comments>
		<pubDate>Sun, 13 Jan 2008 21:35:02 +0000</pubDate>
		<dc:creator>Basil Vandegriend</dc:creator>
				<category><![CDATA[design]]></category>
		<category><![CDATA[requirements]]></category>
		<category><![CDATA[usability]]></category>

		<guid isPermaLink="false">http://www.basilv.com/psd/blog/2008/inspiring-great-design</guid>
		<description><![CDATA[I recently acquired a design tool – a set of IDEO method cards, where each card presents a design approach or a method of gaining inspiration. IDEO's design philosophy is to keep people at the center of the design process, and the four categories they divide the cards into reflect this: Ask people to help. [...]]]></description>
			<content:encoded><![CDATA[<p>I recently acquired a design tool – a set of <a href="http://www.ideo.com">IDEO</a> method cards, where each card presents a design approach or a method of gaining inspiration. IDEO's design philosophy is to keep people at the center of the design process, and the four categories they divide the cards into reflect this:</p>
<ul>
<li><strong>Ask</strong> people to help.</li>
<li><strong>Look</strong> at what people do.</li>
<li><strong>Learn</strong> from the facts you gather.</li>
<li><strong>Try</strong> it yourself.</li>
</ul>
<p>IDEO designs an incredibly wide variety of products – corporate websites, hand-held electronics,  clothing, business services, furniture, and more. With such diversity, it is no surprise that not all of the cards appear applicable to software development. I found that going through the cards and thinking about how they relate to I.T. to be interesting. I ended up classifying the relevant cards into three groups: </p>
<ul>
<li><strong>Requirements</strong>: These cards provide ideas on how to gather or analyze requirements.  This was the largest group by far – over one third of the total number of cards, and they spanned the four categories above. If you work in I.T., it may seem that calling tips for requirements design approaches is inappropriate. In software development there is often a divide between requirements and design. You do need to understand the client's needs and determine a solution that meets those needs, but an explicit separation in role between these activities can often hurt the final product. IDEO takes a holistic approach: determining requirements and understand the user is part of the design process and not a precursor to it.
</li>
<li><strong>User Interface Design</strong>: About one-sixth of the cards presented ideas related to user interface design. These mostly fell into the Try category, with a few in Learn and Ask. Prototyping and testing of various sorts were reoccurring themes in over half of these cards.
</li>
<li><strong>Software Design</strong>: Only a few cards seemed relevant to application architecture and software design. I initially found this surprising since I was expecting more. After further reflection, I realized that the commonly held understanding of design in the context of software development is very technical and narrowly focused. This 'technical' design activity (for lack of a better term) is necessary but not sufficient for creating a great piece of software. Other activities within the course of a development project that we in I.T. do not call design – activities such as requirements gathering, analysis, and usability testing – are all part of IDEO's holistic view of design.
</li>
</ul>
<p>In order to provide a concrete example of what the cards are like, I list in the table below a few of the cards I found particularly interesting. Each card explains not only a design method (the how), but also the reason for using it (the why). (Each card also briefly describes an IDEO project that used this method, but I do not list that below.)</p>
<table class="fancy" cellspacing="0">
<tr>
<th>Title</th>
<th>How</th>
<th>Why</th>
</tr>
<tr>
<td>Five Whys?</td>
<td>Ask "Why?" questions in response to five consecutive answers.</td>
<td>This exercise forces people to examine and express the underlying reasons for their behaviors and attitudes.</td>
</tr>
<tr>
<td>Rapid Ethnography</td>
<td>Spend as much time as you can with people relevant to the design topic. Establish their trust in order to visit and/or participate in their natural habitat and witness specific activities.</td>
<td>This is a good way to achieve a deep firsthand understanding of habits, rituals, natural language, and meanings around relevant activities and artifacts.</td>
</tr>
<tr>
<td>Error Analysis</td>
<td>List all the things that can go wrong when using a product and determine the various possible causes.</td>
<td>This is a good way to understand how design features mitigate or contribute to inevitable human errors and other failures.</td>
</tr>
</table>
<p>Looking at these design methods and the many others listed in the set of IDEO cards makes me appreciate all that goes into a well-designed product, and inspires me to think more carefully about how I think about and approach design.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.basilv.com/psd/blog/2008/inspiring-great-design/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Producing Good Software is Hard</title>
		<link>http://www.basilv.com/psd/blog/2006/producing-good-software-is-hard</link>
		<comments>http://www.basilv.com/psd/blog/2006/producing-good-software-is-hard#comments</comments>
		<pubDate>Thu, 07 Dec 2006 15:00:34 +0000</pubDate>
		<dc:creator>Basil Vandegriend</dc:creator>
				<category><![CDATA[professional]]></category>
		<category><![CDATA[IT industry]]></category>
		<category><![CDATA[project management]]></category>
		<category><![CDATA[requirements]]></category>
		<category><![CDATA[software development]]></category>

		<guid isPermaLink="false">http://www.basilv.com/psd/blog/2006/producing-good-software-is-hard</guid>
		<description><![CDATA[This is a public service announcement to all project managers, business analysts, others working in the I.T. industry, and the general public: producing good software is hard. The next time you wonder why the software you are using crashed, or why your software development project is behind schedule, or why your software doesn't meet the [...]]]></description>
			<content:encoded><![CDATA[<p>This is a public service announcement to all project managers, business analysts, others working in the I.T. industry, and the general public: producing good software is hard. The next time you wonder why the software you are using crashed, or why your software development project is behind schedule, or why your software doesn't meet the users needs, remember this point.</p>
<p>People I have dealt with professionally who are not software developers occasionally make comments that imply that writing enterprise business software is a fairly straight-forward task, easily handled by the average developer. I have challenged these statements by pointing out that reality disagrees. The majority of software development projects are overrun or canceled. Software that does make it into production often has serious operational failures, performance issues, or fails to meet users' requirements, and much of it is poorly designed, making it difficult to correct these issues and implement enhancements. These problems cannot be blamed solely upon weak developers. Across the industry, the typical software development team will be staffed by average developers (by definition), which means that the problems I just described affecting a majority of projects result from the efforts of average developers.</p>
<p>In defense of software developers, the leading causes of project failure or overrun are actually in the areas of project management (i.e. overly aggressive schedules) and requirements gathering. Problems in these areas cause much more serious impacts, and this is perhaps why project managers and business analysts sometimes feel that writing the code is the easy part. But it is not. Even assuming sufficient time, clear requirements, and a decent solution architecture (which are big assumptions), producing working, high-quality code is hard. </p>
<p>Why is this? I'll first look at meeting the functional requirements. For a typical enterprise business application many of the functional requirements are admittedly simple, and can be summarized as creating data entry screens for a particular set of data. Many of the enterprise business applications I have been involved with, however, also have more complex functional requirements such as complex business rules, batch processing, web services, or data conversion. These more challenging requirements are the ones most likely to cause problems for the development team.</p>
<p>Software must also meet non-functional requirements in areas such as performance, usability, and <a href="http://www.basilv.com/psd/blog/2006/the-importance-of-maintainable-software">maintainability</a>, and I believe that most enterprise software does poorly in these areas. It is simple to explain why: everyone is focused on meeting the functional requirements - clients, testers, and project managers as well as developers - so the non-functional requirements are neglected. Even when someone - most often the architect - considers the non-functional requirements, it is difficult to address them all at the same time. Typically multiple iterations are necessary. For example, a developer first writes code that meets the functional requirements, then tries out the user interface and make improvements to address usability issues, then tests and addresses performance issues, and finally cleans up the code  to ensure the design is maintainable - easy to understand and modify. These multiple iterations take time, skill and dedication, and if a developer is lacking in one of these areas, the non-functional requirements will likely be neglected.</p>
<p>Combine the challenges in both the functional and non-functional requirements, and the result is that the typical software application will fall short in at least one area. Add in other common challenges like a compressed schedule and unclear or changing requirements, and the chance of success plummets even lower. In other words, producing good software is hard.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.basilv.com/psd/blog/2006/producing-good-software-is-hard/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

