<?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>Ray Morgan &#187; Project Management</title>
	<atom:link href="http://raymorgan.net/articles/project-management/feed/" rel="self" type="application/rss+xml" />
	<link>http://raymorgan.net</link>
	<description>Web Development, Travel, Photography, and more</description>
	<lastBuildDate>Tue, 25 May 2010 23:29:45 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>How to Use the User Interface to Discover All the Use Cases</title>
		<link>http://raymorgan.net/web-development/using-the-ui-to-discover-use-cases/</link>
		<comments>http://raymorgan.net/web-development/using-the-ui-to-discover-use-cases/#comments</comments>
		<pubDate>Tue, 29 Dec 2009 05:14:40 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Project Management]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://raymorgan.net/?p=7</guid>
		<description><![CDATA[If you build software for a living, it&#8217;s a matter of time before you find yourself discovering too late in a project that some important piece of functionality wasn&#8217;t accounted for. Often this is the result of assumptions &#8212; whoever was responsible for writing the functional spec assumed that some piece of functionality must be [...]]]></description>
			<content:encoded><![CDATA[<p>If you build software for a living, it&#8217;s a matter of time before you find yourself discovering too late in a project that some important piece of functionality wasn&#8217;t accounted for. Often this is the result of <em>assumptions</em> &mdash; whoever was responsible for writing the functional spec <em>assumed</em> that some piece of functionality must be included, since omitting it would be illogical. Discovery of a missed piece of functionality usually sounds something like:</p>
<p class="em strong center">&ldquo;Of course moderators have to approve user-uploaded photos! How could they <em>not</em>?&rdquo;</p>
<p>Omissions like this are particularly common in the administrative half of applications. After all, the product guys invest lots of time designing the public-facing user interface, but use cases for administrative users are often overlooked or assumed to somehow just automagically <em>be there</em>. Those tasked with detailed spec-writing are often surprised that, in most systems, there are <em>at least</em> as many use cases for administrators as for public users.</p>
<p>This article discusses a simple technique for discovering those easy-to-miss use cases as early in the project as possible.</p>
<h2>Accounting for all Basic UI Functions</h2>
<p>You&#8217;re probably familiar with the set of basic database functions collectively known as <a  href="http://en.wikipedia.org/wiki/Create,_read,_update_and_delete">CRUD</a>:</p>
<ul>
<li><strong>Create</strong> a new record</li>
<li><strong>Recall</strong> an existing record</li>
<li><strong>Update</strong> an existing record</li>
<li><strong>Delete</strong> an existing record</li>
</ul>
<p>These four actions constitute the basic functions upon which almost all data storage and retrieval actions are based.</p>
<p>Corresponding to these four primary database functions are eight primary actions that your UI may provide:</p>
<table class="grid" align="center">
<tr>
<th>UI Actions</th>
<th>CRUD Functions</th>
</tr>
<tr>
<td>add</td>
<td>create</td>
</tr>
<tr>
<td>view</td>
<td>recall</td>
</tr>
<tr>
<td>list</td>
<td>recall</td>
</tr>
<tr>
<td>search</td>
<td>recall</td>
</tr>
<tr>
<td>edit</td>
<td>update</td>
</tr>
<tr>
<td>recycle</td>
<td>update (assumes setting a flag)</td>
</tr>
<tr>
<td>restore</td>
<td>update (assumes setting a flag)</td>
</tr>
<tr>
<td>delete</td>
<td>delete</td>
</tr>
</table>
<p>Since our goal is to avoid surprises late in the project, we&#8217;re going to try to account for every action by every actor (user) upon every object in the system.</p>
<p>By way of example, let&#8217;s assume your system is something like <a targer="_blank" href="http://www.flickr.com/">flickr</a>, so it will have use cases to handle its <code>Photograph</code> objects. We can account for those use cases like in this example:</p>
<table class="grid" align="center">
<tr>
<th colspan="3">Use Cases &#8211; <code>Photograph</code> Object</th>
</tr>
<tr>
<th>UI Action</th>
<th>Actor</th>
<th>Use Case</th>
</tr>
<tr>
<td>add</td>
<td>new user</td>
<td>Registered user uploads a new photograph.</td>
</tr>
<tr>
<td>view</td>
<td>any user</td>
<td>User clicks on thumbnail to view a full-size enlargement of a photograph.</td>
</tr>
<tr>
<td>view</td>
<td>registered user</td>
<td>User clicks on thumbnail to view a full-size enlargement of a private photograph whose access is restricted to users on the owner&#8217;s friends list.</td>
</tr>
<tr>
<td>list</td>
<td>any user</td>
<td>User views a list of thumbnails for photographs uploaded in the past seven days.</td>
</tr>
<tr>
<td>list</td>
<td>registered user</td>
<td>Registered user views a list of thumbnails for photographs they have uploaded.</td>
</tr>
<tr>
<td>list</td>
<td>registered user</td>
<td>Registered user views a list of thumbnails for photographs they have recycled.</td>
</tr>
<tr>
<td>list</td>
<td>moderator</td>
<td>Moderator views a list of thumbnails for photographs awaiting moderation.</td>
</tr>
<tr>
<td>search</td>
<td>any user</td>
<td>User searches for photographs by keywords and/or tags.</td>
</tr>
<tr>
<td>search</td>
<td>any user</td>
<td>User searches for photographs by minimum or maximum dimensions.</td>
</tr>
<tr>
<td>edit</td>
<td>registered user</td>
<td>Registered user edits metadata (title, description, tags, etc.) for one of their photographs.</td>
</tr>
<tr>
<td>edit</td>
<td>registered user</td>
<td>Registered user selects tags and applies them to a group of his photographs.</td>
</tr>
<tr>
<td>edit</td>
<td>registered user</td>
<td>Registered user changes the visibility of a photograph from &#8216;visible&#8217; to &#8216;invisible&#8217;.</td>
</tr>
<tr>
<td>edit</td>
<td>registered user</td>
<td>Registered user changes the visibility of a photograph from &#8216;invisible&#8217; to &#8216;visible&#8217;.</td>
</tr>
<tr>
<td>edit</td>
<td>registered user</td>
<td>Registered uploads a new photograph to replace an existing one. (Note: This action puts the photograph back in the queue for moderator approval.)</td>
</tr>
<tr>
<td>edit</td>
<td>moderator</td>
<td>Moderator sets the status of a photograph to &#8216;approved&#8217;.</td>
</tr>
<tr>
<td>edit</td>
<td>moderator</td>
<td>Moderator sets the status of a photograph to &#8216;rejected&#8217;.</td>
</tr>
<tr>
<td>recycle</td>
<td>registered user</td>
<td>Registered user recycles one photograph.</td>
</tr>
<tr>
<td>recycle</td>
<td>registered user</td>
<td>Registered user recycles photographs selected from a group.</td>
</tr>
<tr>
<td>recycle</td>
<td>registered user</td>
<td>Registered user recycles all of the photographs in a selected album.</td>
</tr>
<tr>
<td>restore</td>
<td>registered user</td>
<td>User restores a recycled photograph.</td>
</tr>
<tr>
<td>delete</td>
<td>registered user</td>
<td>Registered user permanently deletes a recycled photograph.</td>
</tr>
</table>
<p>This is an example using only the system&#8217;s <code>Photograph</code> object. The idea is to go through this exercise with, yes, every object in the system.</p>
<h2>Whoa! That&#8217;s going to be a <em>lot</em> of use cases!</h2>
<p>Yes, it probably is, and it&#8217;s invariably more than you&#8217;d expect after just a cursory review of a system. But that&#8217;s the whole point: A cursory review misses a lot, so this is a fairly easy, methodical way to step through all of the actions, actors and objects in a system.</p>
<p class="strong em">Are you crazy? Do you know how long that will take?</p>
<p>Yes, actually I know exactly how long it takes. I also know that it&#8217;s worth every minute. Here&#8217;s why: By the time any project is successfully completed, you have &mdash; one way or another &mdash; done this exercize. If you haven&#8217;t, the project didn&#8217;t complete <em>successfully</em>, and vice versa.</p>
<p>If this sounds tedious, <em>it is</em>. It can take days (or longer) to plow through all of the use cases uncovered by this technique. Note that I say <em>uncovered</em> and not <em>created</em>; this approach is meant to reveal and capture all those little cases nobody thought to include. One way or the other, your system won&#8217;t be complete until you account for all of these use cases, so the sooner you discover them, the better.</p>
<p>Since you&#8217;re going to have to account for all of these use cases in order to succeed, there are some compelling reasons to do it early in the project:</p>
<ul>
<li>Identifying all of the likely use cases early helps you decide how to phase the project, which features to defer, and which pieces of functionality can probably be omitted altogether.</li>
<li>Identifying as many use cases as possible early in the project gives you the best data on how long it&#8217;s likely to take, how much it&#8217;s likely to cost, and in fact whether it&#8217;s worth doing.</li>
<li>Identifying use cases early enables testers to begin drafting test plans almost immediately.</li>
<li>Identifying use cases early enables tech writers to start writing user manuals almost immediately.</li>
<li>Identifying use cases early enables the whole team to succeed by design rather than by chance, which is good, because chance has a lousy track record.</li>
</ul>
<p>It&#8217;s worth noting that there won&#8217;t necessarily be use cases for every action by every actor for every object. For example, there&#8217;s often no requirement for registered public users to delete thier own account (that is, the <code>User</code> object that represents their own account). It&#8217;s common to decide that not all functions are required for every object. Remember, the goal is to <em>account</em> for every possibility, not necessarily to <em>implement</em> them all.</p>
]]></content:encoded>
			<wfw:commentRss>http://raymorgan.net/web-development/using-the-ui-to-discover-use-cases/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
