<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet href="http://technicaldebt.wetpaint.com/xsl/rss2html.xsl" type="text/xsl" media="screen"?><?xml-stylesheet href="http://technicaldebt.wetpaint.com/scripts/wpcss/wiki/technicaldebt/skin/techiechic/rss" type="text/css" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/"><channel><title>Technical Debt - Recently Updated Pages</title><link>http://technicaldebt.wetpaint.com/pageSearch/updated</link><description>Recently Updated Pages on http://technicaldebt.wetpaint.com</description><language>en-us</language><webMaster>info@wetpaint.com</webMaster><pubDate>Fri, 08 Apr 2011 10:48:27 CDT</pubDate><lastBuildDate>Fri, 08 Apr 2011 10:48:27 CDT</lastBuildDate><generator>wetpaint.com</generator><ttl>60</ttl><image><title>Technical Debt</title><url>http://create.wetpaint.com/img/logo.gif</url><link>http://technicaldebt.wetpaint.com</link><description>In software, poor architecture &amp; quality lead to mounting costs over time: &quot;Technical Debt.&quot; Understanding the business is key: pay now for quality, or pay a lot more later. Arguably the best example of TD was the &quot;Y2K bug&quot;.</description></image><item><title>Parallel Development</title><link>http://technicaldebt.wetpaint.com/page/Parallel+Development</link><author>JonKern</author><guid isPermaLink="false">http://technicaldebt.wetpaint.com/page/Parallel+Development</guid><pubDate>Fri, 08 Apr 2011 10:48:27 CDT</pubDate><description>&lt;b&gt;Parallel Development&lt;/b&gt; allows teams to work on various aspects of the same product source code base.  As you near the end of feature development for the current release, freeze the code, and begin more &amp;quot;formal&amp;quot; testing, you will find some developers with time on their hands. For this reason, it makes sense to apply this ever-growing group of developers to work on the next release. Therefore, we create a new branch: &lt;ul&gt;&lt;li&gt;Since we do not want to risk making changes to the &amp;quot;release&amp;quot; code we are about to deliver,&lt;/li&gt;&lt;li&gt;Since we do not want to simply have developers working in their own workspaces until the current release is made and they can start &amp;quot;checking in&amp;quot; code again, and&lt;/li&gt;&lt;li&gt;Since we want to make it easy for a developer to halt their new development and fix a bug (requiring restoring their system to match the current release code base, and reverting back again once their bug fix is approved and checked in).&lt;/li&gt;&lt;/ul&gt;   Hence, we end up with a high-level view of the parallel development process as follows:&lt;br&gt;     &lt;br&gt;Note, for a moment, the overlapping nature of Figure 2. Except for the fact that you are likely resource-limited, development never stops. Market research, client feedback, and planning the next version do not stop either. In addition, a release comes every X months, like clockwork. It is all very rhythmic and should have a non-chaotic flow to the process.  The concept of a &amp;quot;code freeze&amp;quot; is just in terms of the code base for the current release about to be shipped (to allow stabilization of the source). The rest of the developers keep right on working on the main trunk code base.  Essentially, this large &amp;quot;outer loop&amp;quot; surrounding release-style development has an overlapping region. As the code is frozen on Release N and formal testing commences, new development starts on Release N+1 by part of the staff. To keep the code safe, this is when branching is done for this style of development.  This requires all folks involved with developing a release to be very aware of the rhythmic nature of this process. Marketing, product champions, field engineers, documentation, trainers, management, etc., all have to be working ahead of the team in terms of planning the next release. Depending on your overall release schedule duration, you need to be aware of potential bottlenecks with some of the non-development-related issues. For example, marketing would be hard-pressed to plan for the next release at the same time as getting the current release out the door.  &lt;h2&gt;Triggering a Test Cycle&lt;/h2&gt;  If the software world were perfect, all you would need to do is to create features, have them &amp;quot;ensured&amp;quot; by automated unit and acceptance tests, do some manual testing for those areas that require a human touch, and shorten the &amp;quot;Formal Testing&amp;quot; cycle down to mere days.   Obviously, this is rarely the case in complex software. But a worthy goal to strive for, nonetheless.  You should attempt to shrink the amount of time devoted to testing under code freeze to as short as possible. This is largely a balancing act between improving the entire development process, improving quality of code, automating as much testing as possible, making manual testing as efficient as possible, and doing the &amp;quot;right amount&amp;quot; of testing to deliver a quality product. Over time, a team should be able to improve and reach an optimal balance.   In addition, you should not turn out QA builds one after the other every time a bug is found. Every time QA gets a new build, the test cycle restarts, costing $$ and time (and good will) of all the testers. You want to strike a balance here as well.  &lt;h2&gt;Branching&lt;/h2&gt; Though there are a few different ways to control software releases, the most popular method - and the one supported by most tools - is the simple branching technique. This allows teams to undertake parallel development. That is, you can have multiple project teams working in parallel on the same (in a virtual sense) code base.  Of course, &amp;quot;simple branching&amp;quot; is relative. Branching can lead to high degrees of complexity and confusion if not done properly. Branching can even come about due to different reasons: &lt;ul&gt;&lt;li&gt;Product enhancements: patches, releases, etc.&lt;/li&gt;&lt;li&gt;Platform or OS: maybe you need to support a new internationalization initiative, or a new hardware platform&lt;/li&gt;&lt;li&gt;Roles: maybe you branch for the QA team to do their thing&lt;/li&gt;&lt;li&gt;Phases: you have a promotion scheme whereby the code goes from development, to QA, to release, to maintenance&lt;/li&gt;&lt;/ul&gt;   The basic problem facing development is that different developers need different bodies of the &amp;quot;same&amp;quot; code at different times for different purposes. Confused? Me too.  Lets assume we have a product that looks like this: &lt;ul&gt;&lt;li&gt;WidgetFactory 	&lt;ul&gt;&lt;li&gt;v1.0 		&lt;ul&gt;&lt;li&gt;v1.1&lt;/li&gt;&lt;/ul&gt; 		&lt;/li&gt;&lt;li&gt;v2.0 		&lt;ul&gt;&lt;li&gt;v2.01&lt;/li&gt;&lt;li&gt;v2.1&lt;/li&gt;&lt;li&gt;v2.5&lt;/li&gt;&lt;/ul&gt; 		&lt;/li&gt;&lt;li&gt;v3.0&lt;/li&gt;&lt;/ul&gt; 	&lt;/li&gt;&lt;/ul&gt;   You need to be able to have developers create workspaces that reflect the proper body of code for their current tasks (be it development of features in the main trunk, bug fixing for v2.1, or exploratory development for a new architectural approach concept).&lt;br&gt;&lt;br&gt;Some specific instructions using Eclipse found &lt;a href=&quot;http://technicaldebt.wetpaint.com/page/Branch+Development&quot; target=&quot;_self&quot;&gt;here&lt;/a&gt;.&lt;br&gt;&lt;h3&gt;The Main Trunk&lt;/h3&gt;  Obviously, we have to start with a hunk of source code for a given application. The code from which we continue to earn a living must carry on into the future.  All releases share the main trunk. In theory, you propagate applicable bug fixes for a given release (branch) back to the main trunk to the benefit of all future releases. (Merging assumes that the bug fix still makes sense in the context of the current state of the code.)  An even greater theory is that you could build the application from the main trunk and that the automated tests pass with flying colors. This is a style of development that some people prefer. That is, there is an edict that the main trunk should reflect a useful state of running software (sometimes at a given point in time: daily, every Friday, etc.).  The Main Trunk represents the latest and greatest. From this trunk you create the branches - hence the tree analogy. If you branch too much, you get a shrub. Avoid shrubbery.  &lt;h3&gt;Release Branches&lt;/h3&gt;  You typically create release branches to establish the code base that you will eventually deliver to the customer. When the current development branch nears Code Freeze, you create the branch so that you can control changes more closely. What underlies the desire to create a new branch is simple:  &lt;ul&gt;&lt;li&gt;You do not want &amp;quot;harmful&amp;quot; changes to the code as you are squashing bugs, and readying for a stable release/shippable build.&lt;/li&gt;&lt;li&gt;You want other developers to be able to continue on the next version underway. That is, they should be able to continue to add new features, undertake major refactorings, and generally do other tasks that could be very disruptive to the code base.&lt;/li&gt;&lt;/ul&gt;   At the stage where a Code Freeze has been enacted, all developers know to not &amp;quot;break&amp;quot; the build. Only bug fixes that have been approved get done (that is, they are demonstrated to truly fix the problem and not wreak havoc on other parts of the system). Developers may be limited in their capability to check-in to the code base. Maybe the chief programmer must approve the changes, after which you can check in the code. Normally, you blast out a stern email message to the team, reminding them to increase their awareness to protect the release code from instability. This means things like:  &lt;ul&gt;&lt;li&gt;Only change what is minimally necessary to fix a bug.&lt;/li&gt;&lt;li&gt;Be very cautious about changes in files/methods that others have many dependencies on. If unavoidable, alert QA that more testing in the affected area(s) may be in order.&lt;/li&gt;&lt;li&gt;Though you may spot some other neighboring code that needs &amp;quot;improvements&amp;quot; while you are making a bug fix, resist the temptation to make a &amp;quot;little, harmless fix.&amp;quot; (Do it in the new branch, or log it in bug/task tracker for doing in the future.)&lt;/li&gt;&lt;li&gt;The less code you touch, the less likely you will create unintended consequences.&lt;/li&gt;&lt;/ul&gt;   Depending on your style of development, you may do one of the following: &lt;ul&gt;&lt;li&gt;&lt;b&gt;Preferred:&lt;/b&gt; Main trunk is your development stream. You create a new branch N for the release. New development continues in main trunk, and you relegate critical release development to the new branch.&lt;/li&gt;&lt;li&gt;You are working in the existing release N branch. You create a Release N+1 branch. New development takes place in N+1, careful bug fixing takes place in the N branch.&lt;/li&gt;&lt;/ul&gt;   With multiple branches and a trunk, you have the potential for a single file to have different revisions that have diverged in content. The section on &amp;quot;Merging&amp;quot; will address what to do.  &lt;h3&gt;Tags and Labels&lt;/h3&gt; Many times, your version control software gives you the opportunity to apply a special name or symbol to a bunch of files to represent a point in time. For example, when you have finally decided to release the software to your clients, you should label all current files in the branch to be identifiable as the files that went into this official release.   This gives you the ability to reliably retrieve the precise body of source code and related files that went into a shipping/deployed version. This is especially useful when it comes time to fix a bug in this version, and deliver a new &amp;quot;patch&amp;quot; or update your delivery files.  When you have files tagged/labeled/marked, you can request all files with a given tag. This is kind of like turning the repository upside down and shaking it: only those files that have the requested tag will &amp;quot;fall out.&amp;quot; Newer versions of files on the trunk will not be brought forth.  In CVS, for example, you can create a branch based on a given set of tagged files. For example, you can create a branch labeled &amp;quot;ver 1 0 patch&amp;quot; based on files tagged as &amp;quot;ver 1 0.&amp;quot; (Note: I use labels that indicate major and minor version numbers so that it is clear what I am trying to demonstrate. However, you can use tags that are code names or numeric values as well.)  &lt;h3&gt;Merging&lt;/h3&gt;  The concept of merging is to take changes in one branch, and update another branch and/or the main trunk. The easiest way to visualize this is to consider a single file in your system that goes through some changes.   Suppose, for a moment, that one of your customers actually found a bug &amp;ndash; as rare as that might seem to you. You have two choices: &lt;ul&gt;&lt;li&gt;Fix it in the current new development branch/main trunk, deliver in the next scheduled cycle.&lt;/li&gt;&lt;li&gt;Make a bug fix/patch release.&lt;/li&gt;&lt;li&gt;Ignore the bug. :0&lt;br&gt; I know, I said two choices but gave you three. The third choice (a viable one, I might add) requires no knowledge of releases and branching, so we will stick to the first two.&lt;/li&gt;&lt;/ul&gt;   Lets assume you decide to make a patch release, so you create a new branch based on the release branch. By checking out from the new &amp;quot;patch&amp;quot; branch, the developer is able to quickly get the necessary files for the release in which the offending bug exists. The developer then makes a fix to the source code, does some testing, and checks the code back into the &amp;quot;patch&amp;quot; branch. A patch build should be simple (because you also tagged all supporting files; e.g., build scripts, installer scripts, documentation, tests). You then might go through a full or abbreviated QA cycle to test the change(s).  Merging Changes Across Branches:&lt;br&gt;    &lt;br&gt; Note how the Figure also shows changes made in the branches being merged back into the main trunk. Of course, this may or may not be done. Some times, a fix in an older version of the file may be unnecessary due to subsequent changes made to the file or the program architecture.&lt;hr size=&quot;1&quot;&gt;&lt;br/&gt;</description></item><item><title>Branch Development</title><link>http://technicaldebt.wetpaint.com/page/Branch+Development</link><author>JonKern</author><guid isPermaLink="false">http://technicaldebt.wetpaint.com/page/Branch+Development</guid><pubDate>Fri, 08 Apr 2011 10:46:29 CDT</pubDate><description>As described in &lt;a href=&quot;http://technicaldebt.wetpaint.com/page/Parallel+Development&quot; rel=&quot;nofollow&quot; target=&quot;_self&quot;&gt;Parallel Development&lt;/a&gt;, we use &lt;b&gt;branches&lt;/b&gt; in SVN to snapshot the code base that reflects the released version of the project. This allows new development to carry on in the &lt;b&gt;TRUNK&lt;/b&gt;; while still allowing maintenance to the released version to occur in the branch.  &lt;br&gt;As we find new bugs, we will decide if they need to be fixed in the branch. Those items that are deemed critical will be fixed in a special milestone. For example, current release is BETA-2, for hot fixes, we would create &amp;quot;Beta-2-1&amp;quot; as a new milestone/branch.&lt;br&gt;  &lt;b&gt;Branch Development Process&lt;/b&gt; &lt;br&gt;In short, you make your eclipse workspace be identical to BETA2.1 Branch. Do your fixes, check them into the branch. Then you decide if you want to promote the fix to the TRUNK or not (using the version control MERGE feature &amp;ndash; include &amp;#39;dry run&amp;#39; if needed). In general, most of the fixes also belong in the trunk.  &lt;br&gt;  &lt;b&gt;&lt;br&gt;&lt;/b&gt;&lt;table align=&quot;bottom&quot; cellpadding=&quot;5&quot; cellspacing=&quot;8&quot; class=&quot;WPC-edit-style-list2 WPC-edit-border-none WPC-edit-styleData-color1=%23c8f1f7&amp;color2=%23c8f1f7&quot; width=&quot;100%&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor=&quot;#bbf2fa&quot; class=&quot; WPC-edit-borderRight-none WPC-edit-custom-borderRightWPC-edit-custom-bgColor&quot; width=&quot;9%&quot;&gt; &lt;/td&gt;&lt;td bgcolor=&quot;#bbf2fa&quot; class=&quot; WPC-edit-custom-borderTopWPC-edit-custom-bgColorWPC-edit-custom-bgColor WPC-edit-borderLeft-none WPC-edit-custom-borderLeft WPC-edit-borderTop-none WPC-edit-custom-borderTopWPC-edit-custom-bgColor&quot; width=&quot;91%&quot;&gt;&lt;b&gt;Benefits of SVN Merge&lt;/b&gt;&lt;br&gt;Yes, you could copy the good file off to the side (or in your paste buffer), and then paste it into the branch file and commit. However, using the SVN merge feature is better because that sets the svn:mergeinfo metadata so that you can track the true history of a file. Copy/pasting does not do this.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;  Moving forward, developers may be required to change code in different branches other than the main /TRUNK/. If you need to do this, follow the process below to switch your project to the appropriate branch.  &lt;table align=&quot;bottom&quot; cellpadding=&quot;5&quot; cellspacing=&quot;8&quot; class=&quot;tipMacro&quot; width=&quot;100%&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor=&quot;#abedc4&quot; class=&quot;WPC-edit-custom-bgColor&quot; width=&quot;9%&quot;&gt; &lt;/td&gt;&lt;td bgcolor=&quot;#abedc4&quot; class=&quot;WPC-edit-custom-bgColor&quot; width=&quot;91%&quot;&gt;&lt;b&gt;Project, Folder, File?&lt;/b&gt;&lt;br&gt;If you need to do extensive development in a branch that relies on deep compiles of code, do the whole project. Just a few stand-alone changes in a well-isolated area? Do the Folder. A simple tweak of a single file that is isolated? Just do the file...&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;  &lt;h2&gt;Setting Up Your Workspace&lt;/h2&gt;Step 1 - Switch to Branch&lt;br&gt;Right click your project:&lt;br&gt; &lt;br&gt;and go to Team &amp;gt; Switch: &lt;br&gt; &lt;br&gt;&lt;br&gt;  &lt;br&gt;&lt;br&gt;Step 2 - Select Branch &lt;br&gt;Click Browse to search the BRANCHES in the repository: &lt;br&gt; &lt;br&gt;Here we have selected BETA2.1 Branch:  &lt;br&gt;Click OK&lt;br&gt; &lt;br&gt; &lt;br&gt;&lt;br&gt;Step 3 - Verify Switch&lt;br&gt;You should see the branch name in your project: &lt;br&gt; &lt;br&gt; &lt;br&gt;&lt;br&gt;  &lt;h2&gt;Making Changes&lt;/h2&gt;&lt;table align=&quot;bottom&quot; cellpadding=&quot;3&quot; class=&quot;WPC-edit-style-columns3 WPC-edit-border-none WPC-edit-styleData-color1=%23ebebeb&amp;color2=%23c7c7c7&quot; width=&quot;100%&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor=&quot;#ebebeb&quot; class=&quot; WPC-edit-borderTop-solid WPC-edit-custom-borderTop WPC-edit-custom-borderBottom WPC-edit-borderLeft-solid WPC-edit-custom-borderLeft WPC-edit-custom-borderRight WPC-edit-borderRight-solid WPC-edit-custom-borderRight WPC-edit-borderBottom-solid WPC-edit-custom-borderBottom&quot; width=&quot;18%&quot;&gt;Complete Your Work&lt;/td&gt;&lt;td class=&quot; WPC-edit-borderTop-solid WPC-edit-custom-borderTop WPC-edit-custom-borderBottom WPC-edit-custom-borderLeft WPC-edit-borderLeft-solid WPC-edit-custom-borderLeft WPC-edit-borderRight-solid WPC-edit-custom-borderRight WPC-edit-borderBottom-solid WPC-edit-custom-borderBottom&quot; width=&quot;82%&quot;&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td bgcolor=&quot;#ebebeb&quot; class=&quot; WPC-edit-custom-borderTop WPC-edit-custom-borderBottom WPC-edit-borderLeft-solid WPC-edit-custom-borderLeft WPC-edit-custom-borderRight WPC-edit-borderRight-solid WPC-edit-custom-borderRight WPC-edit-borderTop-solid WPC-edit-custom-borderTop WPC-edit-borderBottom-solid WPC-edit-custom-borderBottom&quot; width=&quot;18%&quot;&gt;Commit to Branch&lt;/td&gt;&lt;td class=&quot; WPC-edit-custom-borderTop WPC-edit-custom-borderBottom WPC-edit-custom-borderLeft WPC-edit-borderLeft-solid WPC-edit-custom-borderLeft WPC-edit-borderRight-solid WPC-edit-custom-borderRight WPC-edit-borderTop-solid WPC-edit-custom-borderTop WPC-edit-borderBottom-solid WPC-edit-custom-borderBottom&quot; width=&quot;82%&quot;&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td bgcolor=&quot;#ebebeb&quot; class=&quot; WPC-edit-custom-borderTop WPC-edit-custom-borderBottom WPC-edit-borderLeft-solid WPC-edit-custom-borderLeft WPC-edit-custom-borderRight WPC-edit-borderRight-solid WPC-edit-custom-borderRight WPC-edit-borderTop-solid WPC-edit-custom-borderTop WPC-edit-borderBottom-solid WPC-edit-custom-borderBottom&quot; width=&quot;18%&quot;&gt;Compare to Trunk&lt;/td&gt;&lt;td class=&quot; WPC-edit-custom-borderTop WPC-edit-custom-borderBottom WPC-edit-custom-borderLeft WPC-edit-borderLeft-solid WPC-edit-custom-borderLeft WPC-edit-borderRight-solid WPC-edit-custom-borderRight WPC-edit-borderTop-solid WPC-edit-custom-borderTop WPC-edit-borderBottom-solid WPC-edit-custom-borderBottom&quot; width=&quot;82%&quot;&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td bgcolor=&quot;#ebebeb&quot; class=&quot; WPC-edit-custom-borderTop WPC-edit-custom-borderBottom WPC-edit-borderLeft-solid WPC-edit-custom-borderLeft WPC-edit-custom-borderRight WPC-edit-borderRight-solid WPC-edit-custom-borderRight WPC-edit-borderTop-solid WPC-edit-custom-borderTop WPC-edit-borderBottom-solid WPC-edit-custom-borderBottom&quot; width=&quot;18%&quot;&gt;See Diff&lt;/td&gt;&lt;td class=&quot; WPC-edit-custom-borderTop WPC-edit-custom-borderBottom WPC-edit-custom-borderLeft WPC-edit-borderLeft-solid WPC-edit-custom-borderLeft WPC-edit-borderRight-solid WPC-edit-custom-borderRight WPC-edit-borderTop-solid WPC-edit-custom-borderTop WPC-edit-borderBottom-solid WPC-edit-custom-borderBottom&quot; width=&quot;82%&quot;&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td bgcolor=&quot;#ebebeb&quot; class=&quot; WPC-edit-custom-borderTop WPC-edit-custom-borderBottom WPC-edit-borderLeft-solid WPC-edit-custom-borderLeft WPC-edit-custom-borderRight WPC-edit-borderRight-solid WPC-edit-custom-borderRight WPC-edit-borderTop-solid WPC-edit-custom-borderTop WPC-edit-borderBottom-solid WPC-edit-custom-borderBottom&quot; width=&quot;18%&quot;&gt;Your Changed File&lt;/td&gt;&lt;td class=&quot; WPC-edit-custom-borderTop WPC-edit-custom-borderBottom WPC-edit-custom-borderLeft WPC-edit-borderLeft-solid WPC-edit-custom-borderLeft WPC-edit-borderRight-solid WPC-edit-custom-borderRight WPC-edit-borderTop-solid WPC-edit-custom-borderTop WPC-edit-borderBottom-solid WPC-edit-custom-borderBottom&quot; width=&quot;82%&quot;&gt;Revision 9875&lt;br&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td bgcolor=&quot;#ebebeb&quot; class=&quot; WPC-edit-custom-borderTop WPC-edit-borderLeft-solid WPC-edit-custom-borderLeft WPC-edit-custom-borderRight WPC-edit-borderRight-solid WPC-edit-custom-borderRight WPC-edit-borderTop-solid WPC-edit-custom-borderTop WPC-edit-borderBottom-solid WPC-edit-custom-borderBottom&quot; width=&quot;18%&quot;&gt;Log&lt;/td&gt;&lt;td class=&quot; WPC-edit-custom-borderTop WPC-edit-custom-borderLeft WPC-edit-borderLeft-solid WPC-edit-custom-borderLeft WPC-edit-borderRight-solid WPC-edit-custom-borderRight WPC-edit-borderTop-solid WPC-edit-custom-borderTop WPC-edit-borderBottom-solid WPC-edit-custom-borderBottom&quot; width=&quot;82%&quot;&gt;Add revision number/file in Jira comment -- especially important when we  look to bring fixes into a branch.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br&gt;&lt;h2&gt;Merging From Branch To Trunk&lt;/h2&gt;  &lt;table class=&quot;confluenceTable&quot;&gt;&lt;tbody&gt; &lt;tr&gt; &lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;table align=&quot;bottom&quot; cellpadding=&quot;3&quot; class=&quot;WPC-edit-style-columns3 WPC-edit-border-none WPC-edit-styleData-color1=%23ebebeb&amp;color2=%23c7c7c7&quot; width=&quot;100%&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor=&quot;#ebebeb&quot; class=&quot; WPC-edit-borderTop-solid WPC-edit-custom-borderTop WPC-edit-custom-borderBottom WPC-edit-borderLeft-solid WPC-edit-custom-borderLeft WPC-edit-custom-borderRight WPC-edit-borderRight-solid WPC-edit-custom-borderRight WPC-edit-borderBottom-solid WPC-edit-custom-borderBottom&quot; width=&quot;17%&quot;&gt;commit branch&lt;/td&gt;&lt;td class=&quot; WPC-edit-borderTop-solid WPC-edit-custom-borderTop WPC-edit-custom-borderBottom WPC-edit-custom-borderLeft WPC-edit-borderLeft-solid WPC-edit-custom-borderLeft WPC-edit-borderRight-solid WPC-edit-custom-borderRight WPC-edit-borderBottom-solid WPC-edit-custom-borderBottom&quot; width=&quot;83%&quot;&gt;commit your local changes to branch, including unversioned files&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td bgcolor=&quot;#ebebeb&quot; class=&quot; WPC-edit-custom-borderTop WPC-edit-custom-borderBottom WPC-edit-borderLeft-solid WPC-edit-custom-borderLeft WPC-edit-custom-borderRight WPC-edit-borderRight-solid WPC-edit-custom-borderRight WPC-edit-borderTop-solid WPC-edit-custom-borderTop WPC-edit-borderBottom-solid WPC-edit-custom-borderBottom&quot; width=&quot;17%&quot;&gt;determine branch creation&lt;/td&gt;&lt;td class=&quot; WPC-edit-custom-borderTop WPC-edit-custom-borderBottom WPC-edit-custom-borderLeft WPC-edit-borderLeft-solid WPC-edit-custom-borderLeft WPC-edit-borderRight-solid WPC-edit-custom-borderRight WPC-edit-borderTop-solid WPC-edit-custom-borderTop WPC-edit-borderBottom-solid WPC-edit-custom-borderBottom&quot; width=&quot;83%&quot;&gt;go to your branch within SVN repository browser, right click, show log  and select &amp;quot;stop on copy&amp;quot;. scroll to the end (page if needed) to see  the revision when the branch was copied &lt;br&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td bgcolor=&quot;#ebebeb&quot; class=&quot; WPC-edit-custom-borderTop WPC-edit-custom-borderBottom WPC-edit-borderLeft-solid WPC-edit-custom-borderLeft WPC-edit-custom-borderRight WPC-edit-borderRight-solid WPC-edit-custom-borderRight WPC-edit-borderTop-solid WPC-edit-custom-borderTop WPC-edit-borderBottom-solid WPC-edit-custom-borderBottom&quot; width=&quot;17%&quot;&gt;switch to TRUNK&lt;/td&gt;&lt;td class=&quot; WPC-edit-custom-borderTop WPC-edit-custom-borderBottom WPC-edit-custom-borderLeft WPC-edit-borderLeft-solid WPC-edit-custom-borderLeft WPC-edit-borderRight-solid WPC-edit-custom-borderRight WPC-edit-borderTop-solid WPC-edit-custom-borderTop WPC-edit-borderBottom-solid WPC-edit-custom-borderBottom&quot; width=&quot;83%&quot;&gt;Switch your working copy from the branch back to TRUNK&lt;br&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td bgcolor=&quot;#ebebeb&quot; class=&quot; WPC-edit-custom-borderTop WPC-edit-custom-borderBottom WPC-edit-borderLeft-solid WPC-edit-custom-borderLeft WPC-edit-custom-borderRight WPC-edit-borderRight-solid WPC-edit-custom-borderRight WPC-edit-borderTop-solid WPC-edit-custom-borderTop WPC-edit-borderBottom-solid WPC-edit-custom-borderBottom&quot; width=&quot;17%&quot;&gt;verify you are in TRUNK&lt;/td&gt;&lt;td class=&quot; WPC-edit-custom-borderTop WPC-edit-custom-borderBottom WPC-edit-custom-borderLeft WPC-edit-borderLeft-solid WPC-edit-custom-borderLeft WPC-edit-borderRight-solid WPC-edit-custom-borderRight WPC-edit-borderTop-solid WPC-edit-custom-borderTop WPC-edit-borderBottom-solid WPC-edit-custom-borderBottom&quot; width=&quot;83%&quot;&gt; verify your working copy says you are in trunk&lt;br&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td bgcolor=&quot;#ebebeb&quot; class=&quot; WPC-edit-custom-borderTop WPC-edit-custom-borderBottom WPC-edit-borderLeft-solid WPC-edit-custom-borderLeft WPC-edit-custom-borderRight WPC-edit-borderRight-solid WPC-edit-custom-borderRight WPC-edit-borderTop-solid WPC-edit-custom-borderTop WPC-edit-borderBottom-solid WPC-edit-custom-borderBottom&quot; width=&quot;17%&quot;&gt;merge BRANCH into working copy&lt;/td&gt;&lt;td class=&quot; WPC-edit-custom-borderTop WPC-edit-custom-borderBottom WPC-edit-custom-borderLeft WPC-edit-borderLeft-solid WPC-edit-custom-borderLeft WPC-edit-borderRight-solid WPC-edit-custom-borderRight WPC-edit-borderTop-solid WPC-edit-custom-borderTop WPC-edit-borderBottom-solid WPC-edit-custom-borderBottom&quot; width=&quot;83%&quot;&gt;merge a range of revisions in the branch into the working copy. the  merge dialog FROM should be the BRANCH url and the revision when the  branch was created, so you don&amp;#39;t go back to the start of time. the  merge dialog TO is the same BRANCH url and would be the head revision,  but you can specify an earlier revision in the branch. &lt;br&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td bgcolor=&quot;#ebebeb&quot; class=&quot; WPC-edit-custom-borderTop WPC-edit-borderLeft-solid WPC-edit-custom-borderLeft WPC-edit-custom-borderRight WPC-edit-borderRight-solid WPC-edit-custom-borderRight WPC-edit-borderTop-solid WPC-edit-custom-borderTop WPC-edit-borderBottom-solid WPC-edit-custom-borderBottom&quot; width=&quot;17%&quot;&gt;commit working to TRUNK&lt;/td&gt;&lt;td class=&quot; WPC-edit-custom-borderTop WPC-edit-custom-borderLeft WPC-edit-borderLeft-solid WPC-edit-custom-borderLeft WPC-edit-borderRight-solid WPC-edit-custom-borderRight WPC-edit-borderTop-solid WPC-edit-custom-borderTop WPC-edit-borderBottom-solid WPC-edit-custom-borderBottom&quot; width=&quot;83%&quot;&gt;manually fix any merge conflicts, test locally, then commit your working  to TRUNK&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br&gt;&lt;h2&gt;Merging From Trunk to Branch&lt;/h2&gt;  This is most generally used for a file or two, though you could do it for an entire folder. Basically move to the Branch, then go to the file(s) you changed, and merge in the TRUNK changes. &lt;br&gt;&lt;br&gt;  NOTE: you don&amp;#39;t have to merge just from the TRUNK, these instructions work if you want to merge from one branch to another. It is simply that we often need to know how to grab a change in the TRUNK and put it into the branch that we want to make a build from.&lt;br&gt;  &lt;br&gt;If you only need to merge one or two files, you can actually specify individual file locations in the from/to fields (rather than the top-level directory which would merge the entire tree). Merging single files can be safer because there could be other changes in the trunk that should not be merged.&lt;br&gt;&lt;br&gt;&lt;table align=&quot;bottom&quot; cellpadding=&quot;3&quot; class=&quot;WPC-edit-style-columns3 WPC-edit-border-none WPC-edit-styleData-color1=%23ebebeb&amp;color2=%23c7c7c7&quot; width=&quot;100%&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor=&quot;#ebebeb&quot; class=&quot; WPC-edit-borderTop-solid WPC-edit-custom-borderTop WPC-edit-custom-borderBottom WPC-edit-borderLeft-solid WPC-edit-custom-borderLeft WPC-edit-custom-borderRight WPC-edit-borderRight-solid WPC-edit-custom-borderRight WPC-edit-borderBottom-solid WPC-edit-custom-borderBottom&quot; width=&quot;18%&quot;&gt;Switch to Branch&lt;/td&gt;&lt;td class=&quot; WPC-edit-borderTop-solid WPC-edit-custom-borderTop WPC-edit-custom-borderBottom WPC-edit-custom-borderLeft WPC-edit-borderLeft-solid WPC-edit-custom-borderLeft WPC-edit-borderRight-solid WPC-edit-custom-borderRight WPC-edit-borderBottom-solid WPC-edit-custom-borderBottom&quot; width=&quot;82%&quot;&gt;Right click your project: &lt;br&gt; &lt;br&gt;and go to Team &amp;gt; Switch: &lt;br&gt; &lt;br&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td bgcolor=&quot;#ebebeb&quot; class=&quot; WPC-edit-custom-borderTop WPC-edit-custom-borderBottom WPC-edit-borderLeft-solid WPC-edit-custom-borderLeft WPC-edit-custom-borderRight WPC-edit-borderRight-solid WPC-edit-custom-borderRight WPC-edit-borderTop-solid WPC-edit-custom-borderTop WPC-edit-borderBottom-solid WPC-edit-custom-borderBottom&quot; width=&quot;18%&quot;&gt;Select Branch&lt;/td&gt;&lt;td class=&quot; WPC-edit-custom-borderTop WPC-edit-custom-borderBottom WPC-edit-custom-borderLeft WPC-edit-borderLeft-solid WPC-edit-custom-borderLeft WPC-edit-borderRight-solid WPC-edit-custom-borderRight WPC-edit-borderTop-solid WPC-edit-custom-borderTop WPC-edit-borderBottom-solid WPC-edit-custom-borderBottom&quot; width=&quot;82%&quot;&gt;Click Browse to search the BRANCHES in the repository:  &lt;br&gt; &lt;br&gt;Here we have selected BETA2.1 Branch:  &lt;br&gt; &lt;br&gt;Click OK&lt;br&gt; &lt;br&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td bgcolor=&quot;#ebebeb&quot; class=&quot; WPC-edit-custom-borderTop WPC-edit-custom-borderBottom WPC-edit-borderLeft-solid WPC-edit-custom-borderLeft WPC-edit-custom-borderRight WPC-edit-borderRight-solid WPC-edit-custom-borderRight WPC-edit-borderTop-solid WPC-edit-custom-borderTop WPC-edit-borderBottom-solid WPC-edit-custom-borderBottom&quot; width=&quot;18%&quot;&gt;Select Merge&lt;/td&gt;&lt;td class=&quot; WPC-edit-custom-borderTop WPC-edit-custom-borderBottom WPC-edit-custom-borderLeft WPC-edit-borderLeft-solid WPC-edit-custom-borderLeft WPC-edit-borderRight-solid WPC-edit-custom-borderRight WPC-edit-borderTop-solid WPC-edit-custom-borderTop WPC-edit-borderBottom-solid WPC-edit-custom-borderBottom&quot; width=&quot;82%&quot;&gt;From the perspective of the file that needs to be updated (either via  the navigator or the editor window), right-click to choose Merge:&lt;br&gt; &lt;br&gt;Click  Browse to search the TRUNK in the repository for the file that you are  replacing: &lt;br&gt; &lt;br&gt;Use the &amp;quot;Show Log&amp;quot; button to find  the From and To revisions:&lt;br&gt; &lt;br&gt; Notice  that I have selected revisions in both cases.&lt;br&gt; &lt;br&gt;Click  OK &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td bgcolor=&quot;#ebebeb&quot; class=&quot; WPC-edit-custom-borderTop WPC-edit-borderLeft-solid WPC-edit-custom-borderLeft WPC-edit-custom-borderRight WPC-edit-borderRight-solid WPC-edit-custom-borderRight WPC-edit-borderTop-solid WPC-edit-custom-borderTop WPC-edit-borderBottom-solid WPC-edit-custom-borderBottom&quot; width=&quot;18%&quot;&gt;Commit the changes&lt;/td&gt;&lt;td class=&quot; WPC-edit-custom-borderTop WPC-edit-custom-borderLeft WPC-edit-borderLeft-solid WPC-edit-custom-borderLeft WPC-edit-borderRight-solid WPC-edit-custom-borderRight WPC-edit-borderTop-solid WPC-edit-custom-borderTop WPC-edit-borderBottom-solid WPC-edit-custom-borderBottom&quot; width=&quot;82%&quot;&gt;Now that you have just merged from the TRUNK to the BRANCH, you need to  commit these changes to the BRANCH itself.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br&gt;&lt;br&gt;&lt;hr size=&quot;1&quot;&gt;&lt;br/&gt;</description></item><item><title>Iterations</title><link>http://technicaldebt.wetpaint.com/page/Iterations</link><author>JonKern</author><guid isPermaLink="false">http://technicaldebt.wetpaint.com/page/Iterations</guid><pubDate>Wed, 08 Sep 2010 13:35:41 CDT</pubDate><description>Whether every two weeks, three weeks, or once a month... The development team will peel off a set of tasks from the top of the &lt;a href=&quot;http://technicaldebt.wetpaint.com/page/Release+Planning&quot; target=&quot;_self&quot;&gt;Release Plan&lt;/a&gt; providing the latest business priorities. &lt;br&gt;&lt;br&gt;  These tasks are then re-evaluated by the developers and deeper sets of subtasks are created to enable a reasonable estimate... that is, if you haven&amp;#39;t yet jettisoned the idea of doing estimates (see &lt;a href=&quot;http://technicaldebt.wetpaint.com/page/Detailed+Estimation+Sucks&quot; target=&quot;_self&quot; title=&quot;Detailed Estimation Sucks&quot;&gt;Detailed Estimation Sucks&lt;/a&gt;).&lt;br&gt;&lt;br&gt;The Iteration Process looks something like this:&lt;br&gt;&lt;br&gt; &lt;br&gt;&lt;br&gt;&lt;h2&gt;Basic Iteration Process&lt;/h2&gt;The Dev team and the Business get together and go through the list of   desired issues.&lt;br&gt;&lt;ul&gt;&lt;li&gt;Assign an issue&lt;/li&gt;&lt;li&gt;Get an estimate from   the developer&lt;/li&gt;&lt;li&gt;Continue through the list of desired issues until   the resources are used up&lt;br&gt;&lt;/li&gt;&lt;li&gt;Modify list of issues/priority  as  needed based on business feedback during this process&lt;/li&gt;&lt;/ul&gt;There is a balancing act between what the business hopes to have done in a given iteration, and what the Dev team says they can accomplish. So, at the outset of the planning process, the Business is armed with their set of priorities, pulling from:&lt;br&gt;&lt;ul&gt;&lt;li&gt;A list of all available issues (not just new features!)&lt;br&gt;&lt;/li&gt;&lt;li&gt;The initial idea of what should be in the current iteration. (This would have been decided during the initial Release Planning session -- typically used to get a rough estimate.)&lt;br&gt;&lt;/li&gt;&lt;li&gt;The &amp;quot;1st in Line&amp;quot; and &amp;quot;2nd In Line&amp;quot; buckets&lt;/li&gt;&lt;li&gt;Your own prioritization scheme&lt;br&gt;&lt;/li&gt;&lt;/ul&gt;NOTE: The Dev team may also have a set of issues they want to work on (from infrastructure/automation tasks, to refactoring). &lt;br&gt;&lt;br&gt;There is often a tug-of-war when it comes to planning an iteration. The Business is going to want the Dev Team to have estimates for their features. The Dev team might have questions regarding details before they can give an estimate. If this is all done in real-time, folks may think it can be a bit wasteful. The Business is listening to the developers banter back and forth about how to implement a feature and what the estimate might be. The developers may feel the need to work out some subtasks before estimating &amp;quot;publicly.&amp;quot;&lt;br&gt;&lt;br&gt;NOTE this section discusses estimation as part of iteration planning. Give it a good long consideration before wasting precious time on detailed estimates. Read more here: &lt;a href=&quot;http://technicaldebt.wetpaint.com/page/Detailed+Estimation+Sucks&quot; target=&quot;_self&quot; title=&quot;Detailed Estimation Sucks&quot;&gt;Detailed  Estimation Sucks&lt;/a&gt;.&lt;br&gt;&lt;br&gt;&lt;h3&gt;Priority&lt;/h3&gt;Another common tug of war is Business Priority. Once the business knows the cost of a feature, they may alter the priority. The Business can compute the Return on Investment (at least from a relative perspective) for a given feature. Feature X that might make a few customers happy that costs 25Z might be prioritized lower than Feature Y that will make many customers happy for only 5Z. Conversely, having Feature X&amp;#39;s few -- but happy -- customers that turn out to be the critical partners that Marketing has groomed, need to be kept happy. So Feature X may win out after all. The simple point is to provide the Business with the &amp;quot;cost&amp;quot; of development and allow the priority to be adjusted.&lt;br&gt;&lt;br&gt;In the early requirements gathering phase, you will hopefully capture this sort of critical knowledge up front should it affect design or release planning. Nonetheless, you can get a Feature X at any point in the product life with, or without warning.&lt;br&gt;&lt;br&gt;If it will make the planning process go more smoothly, you may need to have a &amp;quot;pre-meeting&amp;quot; to do an initial pass at explaining the next set of desired features, and then allowing the Dev team to caucus and come up with some estimates or the need for further discussions about a given complex or large feature. In general, any issue requiring more than 20 hours should be broken down into subtasks -- both for ensuring that the task is well thought out, and to show interim progress.&lt;br&gt;&lt;br&gt;&lt;table align=&quot;bottom&quot; cellpadding=&quot;3&quot; class=&quot;WPC-edit-style-list3 WPC-edit-border-none WPC-edit-styleData-color1=%23ebebeb&amp;color2=%23b0ecf5&quot; height=&quot;75&quot; width=&quot;750&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;right&quot; bgcolor=&quot;#b0ecf5&quot; class=&quot;&quot; width=&quot;14%&quot;&gt; &lt;b&gt;Story Points or Hours?&lt;/b&gt;&lt;/td&gt;&lt;td bgcolor=&quot;#b0ecf5&quot; class=&quot;&quot; width=&quot;86%&quot;&gt;It is a common agile practice to use something called &amp;quot;Story Points&amp;quot; so that your units of measure are abstract and not so readily tied to work hours.&lt;br&gt;I have not tried using story points, but conceptually, whether you estimate an issue as 10h or 2sp and you realize that you generally accomplish about 5h or 2sp per day, you end up in the same place.&lt;br&gt;&lt;br&gt;Mike Cohn has excellent material on all manner of Story Point discussions. Including this &lt;a class=&quot;external&quot; href=&quot;http://technicaldebt.wetpaint.comhttp://blog.mountaingoatsoftware.com/?p=15&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;one&lt;/a&gt; that describes using hours for short-term planning.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br&gt;&lt;h3&gt;Developer Estimation&lt;/h3&gt;The estimates should be made in Ideal Hours. &lt;br&gt;&lt;br&gt;&lt;table align=&quot;bottom&quot; cellpadding=&quot;3&quot; class=&quot;WPC-edit-style-list3 WPC-edit-border-none WPC-edit-styleData-color1=%23ebebeb&amp;color2=%23b0ecf5&quot; height=&quot;75&quot; width=&quot;750&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;right&quot; bgcolor=&quot;#b0ecf5&quot; class=&quot;&quot; width=&quot;14%&quot;&gt; &lt;b&gt;Ideal Hours&lt;/b&gt;&lt;/td&gt;&lt;td bgcolor=&quot;#b0ecf5&quot; class=&quot;&quot; width=&quot;86%&quot;&gt;What the heck does this mean? &lt;br&gt; The &amp;quot;ideal&amp;quot; time is what it should take to do the issue uninterrupted. Since many of these issues requires digging and testing, you have to account for those activities in addition to pure code/sql writing. What you would &lt;b&gt;not&lt;/b&gt; include is time to learn SQL or the tool, or inflate it by the time you spend in the Scrum, etc.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br&gt;Allow them to take on tasks to the tune of:&lt;br&gt;&lt;br&gt;&lt;div align=&quot;center&quot;&gt;&lt;i&gt;Max Developer Hours = (Work hours per iteration * Ideal Factor)&lt;/i&gt; &lt;/div&gt;&lt;br&gt;For example, a two week iteration represents 80 work hours per person. The &lt;b&gt;Ideal Factor&lt;/b&gt; can start out at a rate of 50% to account for design time, scrums, discussion with the business, unit tests, testing, foosball. As the team marches forward, that value can be changed to account for reality.&lt;br&gt;&lt;h3&gt;Estimating Basics&lt;/h3&gt;  This is a skill and some would say an &amp;quot;art&amp;quot; form (I am an overly optimistic estimator). &lt;ul&gt;&lt;li&gt;Use hours (e.g., 5h) for your estimating (not days)&lt;/li&gt;&lt;li&gt;Consider the task estimate based on &amp;quot;Ideal Engineering Hours&amp;quot;&lt;/li&gt;&lt;li&gt;If multiple people need to work on a task, add up the two people&amp;#39;s hours&lt;/li&gt;&lt;li&gt;If the estimate is larger than a couple of days, be skeptical, break it down. (Unless you are one of those rare breeds that have excellent estimating skills.)&lt;br&gt;&lt;/li&gt;&lt;/ul&gt;   &lt;h3&gt;Logging time&lt;/h3&gt;  &lt;ul&gt;&lt;li&gt;Use a timer &amp;ndash; you&amp;#39;d be shocked!&lt;/li&gt;&lt;li&gt;If you help someone else on their task (&amp;gt;15m), you can &amp;quot;Log Work&amp;quot; to their task.&lt;/li&gt;&lt;li&gt;Log your time as you complete it.&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;Milestone Review&lt;/h2&gt;  Following the iteration, remaining -- unfinished -- issues are either moved into the next iteration, or moved out altogether. Then, the team should take pride in demonstrating what they have built. Sometimes it is a code review and a modicum of visible output (maybe tests only). Other times it is a nice demo to the Business, QA Team, etc.&lt;br&gt;  &lt;ul&gt;&lt;li&gt;Every two weeks&lt;/li&gt;&lt;li&gt;Starts with a review of visible features for QA to see&lt;/li&gt;&lt;li&gt;Review leftover tasks and bump to next milestone&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Oops, We Didn&amp;#39;t Finish All Issues!&lt;/h3&gt;That&amp;#39;s okay. Try to improve each iteration. It usually isn&amp;#39;t a huge problem if you missed a few issues (say out of 20 or 30).  If the team is doing their best, what else do you want? Why does &amp;quot;management&amp;quot;  care to hit the number dead-nuts on? BTW: Some people would call those  extra few stories &amp;quot;stretch goals&amp;quot; -- which I hate on so many levels.&lt;br&gt;&lt;br&gt;&lt;hr size=&quot;1&quot;&gt;&lt;br/&gt;</description></item><item><title>Jon's Agile Development Tips</title><link>http://technicaldebt.wetpaint.com/page/Jon%27s+Agile+Development+Tips</link><author>JonKern</author><guid isPermaLink="false">http://technicaldebt.wetpaint.com/page/Jon%27s+Agile+Development+Tips</guid><pubDate>Wed, 08 Sep 2010 13:14:19 CDT</pubDate><description>&lt;table align=&quot;bottom&quot; cellpadding=&quot;3&quot; class=&quot;WPC-edit-style-list4 WPC-edit-border-none WPC-edit-styleData-color1=%23ebebeb&amp;color2=%23f70505&quot; height=&quot;41&quot; width=&quot;422&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;right&quot; bgcolor=&quot;#f70505&quot; class=&quot;&quot; width=&quot;20%&quot;&gt;&lt;font color=&quot;#ffffff&quot;&gt;NOTE:&lt;br&gt;&lt;br&gt;&lt;/font&gt;&lt;/td&gt;&lt;td bgcolor=&quot;#d4d4d4&quot; class=&quot;WPC-edit-custom-bgColor&quot; width=&quot;80%&quot;&gt;This set of pages will take me a while to create. I am going to attempt to post my agile process tips and techniques.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br&gt;&lt;h2&gt;Process Introduction&lt;/h2&gt;Over the years, I have worked with many people and learned from masters and novices alike. Here you will read about a single, simple, slightly variable process with a handful of tenets that seem to routinely work at both getting the project off on the right foot, and providing checks and balances to catch us before/when we inevitably stumble. &lt;br&gt;&lt;br&gt;Each situation is unique -- from the whole business/company culture/dev team culture/problem domain perspective. However, the overall approach to meeting the project head-on is very consistent -- just the details vary.&lt;br&gt;&lt;br&gt;To some readers, this process may seem like &amp;quot;a lot of upfront work.&amp;quot; All I can offer you is my advice against blindly applying some process (agile or not) without using your brain and without collaborating at a mental distance greater than just the coding aspects. There is a lot more to software development than software!&lt;br&gt;&lt;br&gt;Software development of the the kind I have been involved with (and continue to enjoy doing) is always &amp;quot;knowledge work&amp;quot; and never &amp;quot;factory work.&amp;quot; The projects tend to be 6 months to over a year, developing business-critical products and the team/process/culture to go with them. The more you understand about the company&amp;#39;s business drivers (often a &amp;quot;level up&amp;quot; from your immediate project&amp;#39;s needs), the more that you can provide innovative and explosive solutions to provide business value.&lt;br&gt;&lt;br&gt;The process described herein is for just such type of projects.&lt;br&gt;&lt;h2&gt;Background&lt;/h2&gt;A conundrum of Agile Development to many laypeople is that we trade in seemingly precise process (sequential steps, roles, Gantt charts, lots of non-software-based evidence of activity) in the name of getting to production faster with higher quality -- yet mysteriously with seemingly &lt;i&gt;less&lt;/i&gt; process.&lt;br&gt;&lt;br&gt;The reaction of naive development teams is to &amp;quot;run wild&amp;quot; and do a poor job of delivering a professional solution and claim it is &amp;quot;agile.&amp;quot; This gives agile a bad name -- at least to those who do not understand that software development is mostly about the &lt;b&gt;quality and experience of the people&lt;/b&gt; and not the name of the &lt;b&gt;process&lt;/b&gt; they followed.&lt;br&gt;&lt;br&gt;Agile requires a keen understanding of sometimes subtle relationships between cause and effect in software development. This is true in many facets of software development: &lt;br&gt;&lt;ul&gt;&lt;li&gt;people&amp;#39;s interactions&lt;/li&gt;&lt;li&gt;frequent, tangible, working results&lt;/li&gt;&lt;li&gt;involving the customer more often&lt;/li&gt;&lt;li&gt;being able to embrace change&lt;br&gt;&lt;/li&gt;&lt;/ul&gt;While some agile techniques -- if blindly adhered to by a newbie team -- can help provide clear feedback, there is still a challenge in our industry to identify the shades of quality. For example, there may be three shades of an architecture used to solve the same problem. &lt;br&gt;&lt;ul&gt;&lt;li&gt;All three approaches work. &lt;br&gt;&lt;/li&gt;&lt;li&gt;On the surface, the user would not be able to see any difference. &lt;br&gt;&lt;/li&gt;&lt;li&gt;All three approaches require about the same time to arrive at. &lt;br&gt;&lt;/li&gt;&lt;/ul&gt;A newbie developer came up with the lowest ranking architecture. A newbie might not be able to decipher the differences between the three in terms of the near- or long-term benefit. Or, they may tacitly understand what you might point out to them, but not really deeply embrace the reasoning because they just haven&amp;#39;t got the amount of experience to appreciate the differences. A developer with more experience might recognize why the middle architecture is better than the worst, but may not be able to come up with the best architecture due to lack of experience (or skill). However, a skilled senior architect will understand the ramifications -- both near- and long-term -- behind choosing the best architecture. You just can&amp;#39;t deny the value of working with as highly-skilled people as you can find for every aspect of the team. Ten highly skilled people with good discipline and process can do the work of 100 mediocre developers and do a better quality job on top of it. Sounds controversial? Hardly -- if you have good experience in our industry for any length of time.&lt;br&gt;&lt;h2&gt;Success Factors&lt;/h2&gt;  Some mantras that we choose to work by:&lt;br&gt;&lt;ul&gt;&lt;li&gt;Always be visible 	&lt;ul&gt;&lt;li&gt;We work in a completely transparent way&lt;/li&gt;&lt;li&gt;We are one, open team, from developer to stakeholder to gold owner&lt;br&gt;&lt;/li&gt;&lt;li&gt;Knowledge transfer is on an as-frequent basis as needed&lt;/li&gt;&lt;li&gt;We tend to document in a natural, cost-effective manner&lt;br&gt;&lt;/li&gt;&lt;/ul&gt; 	&lt;/li&gt;&lt;li&gt;Business vision is critical &amp;amp; necessary driver 	&lt;ul&gt;&lt;li&gt;Development is to support marketing vision and business needs&lt;/li&gt;&lt;li&gt;The closer we work with actual clients, the better the results&lt;/li&gt;&lt;li&gt;Technology and business works together in a give and take&lt;/li&gt;&lt;li&gt;We work our magic to make the business dreams a reality&lt;br&gt;&lt;/li&gt;&lt;/ul&gt; 	&lt;/li&gt;&lt;li&gt;Close the &amp;quot;gaps&amp;quot; to reduce risks: 	&lt;ul&gt;&lt;li&gt;...of building the wrong thing by demonstrating working software in a matter of weeks, not months or years&lt;/li&gt;&lt;li&gt;...of being non-performant by testing early and continuously&lt;/li&gt;&lt;li&gt;...of being brittle by ensuring our code has appropriate level of tests&lt;br&gt;&lt;/li&gt;&lt;li&gt;...of deployment by duplicating or simulating the environment(s)&lt;/li&gt;&lt;/ul&gt; 	&lt;/li&gt;&lt;/ul&gt;   &lt;h2&gt;General Philosophy&lt;/h2&gt;  Our job is to do the best we can at shepherding the company&amp;#39;s assets and resources, and the folks being assigned to the software product development.&lt;br&gt;&lt;br&gt;&lt;b&gt;The basic process:&lt;/b&gt; &lt;ul&gt;&lt;li&gt;Building features in an iterative manner&lt;/li&gt;&lt;li&gt;Having a range of tools to ensure efficiency of development and testing&lt;/li&gt;&lt;li&gt;Evaluation by users after each iteration&lt;/li&gt;&lt;li&gt;Take the reviews/critiques back to the product development team&lt;/li&gt;&lt;li&gt;Be prepared to throw some things away and redesign/rebuild&lt;/li&gt;&lt;li&gt;Repeat as needed&lt;/li&gt;&lt;/ul&gt;   This will lead to a quality product.&lt;br&gt;&lt;br&gt;&lt;b&gt;Some typical rules of thumb:&lt;/b&gt; &lt;ul&gt;&lt;li&gt;Do not do any one aspect to excess, keep things reasonably in sync.&lt;/li&gt;&lt;li&gt;The only truth: running (quality) software demonstrating feature completion.&lt;/li&gt;&lt;li&gt;Client specifies features, dev team dictates cost and schedule.&lt;/li&gt;&lt;li&gt;It is far better to collaborate than to engage in antagonistic &amp;quot;detailed contracts&amp;quot;&lt;/li&gt;&lt;li&gt;Strive to be in a state where the software can be built and running at a moment&amp;#39;s notice (best to have multiple environments)&lt;br&gt;&lt;/li&gt;&lt;li&gt;Tons of detailed documentation and requirements can be wasteful; keeping everything at the conversation level can be short-sighted&lt;br&gt;&lt;/li&gt;&lt;li&gt;Lots of fine-grained project plans for 5 years out is also wasteful&lt;/li&gt;&lt;/ul&gt;   &lt;br&gt;&lt;table align=&quot;center&quot; cellpadding=&quot;5&quot; cellspacing=&quot;8&quot; class=&quot;WPC-edit-style-border1 WPC-edit-border-none WPC-edit-styleData-color1=%23ebebeb&amp;color2=%23c7c7c7&quot; height=&quot;66&quot; width=&quot;696&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;                        WPC-edit-borderTop-solid WPC-edit-borderLeft-solid WPC-edit-borderBottom-solid&quot; width=&quot;5%&quot;&gt; &lt;/td&gt;&lt;td class=&quot;                        WPC-edit-borderTop-solid WPC-edit-borderBottom-solid WPC-edit-borderRight-solid&quot; width=&quot;95%&quot;&gt;&lt;b&gt;Do Not Get Blocked&lt;/b&gt;&lt;br&gt; You must not allow yourself to be blocked. That is, &amp;quot;stuck&amp;quot; from achieving success due to external forces. Bring this to the team&amp;#39;s attention immediately as part of an email to the project list, or in the &lt;a href=&quot;http://technicaldebt.wetpaint.com/page/Development+Process&quot; target=&quot;_self&quot;&gt;daily meeting&lt;/a&gt; or on IRC.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;  &lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;hr size=&quot;1&quot;&gt;&lt;br/&gt;</description></item><item><title>Consistency is a Quality Unto Itself</title><link>http://technicaldebt.wetpaint.com/page/Consistency+is+a+Quality+Unto+Itself</link><author>JonKern</author><guid isPermaLink="false">http://technicaldebt.wetpaint.com/page/Consistency+is+a+Quality+Unto+Itself</guid><pubDate>Wed, 08 Sep 2010 11:44:53 CDT</pubDate><description>&lt;h2&gt;Background&lt;/h2&gt;Whether we are talking about code conventions, UI, class/table names, or even sample data, consistency is a key quality.&lt;br&gt;&lt;br&gt;So much so, that I would rather have a mediocre solution (say for example in the area of data management) across 5 areas of the application than 5 different solutions. Why? Because when you have consistency, folks can recognize each item as being of the same general nature. Also, it is easier to improve and refactor a consistent solution in 5 places than it is to find and fix 5 different approaches.&lt;br&gt;&lt;h2&gt;The Current Solution&lt;/h2&gt;Here is a really dumb, yet illustrative, situation. In our project, we have 3 very distinct environments:&lt;br&gt;&lt;ul&gt;&lt;li&gt;DEV&lt;/li&gt;&lt;li&gt;TEST&lt;/li&gt;&lt;li&gt;PROD&lt;br&gt;&lt;/li&gt;&lt;/ul&gt;Pretty obvious by their names alone, that that these environments serve different purposes. An important part of the application is role-based behavior of the logged-in user. When the user logs in, a set of roles/privileges is retrieved from the User database. To make it easy for developers to work and test as different users, we set up a standard set of user accounts. Standard across the environments, or so I thought.&lt;br&gt;&lt;br&gt;&lt;table align=&quot;bottom&quot; cellpadding=&quot;3&quot; class=&quot;WPC-edit-style-columns2 WPC-edit-border-cols WPC-edit-styleData-color1=%23ebebeb&amp;color2=%23c7c7c7&quot; height=&quot;117&quot; width=&quot;203&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;center&quot; bgcolor=&quot;#ebebeb&quot; class=&quot;&quot; width=&quot;47%&quot;&gt;&lt;b&gt;USER NAME&lt;br&gt;&lt;/b&gt;&lt;/td&gt;&lt;td align=&quot;center&quot; class=&quot;&quot; width=&quot;53%&quot;&gt;&lt;b&gt;ROLE&lt;br&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td bgcolor=&quot;#ebebeb&quot; class=&quot;&quot; width=&quot;47%&quot;&gt;mr_author&lt;/td&gt;&lt;td class=&quot;&quot; width=&quot;53%&quot;&gt;Author&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td bgcolor=&quot;#ebebeb&quot; class=&quot;&quot; width=&quot;47%&quot;&gt;mr_reader&lt;/td&gt;&lt;td class=&quot;&quot; width=&quot;53%&quot;&gt;reader&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td bgcolor=&quot;#ebebeb&quot; class=&quot;&quot; width=&quot;47%&quot;&gt;mr_admin&lt;/td&gt;&lt;td class=&quot;&quot; width=&quot;53%&quot;&gt;Admin&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td bgcolor=&quot;#ebebeb&quot; class=&quot;&quot; width=&quot;47%&quot;&gt;mr_csr&lt;/td&gt;&lt;td class=&quot;&quot; width=&quot;53%&quot;&gt;Support&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br&gt;&lt;h2&gt;Problems&lt;/h2&gt;It all started out by claims of bugs being encountered. Sometimes in PROD... sometimes in TEST... and by different reporters using different logins and reporters using the same logins. Oddly enough, the bugs were against previously-tested -- and passed -- features or bug fixes. It got to the point of absurdity. Could our development team be that bad? I know many of the team members are new to the rigorous development practices associated with a public software product. But the reports were contradictory. The bug reports didn&amp;#39;t fly with the level of maturity that I know the team had gotten to by this time in our project.&lt;br&gt;&lt;br&gt;So, I began to look into whether gravity was still practicing it&amp;#39;s basic vertical stance. Turns out it was, of course. The real culprit ended up being inconsistency in how the test logins were set up. &lt;br&gt;&lt;br&gt;&lt;table align=&quot;bottom&quot; cellpadding=&quot;3&quot; class=&quot;WPC-edit-style-columns2 WPC-edit-border-cols WPC-edit-styleData-color1=%23ebebeb&amp;color2=%23c7c7c7&quot; width=&quot;600&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;center&quot; bgcolor=&quot;#ebebeb&quot; class=&quot;&quot; width=&quot;21%&quot;&gt;&lt;b&gt;USER NAME&lt;br&gt;       &lt;/b&gt;&lt;/td&gt;&lt;td align=&quot;center&quot; class=&quot;&quot; width=&quot;3%&quot;&gt;&lt;b&gt;ROLE-TEST&lt;br&gt;       &lt;/b&gt;&lt;/td&gt;&lt;td align=&quot;center&quot; bgcolor=&quot;#ebebeb&quot; class=&quot;&quot; width=&quot;20%&quot;&gt;&lt;b&gt;EMAIL-TEST&lt;/b&gt;&lt;/td&gt;&lt;td align=&quot;center&quot; class=&quot;&quot; width=&quot;23%&quot;&gt;&lt;b&gt;ROLE-PROD&lt;/b&gt;&lt;/td&gt;&lt;td align=&quot;center&quot; bgcolor=&quot;#ebebeb&quot; class=&quot;&quot; width=&quot;31%&quot;&gt;&lt;b&gt;EMAIL-PROD&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td bgcolor=&quot;#ebebeb&quot; class=&quot;&quot; width=&quot;21%&quot;&gt;mr_author&lt;/td&gt;&lt;td class=&quot;&quot; width=&quot;3%&quot;&gt;Author&lt;/td&gt;&lt;td bgcolor=&quot;#ebebeb&quot; class=&quot;&quot; width=&quot;20%&quot;&gt;MR_AUTHOR &lt;br&gt;mr_author@domn.com&lt;/td&gt;&lt;td class=&quot;&quot; width=&quot;23%&quot;&gt;Author&lt;/td&gt;&lt;td bgcolor=&quot;#ebebeb&quot; class=&quot;&quot; width=&quot;31%&quot;&gt;&lt;font color=&quot;#ff0000&quot;&gt;MR AUTHOR&lt;/font&gt;&lt;br&gt;mr_author@domn.com&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td bgcolor=&quot;#ebebeb&quot; class=&quot;&quot; width=&quot;21%&quot;&gt;mr_reader&lt;/td&gt;&lt;td class=&quot;&quot; width=&quot;3%&quot;&gt;Reader&lt;/td&gt;&lt;td bgcolor=&quot;#ebebeb&quot; class=&quot;&quot; width=&quot;20%&quot;&gt;MR_READER&lt;br&gt;mr_reader@domn.com&lt;/td&gt;&lt;td class=&quot;&quot; width=&quot;23%&quot;&gt;Reader, &lt;font color=&quot;#ff0000&quot;&gt;Author&lt;/font&gt;&lt;/td&gt;&lt;td bgcolor=&quot;#ebebeb&quot; class=&quot;&quot; width=&quot;31%&quot;&gt;MR_READER&lt;br&gt;mr_reader@domn.com&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td bgcolor=&quot;#ebebeb&quot; class=&quot;&quot; width=&quot;21%&quot;&gt;mr_admin&lt;/td&gt;&lt;td class=&quot;&quot; width=&quot;3%&quot;&gt;Admin&lt;/td&gt;&lt;td bgcolor=&quot;#ebebeb&quot; class=&quot;&quot; width=&quot;20%&quot;&gt;MR_ADMIN&lt;br&gt;mr_admin@domn.com&lt;/td&gt;&lt;td class=&quot;&quot; width=&quot;23%&quot;&gt;Admin, &lt;font color=&quot;#ff0000&quot;&gt;Author&lt;/font&gt;&lt;/td&gt;&lt;td bgcolor=&quot;#ebebeb&quot; class=&quot;&quot; width=&quot;31%&quot;&gt;&lt;font color=&quot;#ff0000&quot;&gt;MRADMIN&lt;/font&gt;&lt;br&gt;mr_admin@domn.com&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td bgcolor=&quot;#ebebeb&quot; class=&quot;&quot; width=&quot;21%&quot;&gt;mr_csr&lt;/td&gt;&lt;td class=&quot;&quot; width=&quot;3%&quot;&gt;Support&lt;/td&gt;&lt;td bgcolor=&quot;#ebebeb&quot; class=&quot;&quot; width=&quot;20%&quot;&gt;MRCUSTSV&lt;br&gt;mr_cs@domn2.com&lt;/td&gt;&lt;td class=&quot;&quot; width=&quot;23%&quot;&gt;Support, &lt;font color=&quot;#ff0000&quot;&gt;Author&lt;/font&gt;&lt;/td&gt;&lt;td bgcolor=&quot;#ebebeb&quot; class=&quot;&quot; width=&quot;31%&quot;&gt;&lt;font color=&quot;#ff0000&quot;&gt;MRHDESK&lt;/font&gt;&lt;br&gt;&lt;font color=&quot;#ff0000&quot;&gt;mr_helpdesk&lt;/font&gt;@&lt;font color=&quot;#ff0000&quot;&gt;domn2&lt;/font&gt;.com&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br&gt;So, somehow, the users were set up &lt;font color=&quot;#ff0000&quot;&gt;differently&lt;/font&gt; on the different environments.&lt;br&gt;&lt;ul&gt;&lt;li&gt;Different user names&lt;/li&gt;&lt;li&gt;Different emails&lt;/li&gt;&lt;li&gt;Different roles&lt;br&gt;&lt;/li&gt;&lt;/ul&gt;What was even worse was the emails of these test logins was also inconsistent. This simply exacerbated the situation when attempting to easily find all of the test login users -- so I could check the assigned roles. When I initially specified setting up these special logins, I kept it very simple and clear -- and consistent. The user name should be the basic role name itself, the emails were ostensibly mr_role@domain.com. Unfortunately, when the users were added to the second and third environments, the same approach was not followed, as you can see in the table above. For example, the mr_csr login for the support role was entered as mr_csr@domn.com on TEST, but &lt;font color=&quot;#ff0000&quot;&gt;mr_helpdesk&lt;/font&gt;@&lt;font color=&quot;#ff0000&quot;&gt;domn2&lt;/font&gt;.com on PROD. Thus, making the SQL query that was attempting to find the test login users not work properly. Maddening, I tell you!&lt;br&gt;&lt;br&gt;&lt;h2&gt;The Cost&lt;/h2&gt;It might seem trivial, these differences. Does a user name really matter if it had an underscore or not? Does a mildly different email name and email domain truly matter? &lt;br&gt;YES! When you are trying to find the data across multiple environments and databases, trivial and subtle differences make the quest maddeningly challenging -- and for no real good reason other than inattention to a simple detail. It truly costs no more effort (or at most very little additional effort) to do this sort of thing the &amp;quot;right way&amp;quot; &lt;b&gt;up front&lt;/b&gt; versus the sloppy way. Yet the downstream penalties of doing it the sloppy way can be monumental:&lt;br&gt;&lt;ul&gt;&lt;li&gt;Bug reports that were not repeatable and that made no sense&lt;/li&gt;&lt;li&gt;Developers looking in the wrong places for the cause of the bug&lt;/li&gt;&lt;li&gt;A sense of despair in that inconsistent, non-repeatable behavior on the DEV &amp;amp; TEST boxes made it seem like we had no control.&lt;/li&gt;&lt;li&gt;An expensive goose chase made more costly due to the challenges in simply trying to find the test logins that we created for our own use.&lt;br&gt;&lt;/li&gt;&lt;li&gt;And we had to manually and painstakingly fix the errors on all inconsistent platforms.&lt;br&gt;&lt;/li&gt;&lt;/ul&gt; &lt;h2&gt;Suggestions&lt;/h2&gt;Because there was a &amp;quot;User Admin&amp;quot; panel in another part of a related application, the developer chose to do this work manually each time.&lt;br&gt;&lt;br&gt;A better approach would have been to have followed how we set up data in every other case. That is, by using written SQL insert code files that we could run on any environment to achieve consistency.&lt;br&gt;&lt;h2&gt;When Might This Be Appropriate?&lt;/h2&gt;I am not sure, but I do not think that inconsistency is ever a good idea. (Unless of course you are purposefully trying to stymie fellow developers and testers with oh-so-subtle, barely detectable, differences.&lt;br&gt;&lt;br&gt;&lt;hr size=&quot;1&quot;&gt;&lt;br/&gt;</description></item><item><title>When Fancy Hurts Quality and Maintainability</title><link>http://technicaldebt.wetpaint.com/page/When+Fancy+Hurts+Quality+and+Maintainability</link><author>JonKern</author><guid isPermaLink="false">http://technicaldebt.wetpaint.com/page/When+Fancy+Hurts+Quality+and+Maintainability</guid><pubDate>Wed, 08 Sep 2010 11:44:09 CDT</pubDate><description>&lt;br&gt; 			&lt;h2&gt;Background&lt;/h2&gt;Our application tangentially had to deal with a prior design around Users and Roles that was in place for an existing portal. Our online application also needed users and roles, and the customer wanted to have &amp;quot;single sign-on&amp;quot; which meant they would provide the User management with their existing tables.&lt;br&gt;&lt;br&gt;&lt;h2&gt;Solution&lt;/h2&gt;Here is a model that we ran into to store Users and their Roles:&lt;br&gt; &lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;blockquote&gt;&lt;table align=&quot;right&quot; cellpadding=&quot;3&quot; class=&quot;WPC-edit-style-list7 WPC-edit-border-none WPC-edit-styleData-color1=%23ebebeb&amp;color2=%23c7c7c7&quot; height=&quot;177&quot; width=&quot;298&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;center&quot; bgcolor=&quot;#c7c7c7&quot; class=&quot;WPC-edit-borderTop-solid WPC-edit-borderBottom-solid2px WPC-edit-borderLeft-solid&quot; width=&quot;41%&quot;&gt;&lt;b&gt;ATTR_NAME&lt;/b&gt;&lt;/td&gt;&lt;td align=&quot;center&quot; bgcolor=&quot;#c7c7c7&quot; class=&quot;WPC-edit-borderTop-solid WPC-edit-borderBottom-solid2px WPC-edit-borderRight-solid&quot; width=&quot;59%&quot;&gt;&lt;b&gt;ATTR_DESC&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td bgcolor=&quot;#ebebeb&quot; class=&quot;WPC-edit-borderTop-solid2px WPC-edit-borderLeft-solid&quot; width=&quot;41%&quot;&gt;FIRST_NAME&lt;/td&gt;&lt;td bgcolor=&quot;#ebebeb&quot; class=&quot;WPC-edit-borderTop-solid2px WPC-edit-borderRight-solid&quot; width=&quot;59%&quot;&gt;User&amp;#39;s First name&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;WPC-edit-borderLeft-solid&quot; width=&quot;41%&quot;&gt;LAST_NAME&lt;/td&gt;&lt;td class=&quot;WPC-edit-borderRight-solid&quot; width=&quot;59%&quot;&gt;User&amp;#39;s Last name&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td bgcolor=&quot;#ebebeb&quot; class=&quot;WPC-edit-borderLeft-solid&quot; width=&quot;41%&quot;&gt;USER_EMAIL&lt;/td&gt;&lt;td bgcolor=&quot;#ebebeb&quot; class=&quot;WPC-edit-borderRight-solid&quot; width=&quot;59%&quot;&gt;User&amp;#39;s Email&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;WPC-edit-borderLeft-solid&quot; width=&quot;41%&quot;&gt;CARBON_COPY&lt;/td&gt;&lt;td class=&quot;WPC-edit-borderRight-solid&quot; width=&quot;59%&quot;&gt;Carbon Copy for email&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td bgcolor=&quot;#ebebeb&quot; class=&quot;WPC-edit-borderLeft-solid WPC-edit-borderBottom-solid&quot; width=&quot;41%&quot;&gt;BLIND_COPY&lt;/td&gt;&lt;td bgcolor=&quot;#ebebeb&quot; class=&quot;WPC-edit-borderBottom-solid WPC-edit-borderRight-solid&quot; width=&quot;59%&quot;&gt;Blind Carbon Copy for email&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/blockquote&gt;It is important to note that User attributes hold data like shown in this table:&lt;br&gt;&lt;br&gt;The developers were clever in that you could add new attributes to a User without requiring the main USERS table to change.&lt;br&gt;&lt;br&gt;However, there are many, many, side effects to this solution.&lt;br&gt;&lt;h2&gt;Problems&lt;/h2&gt;&lt;b&gt;What&amp;#39;s In a Domain?&lt;br&gt;&lt;/b&gt;Okay, since when are first and last names not core attributes of a User object?&lt;br&gt;&lt;br&gt;&lt;b&gt;Email&lt;/b&gt;&lt;br&gt;&lt;br&gt;Note how the _USERS table has an attribute called &amp;quot;EMAIL&amp;quot;. Unfortunately, the Email that the system cares about is found solely as a USER_ATTRIB. To get the user&amp;#39;s email, you have to JOIN tables to find *IF* there is an email for the user.&lt;br&gt;&lt;br&gt;&lt;blockquote&gt;&lt;font face=&quot;Courier&quot;&gt;select&lt;br&gt; bu.user_id &amp;quot;ID&amp;quot;, bu.user_name &amp;quot;Name&amp;quot;, bua.attr_value as &amp;quot;Login Email&amp;quot;,&lt;br&gt; br.role_name as &amp;quot;Role&amp;quot;, bu.user_desc &amp;quot;Description&amp;quot;&lt;br&gt;from&lt;br&gt; bus_users bu, bus_roles br, bus_user_roles bur, bus_attrib ba, bus_user_attrib bua&lt;br&gt;where bu.user_id = bur.user_id&lt;br&gt; and bur.role_id = br.role_id and bu.user_id(+) = bua.user_id&lt;br&gt; and bua.attr_id(+) = ba.attr_id and ba.attr_name in (&amp;#39;USER_EMAIL&amp;#39;)&lt;br&gt;order by bu.user_name;&lt;br&gt;&lt;/font&gt;&lt;br&gt;&lt;/blockquote&gt;Just try getting the First name, Last Name, and Email for a given User. ARRGGHHHH!&lt;br&gt;&lt;br&gt;&lt;blockquote&gt;&lt;font face=&quot;Courier&quot;&gt; (select lbua.attr_value from bus_users lbu, bus_user_attrib lbua, bus_attrib lba &lt;br&gt; WHERE lba.attr_name in (&amp;#39;FIRST_NAME&amp;#39;) and lbu.user_id(+) = lbua.user_id &lt;br&gt; and lbua.attr_id(+) = lba.attr_id and lbu.user_id=bu.user_id&lt;br&gt; ) || &amp;#39; &amp;#39; ||&lt;br&gt; (select lbua.attr_value from bus_users lbu, bus_user_attrib lbua, bus_attrib lba &lt;br&gt; WHERE lba.attr_name in (&amp;#39;LAST_NAME&amp;#39;) and lbu.user_id(+) = lbua.user_id &lt;br&gt; and lbua.attr_id(+) = lba.attr_id and lbu.user_id=bu.user_id&lt;br&gt; ) as &amp;quot;Name&amp;quot;&lt;/font&gt;&lt;br&gt;&lt;/blockquote&gt;&lt;br&gt;Now maybe there are better ways to grab the full data that reflects a user, but all I can say is that separating out core domain attributes like name and email into record-based data into a joined table is overkill.&lt;br&gt;&lt;br&gt;Another problem arises in that you have to try all outer joins... you have no idea if data exists for these various user_attributes.&lt;br&gt;&lt;br&gt;&lt;b&gt;Two Emails&lt;br&gt;&lt;/b&gt;Since there are two emails, how are new developers supposed to know which one to use?&lt;br&gt;&lt;br&gt;It looks as if the original User object was extended to accommodate new attributes -- like first and last name and email.&lt;br&gt;&lt;br&gt;An effort should have been made to eliminate the no-longer-needed USER.EMAIL column. Leaving multiple solutions for EMAIL can lead only to confusion and mistakes.&lt;br&gt;&lt;br&gt;&lt;b&gt;Plurals&lt;/b&gt;&lt;br&gt;It should go without saying, that a Class name or a Table name should rarely involve a plural.&lt;br&gt;&lt;br&gt;USERS is a bad name. The name should be USER. The plural comes when we have multiple records or multiple objects.&lt;br&gt;&lt;br&gt;&lt;b&gt;Turning SQL on Its Ear&lt;/b&gt;&lt;br&gt;&lt;br&gt;Can you say slow performance and wacky SQL?&lt;br&gt;&lt;br&gt;SQL normally performs well when you add domain properties as columns, and instances as records.&lt;br&gt;&lt;br&gt;By placing individual property data as records, it basically ruins the SQL optimization.&lt;br&gt;&lt;br&gt;In addition, the Users in the database did not all have EMAIL as attributes. I was given a simple sql query to look up users. All seemed well enough, until I was trying to find a new user just added by an Admin. No luck. So, after a bit of frustration, I tried to look just in the core USERS table for the new user (BTW: USER_NAME is limited to 8 measly characters). So then I discovered that I had to do an OUTER join to allow for the case where the EMAIL may not be present.&lt;br&gt;&lt;br&gt;Oddly enough, the same developer that gave me this SQL, had used it in our app&amp;#39;s code. Guess what? Some functionality of the App did not work right for some users. Go figure. &lt;br&gt;&lt;br&gt;The app in which this data design exists has horrid performance whenever the code we are working on has to touch this set of tables. Even doing direct queries takes a long time.&lt;br&gt;&lt;h2&gt;Suggestions&lt;/h2&gt;Instead of making the extensible &amp;quot;User Attributes&amp;quot; cover core domain properties that are needed in many parts of the apps, properties like first and last name should be directly added to the User table. If you need to add different emails, then create an Email table and include Email Types (Primary, CC, BCC, Forward, etc.). Then a User can have 1..* Email. &lt;br&gt;&lt;br&gt;Also, in a more object-oriented solution -- were these classes and not tables -- you can more easily collect such loosely-defined properties on the fly.&lt;br&gt;&lt;h2&gt;When Might This Be Appropriate?&lt;/h2&gt;In the case where you need to allow the user to extend and customize properties, &amp;quot;User Defined Types/Attributes&amp;quot; can be a handy technique. The alternative would be to add columns like &amp;quot;CustomProperty_1&amp;quot;, &amp;quot;CustomProperty_2&amp;quot;, &amp;quot;CustomProperty_3&amp;quot;, etc. While this is more performant, you still need to allow the user to provide their custom &amp;quot;meaning&amp;quot; to the custom property, and it is limited to however many dummy columns you added to the table. Not to mention what to do if you need multiple data types (numbers, dates, text).&lt;br&gt;&lt;br&gt;&lt;hr size=&quot;1&quot;&gt;&lt;br/&gt;</description></item><item><title>Calendar Date Select</title><link>http://technicaldebt.wetpaint.com/page/Calendar+Date+Select</link><author>JonKern</author><guid isPermaLink="false">http://technicaldebt.wetpaint.com/page/Calendar+Date+Select</guid><pubDate>Tue, 07 Sep 2010 10:10:05 CDT</pubDate><description>Here&amp;#39;s a quick guide to getting started with &lt;a class=&quot;external&quot; href=&quot;http://technicaldebt.wetpaint.comhttp://github.com/timcharper/calendar_date_select&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Calendar Date Select&lt;/a&gt; gem from Tim Harper, et al.&lt;br&gt;&lt;br&gt;Dates in forms can suck when using the standard f.date_select. Consider the following:&lt;br&gt;&lt;blockquote&gt;&lt;b&gt;Model&lt;/b&gt;:&lt;br&gt;&lt;font face=&quot;Courier&quot;&gt;class RegistrationSetup&lt;/font&gt;&lt;br&gt;&lt;blockquote&gt;&lt;font face=&quot;Courier&quot;&gt; include MongoMapper::Document&lt;/font&gt;&lt;br&gt;&lt;font face=&quot;Courier&quot;&gt; key :title, String, :required =&amp;gt; true&lt;/font&gt;&lt;br&gt;&lt;font face=&quot;Courier&quot;&gt; key :open, Date&lt;/font&gt;&lt;br&gt;&lt;font face=&quot;Courier&quot;&gt; key :close, Date&lt;/font&gt;&lt;br&gt;&lt;/blockquote&gt;&lt;font face=&quot;Courier&quot;&gt;end&lt;/font&gt;&lt;br&gt;&lt;/blockquote&gt;And a typical generated view with &amp;quot;date_select:&amp;quot;&lt;br&gt;&lt;blockquote&gt;&lt;b&gt;View&lt;/b&gt;:&lt;br&gt;&lt;font face=&quot;Courier&quot;&gt;&amp;lt;p&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;blockquote&gt;&lt;font face=&quot;Courier&quot;&gt;  &amp;lt;%= f.label :from %&amp;gt;&amp;lt;br /&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;font face=&quot;Courier&quot;&gt;  &amp;lt;%= f.date_select :from %&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;/blockquote&gt;&lt;font face=&quot;Courier&quot;&gt; &amp;lt;/p&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;/blockquote&gt;&lt;font face=&quot;Courier&quot;&gt; &lt;/font&gt;&lt;br&gt;This results in 3 spinners:&lt;br&gt;&lt;blockquote&gt; &lt;br&gt;&lt;/blockquote&gt;The object save fails unless you deal with the date chunking. In addition the use of 3 spinners can be a bit laborious for the user. Naturally, in the controller, we could reassemble the constituent date parts into a Date... Blech. I&amp;#39;m too lazy for that. Plus I want a more modern date selector!&lt;br&gt;&lt;br&gt;&lt;b&gt;A pop-up calendar is a better way&lt;/b&gt;!&lt;br&gt;&lt;br&gt;Here&amp;#39;s a way that I found to use the calendar_date_select gem (see &lt;a class=&quot;external&quot; href=&quot;http://technicaldebt.wetpaint.comhttp://github.com/timcharper/calendar_date_select&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;)&lt;br&gt;&lt;br&gt;&lt;b&gt;Step 1&lt;/b&gt;. Install: &lt;br&gt;&lt;blockquote&gt;&lt;font face=&quot;Courier&quot;&gt; sudo gem install calendar_date_select&lt;/font&gt;&lt;br&gt;&lt;/blockquote&gt;&lt;br&gt;&lt;b&gt;Step 2&lt;/b&gt;. Get code from here: http://github.com/timcharper/calendar_date_select/downloads/&lt;br&gt;&lt;ul&gt;&lt;li&gt;unzip the download somewhere&lt;/li&gt;&lt;li&gt;transfer the appropriate files into your project&amp;#39;s directories as follows:&lt;br&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;public/images&lt;/li&gt;&lt;li&gt;public/javascripts&lt;/li&gt;&lt;li&gt;public/stylesheets directories&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;put the stylesheets you want (I just copied them all) into &lt;/li&gt;&lt;ul&gt;&lt;li&gt;public/stylesheets&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;br&gt;&lt;b&gt;Step 3&lt;/b&gt;. Add to layout/application.html.erb&lt;br&gt;&lt;blockquote&gt;&lt;font face=&quot;Courier&quot;&gt; &amp;lt;%= javascript_include_tag :defaults %&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;font face=&quot;Courier&quot;&gt; &amp;lt;%= calendar_date_select_includes %&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;/blockquote&gt;&lt;br&gt;&lt;b&gt;Step 4&lt;/b&gt;. Add to environment.rb:&lt;br&gt;&lt;blockquote&gt;&lt;font face=&quot;Courier&quot;&gt; config.gem &amp;quot;calendar_date_select&amp;quot;&lt;/font&gt;&lt;br&gt;&lt;/blockquote&gt;&lt;br&gt;&lt;b&gt;Step 5&lt;/b&gt;. Add to your UI; e.g., _form.html.erb&lt;br&gt;&lt;blockquote&gt;&lt;font face=&quot;Courier&quot;&gt;&amp;lt;div id=&amp;quot;calendar&amp;quot;&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;blockquote&gt;&lt;font face=&quot;Courier&quot;&gt; &amp;lt;p&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;blockquote&gt;&lt;font face=&quot;Courier&quot;&gt; &amp;lt;%#= calendar_date_select_tag &amp;quot;e_date&amp;quot;, Date.today, :embedded =&amp;gt; true, :year_range =&amp;gt; 0.years.ago..1.years.from_now %&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;font face=&quot;Courier&quot;&gt; Open: &amp;lt;%= f.calendar_date_select :open, :size =&amp;gt; 15 %&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;font face=&quot;Courier&quot;&gt; Close: &amp;lt;%= f.calendar_date_select :close, :size =&amp;gt; 15 %&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;/blockquote&gt;&lt;font face=&quot;Courier&quot;&gt; &amp;lt;/p&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;/blockquote&gt;&lt;font face=&quot;Courier&quot;&gt;&amp;lt;/div&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;/blockquote&gt;&lt;br&gt;And voila!&lt;br&gt;&lt;blockquote&gt; &lt;br&gt;&lt;/blockquote&gt;&lt;br&gt;I am sure there are other ways to get this gem installed and working.&lt;br&gt;&lt;br&gt;&lt;hr size=&quot;1&quot;&gt;&lt;br/&gt;</description></item><item><title>TD Blog</title><link>http://technicaldebt.wetpaint.com/page/TD+Blog</link><author>JonKern</author><guid isPermaLink="false">http://technicaldebt.wetpaint.com/page/TD+Blog</guid><pubDate>Sun, 05 Sep 2010 23:07:15 CDT</pubDate><description>The last few postings from my blog:&lt;br&gt;&lt;br&gt;&lt;div class=&quot;WPC-edit-field WPC-edit-rss WPC-edit-rss-total-4&quot;&gt;&lt;a class=&quot;external&quot; href=&quot;http://technicaldebt.wetpaint.comhttp://widget.wetpaintserv.us/widget/wetpaintrss/acfaefa546b629c01dc5994d2462a244bbc610f8?wpo=&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt; &lt;/a&gt;&lt;/div&gt;&lt;br&gt;&lt;hr size=&quot;1&quot;&gt;&lt;br/&gt;</description></item><item><title>The Keys to Software Development</title><link>http://technicaldebt.wetpaint.com/page/The+Keys+to+Software+Development</link><author>JonKern</author><guid isPermaLink="false">http://technicaldebt.wetpaint.com/page/The+Keys+to+Software+Development</guid><pubDate>Sun, 05 Sep 2010 23:04:22 CDT</pubDate><description>&lt;br&gt;&lt;table align=&quot;bottom&quot; cellpadding=&quot;3&quot; class=&quot;WPC-edit-border-all&quot; height=&quot;1973&quot; width=&quot;735&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;center&quot; class=&quot;WPC-edit-border-all&quot; width=&quot;100%&quot;&gt;&lt;br&gt;&lt;h3&gt; &lt;br&gt;&lt;/h3&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;center&quot; class=&quot;WPC-edit-border-all&quot; width=&quot;100%&quot;&gt;&lt;br&gt; &lt;br&gt;Add photo caption or credit here.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;center&quot; class=&quot;WPC-edit-border-all&quot; width=&quot;100%&quot;&gt;&lt;br&gt; &lt;br&gt; Add photo caption or credit here.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;center&quot; class=&quot;WPC-edit-border-all&quot; width=&quot;100%&quot;&gt;&lt;br&gt; &lt;br&gt;Add photo caption or credit here.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;b&gt;&lt;table align=&quot;bottom&quot; cellpadding=&quot;3&quot; class=&quot;WPC-edit-style-grid1 WPC-edit-border-all WPC-edit-styleData-color1=%23ebebeb&amp;color2=%23c7c7c7&quot; width=&quot;500&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;&quot; width=&quot;100%&quot;&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;&quot; width=&quot;100%&quot;&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;&quot; width=&quot;100%&quot;&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;&quot; width=&quot;100%&quot;&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;&quot; width=&quot;100%&quot;&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;&quot; width=&quot;100%&quot;&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;&quot; width=&quot;100%&quot;&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;&quot; width=&quot;100%&quot;&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;&quot; width=&quot;100%&quot;&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;&quot; width=&quot;100%&quot;&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;&quot; width=&quot;100%&quot;&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;&quot; width=&quot;100%&quot;&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;&quot; width=&quot;100%&quot;&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;&quot; width=&quot;100%&quot;&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;&quot; width=&quot;100%&quot;&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;&quot; width=&quot;100%&quot;&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;&quot; width=&quot;100%&quot;&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;&quot; width=&quot;100%&quot;&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;&quot; width=&quot;100%&quot;&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;&quot; width=&quot;100%&quot;&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;&quot; width=&quot;100%&quot;&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;&quot; width=&quot;100%&quot;&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;&quot; width=&quot;100%&quot;&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;&quot; width=&quot;100%&quot;&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;&quot; width=&quot;100%&quot;&gt; &lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br&gt;&lt;/b&gt;&lt;br&gt;&lt;b&gt;&lt;br&gt;&lt;/b&gt;&lt;br&gt;&lt;hr size=&quot;1&quot;&gt;&lt;br/&gt;</description></item><item><title>Rails Ramblings</title><link>http://technicaldebt.wetpaint.com/page/Rails+Ramblings</link><author>JonKern</author><guid isPermaLink="false">http://technicaldebt.wetpaint.com/page/Rails+Ramblings</guid><pubDate>Sun, 05 Sep 2010 22:56:03 CDT</pubDate><description>As I run across items I find useful in the world of Ruby and Rails...&lt;br&gt;&lt;br&gt;&lt;a href=&quot;http://technicaldebt.wetpaint.com/page/Calendar+Date+Select&quot; target=&quot;_self&quot; title=&quot;Calendar Date Select&quot;&gt;Calendar Date Select&lt;/a&gt;&lt;br&gt;&lt;hr size=&quot;1&quot;&gt;&lt;br/&gt;</description></item><item><title>Overview</title><link>http://technicaldebt.wetpaint.com/page/Overview</link><author>JonKern</author><guid isPermaLink="false">http://technicaldebt.wetpaint.com/page/Overview</guid><pubDate>Mon, 23 Aug 2010 12:30:32 CDT</pubDate><description>&lt;br&gt; 			&lt;table align=&quot;bottom&quot; cellpadding=&quot;3&quot; class=&quot;WPC-edit-style-columns2 WPC-edit-border-cols WPC-edit-styleData-color1=%23ff0015&amp;color2=%23c7c7c7&quot; width=&quot;400&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor=&quot;#ff0015&quot; class=&quot;WPC-edit-borderBottom-solid WPC-edit-custom-borderBottom WPC-edit-borderTop-solid WPC-edit-custom-borderTop&quot; width=&quot;14%&quot;&gt;&lt;b&gt;&lt;font color=&quot;#ffff00&quot;&gt;NOTE:&lt;/font&gt;&lt;/b&gt;&lt;/td&gt;&lt;td class=&quot;WPC-edit-borderTop-solid WPC-edit-custom-borderTop WPC-edit-borderBottom-solid WPC-edit-custom-borderBottom&quot; width=&quot;86%&quot;&gt;The &amp;quot;&lt;a href=&quot;http://technicaldebt.wetpaint.com/page/Jon%27s+Agile+Development+Tips&quot; target=&quot;_self&quot;&gt;Jon&amp;#39;s Agile Development Tips&lt;/a&gt;&amp;quot; pages are under construction. The other pages are generally complete.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br&gt;This site is dedicated to pointing out Technical Debt (&amp;quot;&lt;font size=&quot;4&quot;&gt;&lt;b&gt;TD&lt;/b&gt;&lt;/font&gt;&amp;quot;) that we run across during our work in the hopes that we all might learn:&lt;br&gt;&lt;ul&gt;&lt;li&gt;Ways to avoid Technical Debt&lt;/li&gt;&lt;li&gt;How to recognize Technical Debt&lt;/li&gt;&lt;li&gt;The costs of Technical Debt&lt;/li&gt;&lt;li&gt;Prevention is better than cure (just like in your health)&lt;/li&gt;&lt;/ul&gt;The site also holds various techniques I employ for running agile software development projects. This part is a kind of work in progress, as I try to transfer stuff from other project wikis over to here in piecemeal fashion.&lt;br&gt;&lt;h2&gt;Look &amp;#39;em Over&lt;/h2&gt; The &lt;a href=&quot;http://technicaldebt.wetpaint.com/page/TD+Examples&quot; target=&quot;_self&quot;&gt;examples&lt;/a&gt; page is a fun place to start.&lt;br&gt; &lt;br&gt; Make some comments on any page as you see fit.&lt;br&gt; &lt;h2&gt;Join the Fray!&lt;/h2&gt; After you get some ideas from the &lt;a href=&quot;http://technicaldebt.wetpaint.com/page/TD+Examples&quot; target=&quot;_self&quot;&gt;examples&lt;/a&gt; page, consider uploading some of your own. To show us your gems, simply follow the instructions &lt;a href=&quot;http://technicaldebt.wetpaint.com/page/How+to+Post&quot; target=&quot;_self&quot; title=&quot;here&quot;&gt;here&lt;/a&gt; for posting examples.&lt;br&gt;&lt;h2&gt;Why the term?&lt;/h2&gt;I have been calling this &amp;quot;stuff&amp;quot; by the term &amp;quot;Technical Debt&amp;quot; for so long, I don&amp;#39;t even recall when, why, or how I began using the term. I have a vague memory of an audience member shouting out the term after I described the concepts in a presentation. Dunno... Doesn&amp;#39;t matter. A quick Google seems to ascribe the term to Ward Cunningham... in his OOPSLA &amp;#39;92 &lt;a class=&quot;external&quot; href=&quot;http://technicaldebt.wetpaint.comhttp://c2.com/doc/oopsla92.html&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;article&lt;/a&gt;. No matter who came up with the term, the intent of all usages seems to be similar. Basically, the idea is to describe what can happen in the software world in common financial terms that most non-technical people can understand.&lt;br&gt;&lt;br&gt;The term has the word &amp;quot;debt&amp;quot; so that most people will sense that -- like financial debt -- technical debt:&lt;br&gt;&lt;ul&gt;&lt;li&gt;could increase over time&lt;/li&gt;&lt;li&gt;requires servicing the debt&lt;/li&gt;&lt;li&gt;needs to be paid off&lt;/li&gt;&lt;li&gt;can cause bankruptcy if unchecked&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;STD?&lt;/h2&gt;Should I name it Software Technical Debt, for short?&lt;br&gt;&lt;br&gt;A nice Parable on Agile Concepts.&lt;br&gt; &lt;hr size=&quot;1&quot;&gt;&lt;br/&gt;</description></item><item><title>Release Planning</title><link>http://technicaldebt.wetpaint.com/page/Release+Planning</link><author>JonKern</author><guid isPermaLink="false">http://technicaldebt.wetpaint.com/page/Release+Planning</guid><pubDate>Fri, 30 Apr 2010 21:13:48 CDT</pubDate><description>Our goal is to arrive at a rough estimate for the batch of features  and tasks necessary to deem a &amp;quot;Release.&amp;quot; For example, a release can be  version 1.0, or a smaller &amp;quot;dot&amp;quot; release. We simply work from an initial list of items to complete.&lt;br&gt;We usually have a set of minimum features we want to consider for our new release. Though we might lay out a rough iteration plan, it is subject to whatever we discover once we get into the thick of things. Sometimes we have to do some technical spikes if we are investigating new techniques. &lt;br&gt;  &lt;h2&gt;Overlapping Streams&lt;/h2&gt;  The hard part of this process is to show the parallel aspects in  diagrams. Before the team finishes the current iteration, the business  needs to be poised and ready with a plan of what they would like in the  next iteration. The following diagram can be the same whether iterations are down the left-hand side, and versions replace the &amp;quot;Release&amp;quot; blocks on the right-hand side.&lt;br&gt;&lt;br&gt; &lt;br&gt;Ensuring stability is covered under &lt;a href=&quot;http://technicaldebt.wetpaint.com/page/Parallel+Development&quot; target=&quot;_self&quot; title=&quot;Parallel&quot;&gt;Parallel&lt;/a&gt; and &lt;a href=&quot;http://technicaldebt.wetpaint.com/page/Branch+Development&quot; target=&quot;_self&quot;&gt;Branch&lt;/a&gt; Development.&lt;br&gt;&lt;br&gt;&lt;hr size=&quot;1&quot;&gt;&lt;br/&gt;</description></item><item><title>Writing Good Issues</title><link>http://technicaldebt.wetpaint.com/page/Writing+Good+Issues</link><author>JonKern</author><guid isPermaLink="false">http://technicaldebt.wetpaint.com/page/Writing+Good+Issues</guid><pubDate>Fri, 30 Apr 2010 21:03:08 CDT</pubDate><description>I use Jira from Atlassian, so your mileage may vary. But in general, Softwae Development is nothing more complex than accomplishing a list of &amp;quot;to-dos&amp;quot; :-)&lt;br&gt;&lt;br&gt;A &lt;b&gt;feature&lt;/b&gt; is:  &lt;ul&gt;&lt;li&gt;something the product does&lt;/li&gt;&lt;li&gt;think marketing brochure bullets or finding it in the User Manual&lt;/li&gt;&lt;li&gt;It might get bugs.&lt;/li&gt;&lt;li&gt;It might get improvements.&lt;/li&gt;&lt;li&gt;It might even be dropped.&lt;/li&gt;&lt;/ul&gt;   A &lt;b&gt;task&lt;/b&gt; is  &lt;ul&gt;&lt;li&gt;something done one time&lt;/li&gt;&lt;li&gt;Is often an implementation detail for creating features&lt;br&gt;&lt;/li&gt;&lt;li&gt;never appears on a marketing brochure or in a feature list&lt;/li&gt;&lt;li&gt;Examples: 	&lt;ul&gt;&lt;li&gt;add users for beta;&lt;/li&gt;&lt;li&gt;get app stood up on PROD;&lt;/li&gt;&lt;li&gt;write a Flex UI training plan&lt;/li&gt;&lt;li&gt;Implement the persistence layer (tables, DAO)&lt;br&gt;&lt;/li&gt;&lt;/ul&gt; 	&lt;/li&gt;&lt;/ul&gt;A &lt;b&gt;subtask&lt;/b&gt; is &lt;br&gt;&lt;ul&gt;&lt;li&gt;a small bit of effort that you might do to accomplish the parent issue. &lt;br&gt;&lt;/li&gt;&lt;li&gt;It is often useful to help you track your to-dos &lt;br&gt;&lt;/li&gt;&lt;li&gt;Is useful to estimate a larger task by breaking it down into visible chunks.&lt;/li&gt;&lt;li&gt;Is used solely by the dev team... that is, it should not be surfaced and scheduled by the business&lt;br&gt;&lt;/li&gt;&lt;/ul&gt;  A &lt;b&gt;bug&lt;/b&gt; is &lt;br&gt;&lt;ul&gt;&lt;li&gt;something that is not working according to plan.&lt;/li&gt;&lt;li&gt;should be considered when doing iteration planning&lt;br&gt;&lt;/li&gt;&lt;li&gt;Covered in more detail in &lt;a href=&quot;http://technicaldebt.wetpaint.com/page/Writing+Good+Bugs&quot; target=&quot;_self&quot;&gt;Writing Good Bugs&lt;/a&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;Tips&lt;/h2&gt;&lt;br&gt;&lt;table align=&quot;bottom&quot; cellpadding=&quot;3&quot; class=&quot;WPC-edit-style-grid1 WPC-edit-border-all WPC-edit-styleData-color1=%23ebebeb&amp;color2=%23c7c7c7&quot; width=&quot;800&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;&quot; width=&quot;18%&quot;&gt;Issue Type&lt;/td&gt;&lt;td class=&quot;&quot; width=&quot;82%&quot;&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;&quot; width=&quot;18%&quot;&gt;&lt;b&gt;Summary&lt;/b&gt;&lt;br&gt;&lt;b&gt;(Title)&lt;/b&gt;&lt;/td&gt;&lt;td class=&quot;&quot; width=&quot;82%&quot;&gt;Make the title clear and concise. It should indicate something the user does or the system does. If it is a Group-type issue, preface with &amp;quot;Group: &amp;quot; just so that it stands out in the various views.&lt;br&gt;&lt;ul&gt;&lt;li&gt; &amp;quot;Agent can select COB easily&amp;quot;&lt;/li&gt;&lt;li&gt; &amp;quot;Agent can view premium breakdowns and summary&amp;quot;&lt;/li&gt;&lt;/ul&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;&quot; width=&quot;18%&quot;&gt;&lt;b&gt;Description&lt;/b&gt;&lt;/td&gt;&lt;td class=&quot;&quot; width=&quot;82%&quot;&gt;NOTE: For lengthy descriptions that also serve as &amp;quot;corporate memory&amp;quot; of the major requirements, do the bulk of docs on the wiki, summarize in the issue and paste a URL.&lt;br&gt;&lt;br&gt;Be sure to describe the issue fully so that the &amp;quot;client-valued&amp;quot; aspects shine through. &lt;br&gt;&lt;br&gt;Here are some templates (search Google for more) to help you word the issues properly.&lt;br&gt;&lt;br&gt;&lt;b&gt;One template&lt;/b&gt;&lt;br&gt; &amp;quot;As a &lt;b&gt;role&lt;/b&gt;, I should be able to &lt;b&gt;feature&lt;/b&gt;, so that &lt;b&gt;benefit&lt;/b&gt;&amp;quot;&lt;br&gt; &amp;quot;As an Agent, I should be able to choose class of business easily (searching by name or SIC code), so that I can quickly and accurately prepare a quote for my client.&amp;quot;&lt;b&gt;&lt;br&gt;&lt;/b&gt;&lt;b&gt;FDD template&lt;/b&gt;&lt;br&gt; Another template (from Feature-Driven Development) is:&lt;br&gt; &amp;lt;action&amp;gt; &amp;lt;result&amp;gt; &amp;lt;object&amp;gt;&lt;br&gt; &amp;quot;Display the detail &amp;amp; summary premium data (to the agent).&amp;quot;&lt;br&gt; &amp;quot;Create a PDF of the detail &amp;amp; summary premium data (so the agent can send to client).&amp;quot;&lt;b&gt;&lt;br&gt;Scenario Template&lt;/b&gt;&lt;br&gt; Be sure to also include how to know when an issue is &lt;b&gt;complete&lt;/b&gt; and testable. Describe various scenarios if needed, when there are different conditions to consider. The point here is to make it clear to the developer and the tester what is expected.&lt;br&gt;&lt;table align=&quot;bottom&quot; cellpadding=&quot;3&quot; class=&quot;WPC-edit-style-grid1 WPC-edit-border-all WPC-edit-styleData-color1=%23ebebeb&amp;color2=%23c7c7c7&quot; width=&quot;400&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;&quot; width=&quot;17%&quot;&gt;Title&lt;/td&gt;&lt;td class=&quot;&quot; width=&quot;83%&quot;&gt;Clearly describe the context/what&amp;#39;s different&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;&quot; width=&quot;17%&quot;&gt;Given...&lt;/td&gt;&lt;td class=&quot;&quot; width=&quot;83%&quot;&gt;Some context&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;&quot; width=&quot;17%&quot;&gt;When...&lt;/td&gt;&lt;td class=&quot;&quot; width=&quot;83%&quot;&gt;User does xyz&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;&quot; width=&quot;17%&quot;&gt;Then...&lt;/td&gt;&lt;td class=&quot;&quot; width=&quot;83%&quot;&gt;this happens&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br&gt;Examples:&lt;br&gt;&lt;table align=&quot;bottom&quot; cellpadding=&quot;3&quot; class=&quot;WPC-edit-style-grid1 WPC-edit-border-all WPC-edit-styleData-color1=%23ebebeb&amp;color2=%23c7c7c7&quot; width=&quot;400&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;&quot; width=&quot;17%&quot;&gt;Title&lt;/td&gt;&lt;td class=&quot;&quot; width=&quot;83%&quot;&gt;Show Premium Details - Single Line Of Business&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;&quot; width=&quot;17%&quot;&gt;Given...&lt;/td&gt;&lt;td class=&quot;&quot; width=&quot;83%&quot;&gt;A Quote for Business Owners Insurance&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;&quot; width=&quot;17%&quot;&gt;When...&lt;/td&gt;&lt;td class=&quot;&quot; width=&quot;83%&quot;&gt;displays the premium after successfully rating&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;&quot; width=&quot;17%&quot;&gt;Then...&lt;/td&gt;&lt;td class=&quot;&quot; width=&quot;83%&quot;&gt;a clear breakdown of the premium details (from ART) will be displayed in a UI, see wiki&lt;a class=&quot;external&quot; href=&quot;http://technicaldebt.wetpaint.comhttp://confluence.immuexa.com//download/attachments/8504/PremiumBreakdown2.png&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot; title=&quot;Visit page outside Confluence&quot;&gt; &lt;/a&gt;. At the bottom of the columnar-based details, show a Premium Total.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br&gt;&lt;table align=&quot;bottom&quot; cellpadding=&quot;3&quot; class=&quot;WPC-edit-style-grid1 WPC-edit-border-all WPC-edit-styleData-color1=%23ebebeb&amp;color2=%23c7c7c7&quot; width=&quot;400&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;&quot; width=&quot;17%&quot;&gt;Title&lt;/td&gt;&lt;td class=&quot;&quot; width=&quot;83%&quot;&gt;Show Premium Details - Multiple LOBs&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;&quot; width=&quot;17%&quot;&gt;Given...&lt;/td&gt;&lt;td class=&quot;&quot; width=&quot;83%&quot;&gt;An RQA with Business Owners + Workers Comp&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;&quot; width=&quot;17%&quot;&gt;When...&lt;/td&gt;&lt;td class=&quot;&quot; width=&quot;83%&quot;&gt;displays the premium after successfully rating&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;&quot; width=&quot;17%&quot;&gt;Then...&lt;/td&gt;&lt;td class=&quot;&quot; width=&quot;83%&quot;&gt;For each LOB, show a clear breakdown of the premium details. For each LOB, show the premium subtotal. At the bottom of the columnar-based details, show a Premium Total for all LOBs.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br&gt;&lt;table align=&quot;bottom&quot; cellpadding=&quot;3&quot; class=&quot;WPC-edit-style-grid1 WPC-edit-border-all WPC-edit-styleData-color1=%23ebebeb&amp;color2=%23c7c7c7&quot; width=&quot;400&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;/tr&gt;&lt;tr&gt;&lt;/tr&gt;&lt;tr&gt;&lt;/tr&gt;&lt;tr&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;&quot; width=&quot;18%&quot;&gt;&lt;b&gt;Component&lt;/b&gt; &lt;/td&gt;&lt;td class=&quot;&quot; width=&quot;82%&quot;&gt;Useful to link the issue to a specific area of the application or work efforts.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;&quot; width=&quot;18%&quot;&gt;&lt;b&gt;Version&lt;/b&gt; &lt;/td&gt;&lt;td class=&quot;&quot; width=&quot;82%&quot;&gt;a.k.a. &amp;quot;Iteration&amp;quot; -- implies when the feature is scheduled for completion&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;&quot; width=&quot;18%&quot;&gt;&lt;b&gt;Assign&lt;/b&gt; &lt;/td&gt;&lt;td class=&quot;&quot; width=&quot;82%&quot;&gt;Set during issue handling process. Generally should be based on person&amp;#39;s knowledge and skills in inverse proportion to the criticality and complexity and deadline. Should not simply be any warm body.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;&quot; width=&quot;18%&quot;&gt;&lt;b&gt;Priority&lt;/b&gt; &lt;/td&gt;&lt;td class=&quot;&quot; width=&quot;82%&quot;&gt;Often known in advance. Helps team understand relative importance of an issue. Macro priority is the Version. This priority can sometimes be used to help a developer sort their work tasks in proper order.&lt;br&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;&quot; width=&quot;18%&quot;&gt;&lt;b&gt;Estimate&lt;/b&gt; &lt;/td&gt;&lt;td class=&quot;&quot; width=&quot;82%&quot;&gt;Developer doing the task can enter their estimate (see process)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;&quot; width=&quot;18%&quot;&gt;&lt;b&gt;Due Date&lt;/b&gt;&lt;/td&gt;&lt;td class=&quot;&quot; width=&quot;82%&quot;&gt;Used when an issue needs to be done by a date other than end of milestone (used infrequently).&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;&quot; width=&quot;18%&quot;&gt;&lt;b&gt;Attachment&lt;/b&gt; &lt;/td&gt;&lt;td class=&quot;&quot; width=&quot;82%&quot;&gt;Upload any useful attachments, or reference those that are on a wiki page!&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;&quot; width=&quot;18%&quot;&gt;&lt;b&gt;Links&lt;/b&gt;&lt;/td&gt;&lt;td class=&quot;&quot; width=&quot;82%&quot;&gt;If there are related issues or dependencies, add them via &lt;b&gt;link&lt;/b&gt;. For example see &lt;a href=&quot;http://technicaldebt.wetpaint.com/page/Linking+Tests+to+Issues&quot; target=&quot;_self&quot; title=&quot;Linking Issues&quot;&gt;Linking Issues&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br&gt;&lt;br&gt;&lt;table class=&quot;confluenceTable&quot;&gt;&lt;tbody&gt;  &lt;/tbody&gt;&lt;/table&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;a class=&quot;external&quot; href=&quot;http://technicaldebt.wetpaint.comhttp://confluence.immuexa.com/display/MG/Writing+Good+Issues?showComments=true&amp;showCommentArea=true#addcomment&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;&lt;br&gt;&lt;/a&gt;&lt;hr size=&quot;1&quot;&gt;&lt;br/&gt;</description></item><item><title>Writing Good Bugs</title><link>http://technicaldebt.wetpaint.com/page/Writing+Good+Bugs</link><author>JonKern</author><guid isPermaLink="false">http://technicaldebt.wetpaint.com/page/Writing+Good+Bugs</guid><pubDate>Fri, 30 Apr 2010 20:51:25 CDT</pubDate><description>&lt;b&gt;Most of the instructions for &lt;a href=&quot;http://technicaldebt.wetpaint.com/page/Writing+Good+Issues&quot; target=&quot;_self&quot;&gt;Writing Good Issues&lt;/a&gt; still apply!&lt;/b&gt;  &lt;ul&gt;&lt;li&gt;Meaningful title 	&lt;ul&gt;&lt;li&gt;Indicate what is wrong&lt;/li&gt;&lt;li&gt;Example: &amp;quot;BOP Application&amp;quot; as a title is too wide open to interpretation. One tip is to think of being in your user&amp;#39;s/client&amp;#39;s shoes and reading the title as part of the Release Notes. Ask yourself, &amp;quot;would the title make any sense in such a stand-alone fashion?&amp;quot;&lt;br&gt; Contrast how the two would read in a &amp;quot;Release Notes&amp;quot; document/webpage:&lt;br&gt; &amp;quot;Bug Fixed: BOP Application&amp;quot;&lt;br&gt; &amp;quot;Bug Fixed: BOP Application -- Form missing fax number&amp;quot;&lt;/li&gt;&lt;/ul&gt; 	&lt;/li&gt;&lt;li&gt;Clear description 	&lt;ul&gt;&lt;li&gt;What is wrong&lt;/li&gt;&lt;li&gt;Add expected or desired behavior&lt;/li&gt;&lt;/ul&gt; 	&lt;/li&gt;&lt;li&gt;Choose the component, if known. Otherwise, development will categorize it&lt;/li&gt;&lt;li&gt;Record as much context as possible 	&lt;ul&gt;&lt;li&gt;Where you were testing (if multiple environments)&lt;/li&gt;&lt;li&gt;What you were doing that led to the bug&lt;/li&gt;&lt;li&gt;What steps are required to reproduce the bug&lt;/li&gt;&lt;li&gt;Any specific identifier for the data (e.g., an ID, a title)&lt;/li&gt;&lt;/ul&gt; 	&lt;/li&gt;&lt;li&gt;Add any helpful screenshots&lt;/li&gt;&lt;li&gt;Indicate the severity of the bug (see below)&lt;/li&gt;&lt;/ul&gt;   &lt;h3&gt;Severity&lt;/h3&gt;  When we receive a PRODUCTION bug, we have to immediately determine the nature of the bug. Basically, we need to know if we should fix it ASAP because it is causing major problems for our customers, or if it can wait.&lt;br&gt;  To evaluate a bug so that we can determine the severity, we need to have enough additional information in the following fashion (for example):&lt;br&gt;&lt;table align=&quot;bottom&quot; cellpadding=&quot;3&quot; class=&quot;WPC-edit-style-grid2 WPC-edit-border-all WPC-edit-styleData-color1=%23ebebeb&amp;color2=%23c7c7c7&quot; width=&quot;400&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor=&quot;#ebebeb&quot; class=&quot;&quot; width=&quot;20%&quot;&gt;Severity&lt;/td&gt;&lt;td bgcolor=&quot;#ebebeb&quot; class=&quot;&quot; width=&quot;80%&quot;&gt;Impact to the user getting their job done&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;right&quot; class=&quot;&quot; width=&quot;20%&quot;&gt;&lt;b&gt;SEV 1&lt;/b&gt;&lt;/td&gt;&lt;td class=&quot;&quot; width=&quot;80%&quot;&gt;Cannot perform their job. Loss of data, time, and/or money. No workaround exists.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;right&quot; class=&quot;WPC-edit-custom-bgColor&quot; width=&quot;20%&quot;&gt;&lt;b&gt;SEV 2&lt;/b&gt;&lt;/td&gt;&lt;td class=&quot;WPC-edit-custom-bgColor&quot; width=&quot;80%&quot;&gt;Can perform their job, but it takes much longer than it should. Workaround exists.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;right&quot; class=&quot;&quot; width=&quot;20%&quot;&gt;&lt;b&gt;SEV 3&lt;/b&gt;&lt;/td&gt;&lt;td class=&quot;&quot; width=&quot;80%&quot;&gt;Bug is annoying, workaround exists.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td bgcolor=&quot;#ebebeb&quot; class=&quot;&quot; width=&quot;20%&quot;&gt;Importance&lt;/td&gt;&lt;td bgcolor=&quot;#ebebeb&quot; class=&quot;&quot; width=&quot;80%&quot;&gt;Indicate the likelihood of this occurring, or the importance of getting it fixed&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;The &lt;b&gt;SAMPLE&lt;/b&gt; table below outlines the response times based on the level of severity of the bug.&lt;br&gt;  &lt;table class=&quot;confluenceTable&quot;&gt;&lt;tbody&gt;  &lt;tr&gt;     &lt;/tr&gt; &lt;tr&gt;     &lt;/tr&gt; &lt;tr&gt;     &lt;/tr&gt; &lt;tr&gt;     &lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt;&lt;br&gt;  &lt;table align=&quot;bottom&quot; cellpadding=&quot;3&quot; class=&quot;WPC-edit-style-list4 WPC-edit-border-none WPC-edit-styleData-color1=%23ebebeb&amp;color2=%23c7c7c7&quot; height=&quot;647&quot; width=&quot;685&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor=&quot;#c7c7c7&quot; class=&quot;&quot; width=&quot;12%&quot;&gt;Severity&lt;/td&gt;&lt;td bgcolor=&quot;#c7c7c7&quot; class=&quot;&quot; width=&quot;62%&quot;&gt;Criteria&lt;/td&gt;&lt;td bgcolor=&quot;#c7c7c7&quot; class=&quot;&quot; width=&quot;1%&quot;&gt;Response Goal&lt;/td&gt;&lt;td bgcolor=&quot;#c7c7c7&quot; class=&quot;&quot; width=&quot;25%&quot;&gt;Resolution Goal&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;center&quot; bgcolor=&quot;#c7c7c7&quot; class=&quot;&quot; width=&quot;12%&quot;&gt;1&lt;/td&gt;&lt;td bgcolor=&quot;#ebebeb&quot; class=&quot;&quot; width=&quot;62%&quot;&gt;&lt;b&gt;Causes a Severe&lt;/b&gt; impact on customer&amp;#39;s business (e.g., can&amp;#39;t  provide a quote, quote was inaccurate).&lt;br&gt; &lt;b&gt;Causes the Portal&lt;/b&gt; to cease: (a) working, or (b) working in any  material respect. This includes any error in the Portal that poses harm  to Customer&amp;#39;s computer systems, or data losses.&lt;br&gt; &lt;b&gt;No known workaround&lt;/b&gt; available. &lt;/td&gt;&lt;td bgcolor=&quot;#ebebeb&quot; class=&quot;&quot; width=&quot;1%&quot;&gt;2 Hours *&lt;/td&gt;&lt;td bgcolor=&quot;#ebebeb&quot; class=&quot;&quot; width=&quot;25%&quot;&gt;Will work on the problem until resolved or a workaround is found.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;center&quot; bgcolor=&quot;#c7c7c7&quot; class=&quot;&quot; width=&quot;12%&quot;&gt;2&lt;/td&gt;&lt;td class=&quot;&quot; width=&quot;62%&quot;&gt;&lt;b&gt;Causes a major function&lt;/b&gt; of the Portal to be substantially  impaired, although it still operates.&lt;br&gt; In &lt;b&gt;Dev Environment&lt;/b&gt;, causes a non-critical impact on development  activity (e.g., jeopardizing production rollout).&lt;br&gt; In &lt;b&gt;Production Environment&lt;/b&gt;, causes a non-critical impact on  business operations of agent (e.g., some premium details or other  question data missing from a form).&lt;br&gt; &lt;b&gt;Intermittent disruption&lt;/b&gt; of portal service.&lt;br&gt; &lt;b&gt;No stable workaround&lt;/b&gt; available.&lt;/td&gt;&lt;td class=&quot;&quot; width=&quot;1%&quot;&gt;4 Hours *&lt;/td&gt;&lt;td class=&quot;&quot; width=&quot;25%&quot;&gt;Vendor will make reasonable efforts to provide a correction or  workaround within three (3) days&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;center&quot; bgcolor=&quot;#c7c7c7&quot; class=&quot;&quot; width=&quot;12%&quot;&gt;3&lt;/td&gt;&lt;td bgcolor=&quot;#ebebeb&quot; class=&quot;&quot; width=&quot;62%&quot;&gt;&lt;b&gt;Causes a minor function&lt;/b&gt; of the Portal to be impaired.&lt;br&gt; In &lt;b&gt;Dev Environment&lt;/b&gt;, causes a minor impact on development activity  (e.g., does not jeopardize production rollout).&lt;br&gt; In &lt;b&gt;Production Environment&lt;/b&gt;, causes a minor impact on business  operations of end customer (e.g., minimal degradation of functionality).  &lt;/td&gt;&lt;td bgcolor=&quot;#ebebeb&quot; class=&quot;&quot; width=&quot;1%&quot;&gt;2 Days&lt;/td&gt;&lt;td bgcolor=&quot;#ebebeb&quot; class=&quot;&quot; width=&quot;25%&quot;&gt;Will make reasonable efforts to resolve the problem or provide a  workaround within thirty (30) days&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;center&quot; bgcolor=&quot;#c7c7c7&quot; class=&quot;&quot; width=&quot;12%&quot;&gt;4&lt;/td&gt;&lt;td class=&quot;&quot; width=&quot;62%&quot;&gt;In &lt;b&gt;Dev Environment&lt;/b&gt;, causes little or no impact on development  activity.&lt;br&gt; In &lt;b&gt;Production Environment&lt;/b&gt;, causes little or no impact on business  operations of end user. &lt;/td&gt;&lt;td class=&quot;&quot; width=&quot;1%&quot;&gt;1 Week&lt;/td&gt;&lt;td class=&quot;&quot; width=&quot;25%&quot;&gt;Will make reasonable efforts to resolve the problem or provide a  workaround if such problem has not been resolved in the next maintenance  release of the Portal&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br&gt;NOTE:&lt;br&gt;* Issues of Critical or High severity levels must be reported via  telephone to receive these response times.&lt;br&gt;&lt;h3&gt;Issue Contents&lt;/h3&gt; Bugs should describe all that is necessary for the  developer to:  &lt;ol&gt;&lt;li&gt;know the problem via a test/demonstration (i.e.,  it needs to be repeatable),&lt;/li&gt;&lt;li&gt;troubleshoot, and&lt;/li&gt;&lt;li&gt;verify the  problem is gone via the same (and possibly other) tests/demonstrations.&lt;/li&gt;&lt;/ol&gt;&lt;br&gt;&lt;b&gt;Be thorough&lt;/b&gt; &lt;table align=&quot;bottom&quot; cellpadding=&quot;3&quot; class=&quot;WPC-edit-style-grid1 WPC-edit-border-all WPC-edit-styleData-color1=%23ebebeb&amp;color2=%23c7c7c7&quot; height=&quot;211&quot; width=&quot;600&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;&quot; width=&quot;26%&quot;&gt;Reading:&lt;/td&gt;&lt;td class=&quot;&quot; width=&quot;74%&quot;&gt;MG-1243@JIRA &lt;b&gt;Underwriter questions - yes/no choices&lt;/b&gt; &lt;br&gt; When switching a yes/no choice from yes to no, the NO field does not value on the first selection. See screen printing. No to Yes is working but Yes to NO required two clicks.&lt;br&gt; Happening in both &amp;quot;Appliances - Household&amp;quot; and &amp;quot;Apartment/Condo.&amp;quot; I didn&amp;#39;t check the other classes of business yet. &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;&quot; width=&quot;26%&quot;&gt;Leaves me wondering:&lt;/td&gt;&lt;td class=&quot;&quot; width=&quot;74%&quot;&gt;Is it the UI?  &lt;ul&gt;&lt;li&gt;Can you see this behavior in Diner?&lt;/li&gt;&lt;li&gt;In other parts of the Qstnr 3?&lt;br&gt; Is it the data?&lt;/li&gt;&lt;li&gt;Does this happen on every UW question?&lt;/li&gt;&lt;li&gt;...on every question with a Yes/No?&lt;/li&gt;&lt;li&gt;...on only some questions?&lt;/li&gt;&lt;li&gt;...on only questions that have rules?&lt;/li&gt;&lt;li&gt;...on only questions that are made visible by rules?&lt;/li&gt;&lt;li&gt;...on only choices that participate in rules?&lt;/li&gt;&lt;/ul&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br&gt;&lt;div class=&quot;tabletitle&quot;&gt;&lt;/div&gt;&lt;br&gt;&lt;hr size=&quot;1&quot;&gt;&lt;br/&gt;</description></item><item><title>When will the app be done</title><link>http://technicaldebt.wetpaint.com/page/When+will+the+app+be+done</link><author>JonKern</author><guid isPermaLink="false">http://technicaldebt.wetpaint.com/page/When+will+the+app+be+done</guid><pubDate>Fri, 30 Apr 2010 20:35:12 CDT</pubDate><description>This is often a tough balance between the Dev team and the Business. &amp;quot;How much&amp;quot; and &amp;quot;When&amp;quot; are critical to the business and elusive for the Dev team at the outset.&lt;br&gt;&lt;br&gt;Honesty and collaboration is the best course of action. Sure, you can answer what they want to hear, but that ain&amp;#39;t right.&lt;br&gt;&lt;br&gt;Do your best at &lt;a href=&quot;http://technicaldebt.wetpaint.com/page/Initial+Requirements+Scoping&quot; target=&quot;_self&quot;&gt;up-front estimation&lt;/a&gt;, make a stab at team size and velocity (I use &lt;a href=&quot;http://technicaldebt.wetpaint.com/page/Issue+Management&quot; target=&quot;_self&quot;&gt;hours&lt;/a&gt;, not story points), and give a general &amp;quot;season&amp;quot; as a probably date.&lt;br&gt;&lt;br&gt;As we elicit the overall requirements and rough list of features, I&amp;#39;ll end up creating a spreadsheet that will include columns for &amp;quot;Estimate&amp;quot; and &amp;quot;Risk Multiplier.&amp;quot; The Risk Multiplier is used to provide some high-lows. If we see a lot of high risk in an area, e may choose to mitigate that risk by doing a technical spike, for example.&lt;br&gt;&lt;br&gt;Oh, and keep folks informed as we learn more!&lt;br&gt;&lt;hr size=&quot;1&quot;&gt;&lt;br/&gt;</description></item><item><title>Initial Requirements Scoping</title><link>http://technicaldebt.wetpaint.com/page/Initial+Requirements+Scoping</link><author>JonKern</author><guid isPermaLink="false">http://technicaldebt.wetpaint.com/page/Initial+Requirements+Scoping</guid><comments>Rename</comments><pubDate>Fri, 30 Apr 2010 20:19:05 CDT</pubDate><description>&lt;br&gt;For the initial &amp;quot;Phase 0&amp;quot; or &amp;quot;Release Planning&amp;quot; effort, we want to arrive at enough of a plan to give the business some idea as to the approximate schedule and cost for what the business wants built. Normally, we use this up-front planning time to iterate with the business on just what will constitute a good first product release. That is, the business might have some ideas for features that cost more than they are worth. Conversely, the development team might have an approach in mind that makes other business value attainable. The point is that I like to work at a &amp;quot;level up&amp;quot; from the intended product. To understand the business environment and drivers surrounding the specific project is invaluable. This often allows us to come up with spectacular game-changing solutions because we aren&amp;#39;t simply boxed in with an &lt;i&gt;a priori&lt;/i&gt; idea of product shape (which naturally was formed within a set context).&lt;br&gt;&lt;br&gt;We also let the business know that it is an &amp;quot;&lt;i&gt;early-stage&lt;/i&gt;&amp;quot; plan, that we will continuously update with each iteration. Progress will be very visible to all participants throughout, allowing for adjustments along the way.  &lt;h2&gt;Business Modeling&lt;/h2&gt;  Software is designed to solve business problems. In the beginning of a project, I like to have a series of meetings with the business to flesh out the core requirements with subject matter experts, architects, and stakeholders in the room. It is often helpful to think about the problem by working backwards from the endpoint. Many times, there is a core set of requirements needed to meet minimal business worth for the stakeholders. That is, without these features, nothing else matters. For example, what requirements will an insurance agent have for the system to allow them to place more business and manage their customers? What aspects of the system are needed for the insurance company&amp;#39;s Underwriters to manage the lines of business rules and profitability/risk ratios? Add to this the unique aspects that the sales portal could provide (for example, through providing agents with a sales funnel concepts maybe?). The goal is to arrive at the sort of information we need to have on hand to make such functionality possible. Arriving at the core features helps us when deriving estimates and setting priorities. Non-core, or &amp;quot;mice to have&amp;quot; features can be shuffled to later in the project, or to version 2 following successful product launch.&lt;br&gt;&lt;br&gt;  Underlying the requirements gathering process (outlined below), we use object-oriented techniques. The domain information is placed into &amp;quot;Classes&amp;quot; with names familiar to the business, and appropriate associations.  I use simple sticky notes and a whiteboard to start.&lt;br&gt;&lt;br&gt;A great deal of emphasis is placed on the business model for the simple fact that this is where you make or break most software systems. By keeping the business model reflecting what you do for a living, we are more able to adapt to new feature requests or to move with the industry as changes inevitably occur.  &lt;br&gt;&lt;br&gt;To tie yourself to industry data formats, or database-specific calls, or user interface aspects, is to potentially cause future harm to the company. The results of doing such designs are often applications that are not easy to upgrade, apps that are hard to maintain, unpredictable schedules, and blown maintenance deadlines. All because of allowing &amp;quot;technical debt&amp;quot; to creep into the system and build up over time, unchecked.&lt;br&gt;&lt;br&gt;  Therefore, we tirelessly labor over getting the business model &amp;quot;front and center&amp;quot; in the application development effort. From this perspective, most other aspects &amp;quot;hang&amp;quot; off of the domain nomenclature: features, bugs, enhancements, etc., &lt;b&gt;all&lt;/b&gt; use the same terminology  &lt;br&gt;&lt;br&gt;One more thing. We don&amp;#39;t model &amp;quot;everything under the sun.&amp;quot; If there is no need to record agent hair color (for example), we won&amp;#39;t model that characteristic. If, however, the analytic logic could make use of number of times an agent&amp;#39;s application was &amp;quot;referred,&amp;quot; we would endeavor to record that in the business model.  &lt;h2&gt;Requirements Elicitation&lt;/h2&gt;  As part of the process to discover the business model, we simply ask about the overarching business goals and the user&amp;#39;s requirements. We do this in a very &lt;b&gt;iterative&lt;/b&gt; and agile style, making &lt;b&gt;successive passes&lt;/b&gt; until we&amp;#39;re satisfied that we know enough to make a reasonable estimate and plan of attack. &lt;br&gt;&lt;br&gt;Over time, the domain model and features list and cost estimate gain more and more information. In the early part of the process, we make huge steps with every day spent. As the process draws to a close, you will see less and less value coming from the time spent together, and fewer significant contributions to the overall understanding of the information leading to the estimate. You&amp;#39;ll realize it is time to stop planning, and time to kick off development.&lt;br&gt;&lt;br&gt;For most of my projects, the time has followed what FDD often cites: 10% of the overall development schedule. Three months for a three-year project. Two weeks for a 6-month project. Your mileage may vary.&lt;br&gt;&lt;br&gt;&lt;h3&gt;System Purpose&lt;/h3&gt;It is critical to have a basic idea about what the &lt;b&gt;system&amp;#39;s purpose&lt;/b&gt; is, and any concrete features that it must have. At the outset of the project, it is imperative that we have folks in the room who are subject matter experts and who know what the system is intended to do. The System Purpose can be (indeed, I would go so far as to say &amp;quot;&lt;i&gt;should be&lt;/i&gt;&amp;quot;) quite simple (Peter Coad recommends 25 words or less): &lt;br&gt;&lt;br&gt; SYSTEM PURPOSE:  &lt;table cellpadding=&quot;3&quot; class=&quot;WPC-edit-style-grid2 WPC-edit-border-all WPC-edit-styleData-color1=%23ebebeb&amp;color2=%23c7c7c7&quot; height=&quot;56&quot; width=&quot;543&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor=&quot;#ebebeb&quot; class=&quot;confluenceTd&quot; width=&quot;100%&quot;&gt; Acme Insurance needs to build a &amp;quot;modern&amp;quot; web application to permit agencies to sell Acme insurance to the agency&amp;#39;s clients. (1) Sell more insurance, (2) Reduce cost of sales, (3) Improve company&amp;#39;s street cred with a modern app.&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt;  &lt;br&gt;&lt;h3&gt;Initial Requirements Gathering&lt;/h3&gt;You do not need to gather all of the requirements in the first go. That is, we do not need volumes of written requirements to start. We need to have enough information to make an initial stab at what the basic application needs to be, how we might architect it, and approximately what season it might be near completion (given a certain team size and make-up). Usually, the business wants a ballpark cost estimate, or wants to know what can be done for a specific budget.&lt;br&gt;&lt;br&gt;&lt;blockquote&gt; &lt;b&gt;Note&lt;/b&gt;&lt;i&gt;The more accurate the estimate needs to be, the more work you need to do prior to giving an estimate. The Law of Diminishing Returns applies.&lt;br&gt;&lt;/i&gt;&lt;/blockquote&gt;&lt;br&gt;As we bore deeper into the domain features, we continue to add to the domain model and build up a simple list of features -- either as class methods or a simple text list to start. The wisdom comes in knowing what is important to capture, what details can be skipped until later, and what constitutes &lt;i&gt;good enough&lt;/i&gt; for the first high-level pass. The &amp;quot;depth&amp;quot; is tempered by the up-front knowledge of how accurate and detailed the estimate needs to be. The depth is also controlled by a sense of risk of estimating. That is, if a feature sounds potentially complex and risky, we&amp;#39;ll want to spend enough time to dig a bit deeper. Maybe go down to the next level of sub-features, so to speak, or break down what is turning out to be a &amp;quot;Feature Set.&amp;quot;&lt;br&gt;&lt;br&gt;&lt;blockquote&gt; &lt;b&gt;Balance Tip&lt;/b&gt;&lt;i&gt; We are always playing a balancing game. Do too much upfront, and it may be wasted effort. Do too little, and you may provide the business with a woefully inadequate estimate, or get a nasty surprise at the end when that missing feature appears.&lt;br&gt;&lt;/i&gt;&lt;/blockquote&gt; &lt;br&gt;At the outset, we just need a reasonable title for the feature, maybe a sentence or two of prose. Enough to make a reasonable hack at estimating the size. When the time comes to actually schedule and produce the feature, we get back together and talk it out in more detail &amp;ndash; again, preferably with a subject matter expert leading the way. This will lead to a more accurate estimate as it will incorporate more project learning.&lt;br&gt;&lt;br&gt;  Part of the agile philosophy is to prefer individuals and interactions over documentation &amp;ndash; especially since there is no such thing as a perfect specification anyway. And, to spend double or triple the time on writing more documentation will experience the law of diminishing returns in a dramatic fashion.  &lt;br&gt;&lt;br&gt;Once we get to a point of having the bulk of the initial features, we will ask for them to be prioritized -- though sometimes we have gathered that information along the way when it was obvious. By concentrating on the highest priority (&amp;quot;must-have&amp;quot;) features first, we begin to deliver recognizable value almost immediately as we produce working software each day of each iteration (admittedly, a releasable product requires a bunch of features before real value is delivered).&lt;br&gt;&lt;br&gt;&lt;blockquote&gt;    &lt;b&gt;Balance Tip&lt;/b&gt;   &lt;i&gt;How do we estimate accurately? You may not have the development team intact when doing Phase 0. You may not feel comfortable with the technology. You may not be sure of some of the requirements. You must balance knowing enough about the app&amp;#39;s requirements yet not having all of the detail.&lt;br&gt;   &lt;/i&gt; &lt;/blockquote&gt;  &lt;br&gt;Typically, you have to rely on your &amp;quot;gut feel&amp;quot; and those of your trusted senior architect/developer types. If there are high risks, you may need to counter by:&lt;ul&gt;&lt;li&gt;Doing some investigation to reduce the risk&lt;/li&gt;&lt;li&gt;Add a multiplier/padding to the estimate to attempt to account for uncertainty&lt;br&gt;&lt;/li&gt;&lt;/ul&gt;So one quick-pass technique I use is to ballpark the cost of developing the basic domain model components (classes, tables, etc.). Gather the list of features into a spreadsheet or convenient issue tracker (but this usually takes more time than a quick spreadsheet). Add a column for estimate in hours. Add a column for &amp;quot;risk factor&amp;quot; in case you need to multiply the estimate to account for uncertainty of general &amp;quot;gnarliness&amp;quot; of the requirement. If you have a feel for the major UI components above and beyond the feature list, throw them into the mix as well. Anything else you can think of... setting up automated processes, various environments, and so on. Balance the numbers with the gut feel folks have about the app; for example, &amp;quot;I think a team of six can have that implemented in 4 months.&amp;quot;&lt;br&gt;&lt;h3&gt;Risk Leveling&lt;/h3&gt;The way I like to look at this initial period, is to consider what we are trying to accomplish. We need to provide an estimate and rough &amp;quot;shape&amp;quot; of the application to a certain level of &amp;quot;risk&amp;quot; to make the stakeholders happy. If estimates need to be very accurate, then you need to squeeze out medium and high risks. You might even need to do an initial project to build out and test some aspects of your architecture. If you need a moderately accurate estimate and you have worked in this kind of an app many times, then maybe you only need to squeeze out the high-risk areas. The point is that not all features on the list are the same, unless you make an effort to &amp;quot;level&amp;quot; out the uncertainty. &lt;br&gt;  &lt;h2&gt;&amp;quot;Doing&amp;quot; Complements Theorizing&lt;/h2&gt;  Part of being agile means we seek to understand enough about what we are trying to accomplish to help provide meaningful estimates. Instead of producing purely paper output and schedules made with only best guesses, we will strive to uncover enough detail about what it is we&amp;#39;ll be building, and what complexities we may run into. &lt;br&gt;&lt;br&gt;  For example, there are some technical challenges facing us with: &lt;ul&gt;&lt;li&gt;Should we build a porting scheme for the 3rd-party back-end system (Sphnx)? Or should we access it in real-time?&lt;/li&gt;&lt;li&gt;What details can we find out about the web service rating engine?&lt;br&gt;&lt;/li&gt;&lt;li&gt;We might need to scope out the Java/Flex architecture (thin slice) to see &amp;quot;how it feels&amp;quot; (and costs to develop)&lt;br&gt;&lt;/li&gt;&lt;/ul&gt;   How do we do this? We intend to explore a bit of the solution space itself to get a better handle on what we are up against. Our gut instinct tells us that we will want to ensure efficient means of integrating with Sphnx, for example.  &lt;br&gt;&lt;br&gt;By way of analogy... Think of developing an application with 100 features being akin to carrying 100 pumpkins from Point A to B by foot, one at a time (maybe 300 years ago). We could do some theorizing about how long it will take by guessing on the distance, and guessing at how much ground we might cover in a typical day. However, if nobody has ever gone from A to B before, how accurate do you think we would be? However, if we actually try to take one pumpkin to get a more realistic feeling for the complexity involved, we will likely learn some valuable details along the way. For example, we would learn about rivers to ford, possibly forests with bears. We would learn about what sorts of unexpected deviations might occur that add unpredictable variability to the equation.   &lt;br&gt;&lt;br&gt;At any rate, I hope you get the picture. By practicing delivering some features, even if a bit shallow at first, we will gain valuable knowledge to help the team going forward. At a minimum, we need to have a handle on the technical approach to lend credence to our initial rough release plan estimates.  &lt;h2&gt;Expected Results&lt;/h2&gt;  We want the &amp;quot;Requirements Workshop&amp;quot; to help produce  &lt;ul&gt;&lt;li&gt;A reasonable understanding of the major features needed for this application&lt;/li&gt;&lt;li&gt;A pretty solid business model able to take us through initial release&lt;/li&gt;&lt;li&gt;A realistic &amp;quot;feel&amp;quot; for the application&amp;#39;s technical aspects&lt;/li&gt;&lt;li&gt;Some possible solutions for the more technically challenging aspects of this app&lt;/li&gt;&lt;li&gt;A &amp;quot;slice&amp;quot; of the requirements in visible form, in a working piece of software&lt;/li&gt;&lt;/ul&gt;   We will also produce an initial release schedule/roadmap. This will consist of a simple list of features to be delivered in the initial release and possibly a set for one subsequent release (if we have convinced the business that some features can wait until after the initial release). We will also put a &amp;quot;size&amp;quot; and schedule around what Release #1 will require. Often, I will break down larger pieces of the puzzle for Release 1 by roughing out an Iteration Schedule of how certain larger (major) feature sets will roll out. But this is always done with extreme simplicity since we do not want to waste excessive effort on any long-term planning details.&lt;br&gt;&lt;br&gt;  &lt;hr size=&quot;1&quot;&gt;&lt;br/&gt;</description></item><item><title>About Me</title><link>http://technicaldebt.wetpaint.com/page/About+Me</link><author>JonKern</author><guid isPermaLink="false">http://technicaldebt.wetpaint.com/page/About+Me</guid><pubDate>Fri, 30 Apr 2010 19:52:43 CDT</pubDate><description>I live in eastern Pennsylvania in a house from early 1700s -- old for the USA &amp;lt;g&amp;gt;, but not for the Old World! I have a wife, a son (20 something), and twin daughters (teens), a Yorkshire Terrier, 2 indoor cats, and 2 barn cats.&lt;br&gt;&lt;br&gt;I began life testing jet engines as an aerospace engineer. Then I discovered software on a Dec Vax. (I also discovered Adventure!) I learned IDL, FORTRAN, some C. Then I discovered object-oriented programming (with Turbo C++). It was all over after that. I cut my teeth on R:Base and learned SQL -- though I did not know it at the time. I did application development on the side. I became proficient at PowerBuilder and later Power++. I learned C as part of my graduate work in numerical computations. I was using C for flight simulation and hardware-in-the-loop projects.&lt;br&gt;&lt;br&gt;I met Peter Coad in 92 -- he became my OO mentor. I bought Together/C+ + in 1994 and began to do whatever I could to help this wonderful product grow. I formed LightshipInc, a consulting company, in 1995, grew to about 10 people. We designed and built IBM&amp;#39;s Manufacturing Execution system. I did the UI design on paper and sold the execs that we could take on the (3 year) project. We did great engineering product order configurator using OODBMS for a pump manufacturer (Ingersoll-Rand).&lt;br&gt;&lt;br&gt;Throughout the 80s/early 90s, I experienced inefficiencies of doing software government-style. So I had created my own agile methods in &amp;quot;self defense&amp;quot; (besides, I don&amp;#39;t like to waste money). I first published this stuff in a Lotus Developers book or two. (Don&amp;#39;t ask why &amp;lt;g&amp;gt;.)&lt;br&gt;&lt;br&gt;In 1999, Peter Coad recruited me to help form TogetherSoft -- with quite a few other guys. In a few years we had grown quite a bit in size. From 2000 to 2002 I commuted to St. Petersburg, Russia, to lead new product development and what not (like learn to drink vodka properly). Brilliant developers.&lt;br&gt;&lt;br&gt;In February 2001, I attended the gathering in Snowbird that led to the &lt;a class=&quot;external&quot; href=&quot;http://technicaldebt.wetpaint.comhttp://agilemanifesto.org&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Agile Manifesto&lt;/a&gt; -- as I recall (which may be flawed memory), &amp;#39;agile&amp;#39; being suggested because I had done a lot of work with Agile Fighter research, and Alistair Cockburn did not want to be known as a &amp;quot;&lt;i&gt;Lightweight&lt;/i&gt; Methodologist.&amp;quot;&lt;br&gt;&lt;br&gt;In 2003 we sold TogetherSoft to Borland. I was recruited by Compuware to come work for the OptimalJ team in May 2003. I tried my best... there was too much inertia for me to have the impact I desired. Awesome product idea, however. Brilliant developers. I got to start a blog (~35K hits/month), and a newsletter (~6,000 subscribers).&lt;br&gt;&lt;br&gt;In Fall 2006, I turned private, working with a couple of friends of mine at &lt;a class=&quot;external&quot; href=&quot;http://technicaldebt.wetpaint.comhttp://immuexa.com/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;immuexa&lt;/a&gt;... have worked on a SemWeb project, and on a insurance portal project with &lt;a class=&quot;external&quot; href=&quot;http://technicaldebt.wetpaint.comhttp://synergycomponents.com/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Synergy Components&lt;/a&gt;, among other things. We also do pre-planning software for the fire and first responders at &lt;a class=&quot;external&quot; href=&quot;http://technicaldebt.wetpaint.comhttp://fireplanningassociates.com/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Fire Planning Associates&lt;/a&gt;.&lt;br&gt;&lt;br&gt;My ideal job is working on cool projects with a great team, a great customer; and to be able to travel.&lt;br&gt;&lt;br&gt;My family and I travel quite a bit... we like to ski, I like to &lt;a class=&quot;external&quot; href=&quot;http://technicaldebt.wetpaint.comhttp://www.flickr.com/photos/jonkyonthespot/sets/72157621198453614/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;rock climb&lt;/a&gt;, climb &lt;a class=&quot;external&quot; href=&quot;http://technicaldebt.wetpaint.comhttp://www.flickr.com/photos/jonkyonthespot/3878456314/in/set-72157622084354144/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;mountains&lt;/a&gt; (Alpine), and drive cars fast (mostly Audis) around &lt;a class=&quot;external&quot; href=&quot;http://technicaldebt.wetpaint.comhttp://www.youtube.com/watch?v=PHJGMHHQlW0&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;tracks&lt;/a&gt; and autocrosses :-)&lt;br&gt;&lt;br&gt;Cheers! &lt;br&gt;&lt;hr size=&quot;1&quot;&gt;&lt;br/&gt;</description></item><item><title>Detailed Estimation Sucks</title><link>http://technicaldebt.wetpaint.com/page/Detailed+Estimation+Sucks</link><author>JonKern</author><guid isPermaLink="false">http://technicaldebt.wetpaint.com/page/Detailed+Estimation+Sucks</guid><pubDate>Tue, 20 Apr 2010 21:29:40 CDT</pubDate><description>Pretend you have a team cranking away at a production app. Part of the IT staff, so to speak.&lt;br&gt;&lt;br&gt;Please have a seat. Yes, over there by the window is fine. Buckle up. You may experience some turbulence.&lt;br&gt; &lt;br&gt; If you want to know &amp;quot;when you can get all that stuff done,&amp;quot; sit the team in a room, show them the list of stuff, and ask them. I&amp;#39;ll give you an hour. I suggest you have them use &lt;b&gt;seasons&lt;/b&gt; from the sounds of the current mess :-)&lt;br&gt; &lt;br&gt; If you really want to know within a month as to when the list of 1000 issues will be done (including the 250 that you don&amp;#39;t yet know about), then wait until you are about to release, and you will have a very accurate number.&lt;br&gt; &lt;br&gt; I doubt that estimating accurately or poorly will help all that much in knowing when an entire list of stuff will be done. Especially when the list changes over time. Given that, why spend any/much energy? &lt;i&gt;&amp;quot;Don&amp;#39;t polish a turd.&amp;quot;&lt;/i&gt;&lt;br&gt; &lt;br&gt;  Why not simply guarantee to management that the team will do their best effort. Just grab a stack of important (i.e., prioritized) stuff to do (loosely based on a logical roadmap/release plan), track the amount of things done each iteration on a chart. Skip the up-front waste of time estimating everything in detail. I mean really... just stab at &amp;quot;we can do 20&amp;quot; and see how it goes -- adjust as needed. Should take all of about 30 minutes each iteration depending on your tools and your team collaboration. &lt;br&gt; &lt;br&gt; Put an indication on the chart of number of total issues -- but be ready to continually update this as new issues/bugs arrive (it&amp;#39;s lots of fun to watch the goal continually move further away). Or have the chart represent the bare minimum marketable features (bigger ticket items without the details). Now anyone can sense the rate of closure of the team towards the goal as each iteration piles on more closed issues. After two iterations, you can draw a straight line, after three, you can use fancier curve fits and show the least squares correlation coefficient &amp;lt;g&amp;gt;. &lt;br&gt; &lt;br&gt; Instead of spending time estimating, spend time making the project progress information radiator as meaningful as possible. Believe me, software is merely working a to-do list. Anybody can watch a list of things getting ticked off and do a mental estimation as to rate of progress. Build a better view into what the project is actually doing and let people think about how it might look going forward. At least your historical data is guaranteed accurate!&lt;br&gt; &lt;br&gt; The only time I would estimate &amp;quot;more accurately&amp;quot; is if I have competing ideas or ways to solve a problem via wildly differing approaches. Then maybe we might want to weigh one versus the other from a business point of view because it could make a big difference in the long run.&lt;br&gt; &lt;br&gt; But for an entrenched team on an entrenched product to estimate each little feature/issue/bug fix/story at the outset of each iteration?? I question the value of the team&amp;#39;s time being spent doing that. I gave it up for Lent.&lt;br&gt;&lt;br&gt;Try no doing detailed iteration estimation. It can be very liberating to just do the work as best and as fast as you can.&lt;br&gt; &lt;br&gt; At some point, you and management will realize that &lt;b&gt;it doesn&amp;#39;t matter if the team is good at estimating or not&lt;/b&gt;. At some point you may realize that most of &lt;b&gt;the estimation process is an illusion&lt;/b&gt;, a grand trip into self-delusion fantasy land. The same amount of work will get done (well, more will likely get done if less time is spent estimating). &lt;br&gt; &lt;br&gt; If you need to control &lt;b&gt;what&lt;/b&gt; work gets done by when, then you prioritize mercilessly and do a good job to make development efficient (which includes smart architecture and design, among other things). If you need to speed up &lt;b&gt;when&lt;/b&gt; the work gets done, then you need to consider resources (better or more) and/or reducing scope. &lt;br&gt; &lt;br&gt; Now, if you want to spend time making the team better at estimating for their own edification (a la PSP), let them do their own estimates and track actuals and try to improve over time.&lt;br&gt; &lt;br&gt; If only software were as simple as aerodynamics. I can predict quite accurately how a NACA airfoil is going to behave in 2D and 3D airflow. I have never been able to have a team predict to that level of accuracy. Predicting software is not much different than predicting a relationship.&lt;br&gt;&lt;br&gt;Something to ponder... Why bother with estimates at all? &lt;br&gt; &lt;br&gt;1. Who needs them and what are they for? &lt;br&gt;2. What happens if you are dead-on accurate? &lt;br&gt;3. What happens if you are off by 100%? &lt;br&gt;4. What if #2 == #3?? &lt;br&gt;5. Are the workers going to be fired with poor estimates? Given raises?&lt;br&gt;6. How did they estimate before? &lt;br&gt;7. Is estimation the best use of their time?&lt;br&gt;&lt;br&gt;We&amp;#39;re now ready for take-off!&lt;br&gt;&lt;hr size=&quot;1&quot;&gt;&lt;br/&gt;</description></item><item><title>Miscellanea</title><link>http://technicaldebt.wetpaint.com/page/Miscellanea</link><author>JonKern</author><guid isPermaLink="false">http://technicaldebt.wetpaint.com/page/Miscellanea</guid><pubDate>Sun, 28 Mar 2010 08:35:04 CDT</pubDate><description>&lt;br&gt;My adventure climbing the Matterhorn in 2009: &lt;a href=&quot;http://technicaldebt.wetpaint.com/page/Switzerland+2009&quot; target=&quot;_self&quot; title=&quot;Switzerland Climbing&quot;&gt;Switzerland Climbing&lt;/a&gt;&lt;br&gt;&lt;br&gt;Great bread recipe, no kneading required: &lt;a href=&quot;http://technicaldebt.wetpaint.com/page/Artisan+Bread+Recipe&quot; target=&quot;_self&quot; title=&quot;Artisanal Bread&quot;&gt;Artisanal Bread&lt;/a&gt;&lt;br&gt;&lt;br&gt;Here are some silly attempts at audio humor by using Voice Candy application:&lt;br&gt;&lt;br&gt;&lt;ul&gt;&lt;li&gt;Agile Cheese &lt;a class=&quot;external&quot; href=&quot;http://technicaldebt.wetpaint.comhttp://files.me.com/jonkernpa/pnwkwx.wav&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;wav file&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Use the Agile Force &lt;a class=&quot;external&quot; href=&quot;http://technicaldebt.wetpaint.comhttp://files.me.com/jonkernpa/uypevz.wav&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;wav file&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Nutty User Stories &lt;a class=&quot;external&quot; href=&quot;http://technicaldebt.wetpaint.comhttp://files.me.com/jonkernpa/t06vml.wav&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;wav file &lt;/a&gt;&lt;/li&gt;&lt;li&gt;Mr. Agile Robotto &lt;a class=&quot;external&quot; href=&quot;http://technicaldebt.wetpaint.comhttp://files.me.com/jonkernpa/z10yoo.wav&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;wav file&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;Even though there is dispute over the whole right/left thing, this is humorous: &lt;a href=&quot;http://technicaldebt.wetpaint.com/page/Right+Brain+Test&quot; target=&quot;_self&quot; title=&quot;&amp;quot;Right Brain&amp;quot; Test&quot;&gt;&amp;quot;Right Brain&amp;quot; Test&lt;/a&gt;&lt;br&gt;&lt;hr size=&quot;1&quot;&gt;&lt;br/&gt;</description></item><item><title>Artisan Bread Recipe</title><link>http://technicaldebt.wetpaint.com/page/Artisan+Bread+Recipe</link><author>JonKern</author><guid isPermaLink="false">http://technicaldebt.wetpaint.com/page/Artisan+Bread+Recipe</guid><pubDate>Sat, 30 Jan 2010 08:17:17 CST</pubDate><description>A friend (Jacques Murphy), gave us this printed recipe. I googled for &amp;quot;Artisan-Free-Form loaf&amp;quot; and found many references. Apparently, it is from a book: Bake bread easily every day with &lt;a class=&quot;external&quot; href=&quot;http://technicaldebt.wetpaint.comhttp://www.globalgourmet.com/food/cookbook/2009/artisan-bread/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Artisan Bread in Five Minutes a Day&lt;/a&gt; by Jeff Hertzberg and Zo&amp;euml; Fran&amp;ccedil;ois.&lt;br&gt;&lt;br&gt;Since the dough can be stored in a fridge, I purchased a square plastic container with a lid, that will hold a full, risen, batch (6 liters).&lt;br&gt;&lt;br&gt;&lt;b&gt;Preparation&lt;/b&gt;&lt;br&gt;The mixing takes all of about 10 minutes -- I often do it when I want a break from thinking about a tough coding or design problem :-)&lt;br&gt;&lt;br&gt;Here is what I do:&lt;br&gt;&lt;ol&gt;&lt;li&gt;Make 3 cups of 100-deg F. water, pour into mixing 6 liter container/big bowl&lt;br&gt;(Sometimes, if I have a &amp;quot;stump&amp;quot; of red wine or the like, I&amp;#39;ll use it as part of the liquid. Going over 1cup wine will make it very wine-y tasting.)&lt;br&gt;&lt;/li&gt;&lt;li&gt;Add 1.5T granulated yeast (== 1T + 1.5t)&lt;/li&gt;&lt;li&gt;Add 1.5T sea salt (or Lawry&amp;#39;s garlic salt for even more pizazz)&lt;br&gt;&lt;/li&gt;&lt;li&gt;Sometimes I add in 1.5T sugar -- just because I feel like feeding the yeasties some sugar&lt;/li&gt;&lt;li&gt;6.5 cups unsifted, unbleached, all-purpose flour. I scoop in the measuring cup and level off the measure with the straight edge of a knife.&lt;/li&gt;&lt;li&gt;With wooden spoon, strong spatula, stir up the mixture until there are no longer any dry clumps of flour&lt;/li&gt;&lt;li&gt;Let rise about 2+ hours, covered -- but not tightly sealed (yeasties have to breath, dontchaknow). Room temperature is fine, or near the wood stove, or sometimes I put it nearby on the stove when I am making stock for hours. Yeaties like a little warmth as they grow and multiply.&lt;br&gt;&lt;/li&gt;&lt;/ol&gt;You could put the dough into the fridge -- we have had the dough in the fridge for as long as 12 days with no issues.&lt;br&gt;&lt;br&gt;&lt;b&gt;Baking&lt;/b&gt;&lt;br&gt;Place a rack in the middle of a 450 deg F. oven, with the broiler pan positioned in the lowest position (you&amp;#39;ll see why below).&lt;br&gt;&lt;br&gt;Prepare a baking sheet -- either with corn meal, or parchment/baking paper.&lt;br&gt;&lt;br&gt;Since the dough can be pretty sticky at times, sprinkle the dough with flour (I cover my hands with flour too). Dig out a big clump -- I keep a sharp knife nearby to cut off the clump as I pull it up from the container. Work the clump into the shape you desire, additional flour is sometimes needed to keep it from sticking to your hands.&lt;br&gt;&lt;br&gt;You can make any size and shape you like:&lt;br&gt;&lt;ul&gt;&lt;li&gt;round or oblong loaf&lt;/li&gt;&lt;li&gt;long baguette&lt;/li&gt;&lt;li&gt;rolls&lt;/li&gt;&lt;/ul&gt;Score the top of the loaf with a sharp knife... Sprinkle liberally with flour (for that artisan look) or large salt crystals over top if you like.&lt;br&gt;&lt;br&gt;You can let it rest for 30-40 minutes -- especially if it is from the fridge. But I have already rushed the dough into the oven (and my mouth) with no real issues.&lt;br&gt;&lt;br&gt;&lt;b&gt;The Power of Steam&lt;/b&gt;&lt;br&gt;Get a cup of water ready to pour into the broiler pan (something with a long handle is a good idea). &lt;br&gt;&lt;br&gt;Place the bread into the oven.&lt;br&gt;&lt;br&gt;Pull the broiler pan out a bit, so that you can quickly pour the water into the pan -- it will steam like crazy, so don&amp;#39;t burn yourself. Quickly close the door -- which will push the pan back into the oven).&lt;br&gt;&lt;br&gt;The steam will make that yummy hard crust!&lt;br&gt;&lt;br&gt;Bake for about 30 minutes, or until the crust is brown and firm to the touch. Vary the time based on the size and shape...&lt;br&gt;&lt;br&gt;&lt;b&gt;Versatility&lt;/b&gt;&lt;br&gt;&lt;br&gt;We also use the dough for homemade pizza and strombolis.&lt;br&gt;&lt;br&gt;After a few times making this recipe, you&amp;#39;ll have all the nuances figured out. It is a very robust recipe that can withstand lots of variations. Experiment!&lt;br&gt;&lt;br&gt;&lt;hr size=&quot;1&quot;&gt;&lt;br/&gt;</description></item></channel></rss>