<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Basil Vandegriend: Professional Software Development &#187; refactoring</title>
	<atom:link href="http://www.basilv.com/psd/blog/tag/refactoring/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.basilv.com/psd</link>
	<description></description>
	<lastBuildDate>Thu, 17 May 2012 14:31:08 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Why You Should Polish Your Code</title>
		<link>http://www.basilv.com/psd/blog/2007/why-you-should-polish-your-code</link>
		<comments>http://www.basilv.com/psd/blog/2007/why-you-should-polish-your-code#comments</comments>
		<pubDate>Mon, 25 Jun 2007 22:13:24 +0000</pubDate>
		<dc:creator>Basil Vandegriend</dc:creator>
				<category><![CDATA[coding]]></category>
		<category><![CDATA[code review]]></category>
		<category><![CDATA[refactoring]]></category>
		<category><![CDATA[software development]]></category>

		<guid isPermaLink="false">http://www.basilv.com/psd/blog/2007/why-you-should-polish-your-code</guid>
		<description><![CDATA[When are you done writing a piece of code? Is it when you have implemented the necessary functionality? When you have tested it? I believe there is more to professional-quality code than just getting it to function properly. What else is there? Making sure the code is maintainable - well designed and understandable. I use [...]]]></description>
			<content:encoded><![CDATA[<p>When are you done writing a piece of code? Is it when you have implemented the necessary functionality? When you have tested it? I believe there is more to professional-quality code than just getting it to function properly. What else is there? Making sure the code is <a href="http://www.basilv.com/psd/blog/2006/how-to-create-maintainable-software">maintainable</a> - well designed and understandable. I use the term polishing code to refer to this kind of work that is done on a code base after it is functioning properly. I like the analogy with woodworking: once a piece is assembled and finished, the final step is to polish the surface to make it shine.</p>
<p>Based on the code bases I have seen and worked with, polishing code is not a frequent practice. In fact, I have encountered people who are surprised by my commitment to it, or who do not believe in its value. Many of these people are not developers, or have not spent much time doing ongoing software maintenance. Part of the reason for the lack of appreciation is that polishing code provides long term benefits for a short term cost. This induces project managers and developers on development projects with compressed time frames to skip such kinds of activities. In other cases, non-technical managers simply have no idea of the poor quality of code their developers are producing. One project manager I dealt with personally reviewed and made minor grammatical corrections to the documentation produced by the project team, but had no similar processes in place for the poor quality code produced by the project team.</p>
<p>So why do I believe that polishing code is valuable? I have several reasons. The most important is that it minimizes the long term cost of maintaining the software. To explain this, I like to use the concept of <a href="http://martinfowler.com/bliki/TechnicalDebt.html">technical debt</a>. Quality issues such as poor design in software represent a debt for which you will need to make continuing interest payments later in the form of increased effort to understand or change the software. This is the case even if the software functions correctly. To pay off that debt, you must address the underlying quality issues - in other words, you must polish the code. Martin Fowler wrote a recent <a href="http://martinfowler.com/bliki/DesignStaminaHypothesis.html">article about this topic in the context of good design</a> that explains the trade-offs involved. Another reason I polish my code is that it is a permanent record of my capabilities as a professional software developer. My reputation amongst developers who need to work with my code later is in large part determined by my code's quality. Code of mine that is difficult to understand or change or is riddled with defects will have maintenance developers cursing at me. I would rather have them be pleasantly surprised at finding helpful comments and a clean design. </p>
<p>So now you hopefully believe that polishing code is valuable, but you may be asking how exactly to go about it. In terms of timing, polishing of code should ideally be done throughout the development of a section of code. In reality, however, it is much easier to focus on one issue at a time, and the primary issue is just getting the code to work. Therefore after the code is written and passing the automated unit tests, it is only natural for it to have some rough spots. This is the ideal point to do a review of your code to identify places to polish. My basic goals when polishing are to improve the understandability of the code and to improve its design. During the review, I look for specific problems impacting these two goals. When I find such a problem, I immediately rectify it by <a href="http://www.amazon.ca/gp/product/0201485672?ie=UTF8&#038;tag=basilvandegri-20&#038;linkCode=as2&#038;camp=15121&#038;creative=330641&#038;creativeASIN=0201485672">refactoring the code</a><img src="http://www.assoc-amazon.ca/e/ir?t=basilvandegri-20&#038;l=as2&#038;o=15&#038;a=0201485672" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />. Often it is as easy as using one of the built-in refactoring tools of the development environment to safely make the change with a near-zero risk of introducing defects.</p>
<p>Some examples of specific problems I look for are:</p>
<ul>
<li>Duplication of logic in two or more places.</li>
<li>Undesired dependencies. For applications divided into layers such as persistence, business and user interface, the dependencies between the layers need to be managed. Finding undesired dependencies such as the use of persistence code directly within the user interface layer is a strong indicator of a design problem.</li>
<li>Overly complex logic, like a large switch statement or series of nested if-else statements. Sometimes such logic can be drastically simplified through the use of object-oriented design principles.</li>
<li>Too many classes within one package.</li>
<li>Too many methods within a class, particularly public methods. This is often an indicator that the class is trying to do too much and should be split into multiple classes.</li>
<li>Overly long file, in excess of a couple thousand lines. Even in Java where each public class is forced to be in its own file, it is possible to end up with very long files. This may be because there is too much logic within the class, or it may be because of many nested classes or private classes in the same file. In the latter case, these can be moved to one or more separate files.</li>
<li>Overly long methods. Anything longer than about one screen warrants a closer look to see if it can be simplified, usually via an extract method refactoring.</li>
<li>Poorly named classes, methods, fields or local variables. One indicator I look for is a one-sentence comment describing a vaguely named variable or method. Usually the variable or method can be renamed to capture the essence of the comment and the comment can then be deleted.</li>
<li>Lack of a class comment. A concise summary of the purpose of the class is often quite useful. If it is difficult to come up with such a summary, it is an indicator that the class may be trying to do too much or does not have a clear focus.</li>
</ul>
<p>Ron Jeffries' site <a href="http://www.xprogramming.com/">http://www.xprogramming.com/</a> has a great series of articles that provide concrete examples of polishing code, including before and after samples of the source code.</p>
<p>Polishing your own code is good, but it is better if your entire team adopts the practice. An effective way to ensure code is polished within a team is via code reviews. While ideally everyone should polish their own code, having a separate reviewer check for code quality problems is a big help. This is especially true for ensuring that the code is understandable by someone other than the original developer. </p>
<p>Applications with polished code are easier to understand and modify, which helps extend their useful life. Applications with poor quality code are more likely to be partially rewritten or even completely replaced if the cost of ongoing maintenance becomes too high. Which of these applications would you prefer to contribute to? The choice is yours.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.basilv.com/psd/blog/2007/why-you-should-polish-your-code/feed</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Top Five Essential Practices for Developing Software</title>
		<link>http://www.basilv.com/psd/blog/2007/top-five-essential-practices-for-developing-software</link>
		<comments>http://www.basilv.com/psd/blog/2007/top-five-essential-practices-for-developing-software#comments</comments>
		<pubDate>Wed, 09 May 2007 13:41:34 +0000</pubDate>
		<dc:creator>Basil Vandegriend</dc:creator>
				<category><![CDATA[professional]]></category>
		<category><![CDATA[automated build]]></category>
		<category><![CDATA[deploy]]></category>
		<category><![CDATA[process]]></category>
		<category><![CDATA[refactoring]]></category>
		<category><![CDATA[software development]]></category>
		<category><![CDATA[unit testing]]></category>
		<category><![CDATA[version control]]></category>

		<guid isPermaLink="false">http://www.basilv.com/psd/blog/2007/top-five-essential-practices-for-developing-software</guid>
		<description><![CDATA[As a software developer what practices do you consider essential? Which practices are must-haves that you would refuse to build software without? I believe that producing good software is hard, and that we software developers need all the help we can get in developing software. I have put together a list of the top five [...]]]></description>
			<content:encoded><![CDATA[<p>As a software developer what practices do you consider essential? Which practices are must-haves that you would refuse to build software without?</p>
<p>I believe that <a href="http://www.basilv.com/psd/blog/2006/producing-good-software-is-hard">producing good software is hard</a>, and that we software developers need all the help we can get in developing software. I have put together a list of the top five practices that I find to be the most helpful in making it easier to produce good software:</p>
<ul>
<li><a href="#test">Automated Tests</a></li>
<li><a href="#versioncontrol">Version Control</a></li>
<li><a href="#refactoring">Refactoring</a></li>
<li><a href="#builddeploy">Repeatable Build and Deploy</a></li>
<li><a href="#communication">Communication</a></li>
</ul>
<p>These practices are generally applicable across the board: for new application development and ongoing application maintenance, for small teams and large teams, for custom enterprise software for a single customer and commercial shrink-wrap software, and for any language or technology. The specifics of how the practice is implemented will of course vary depending on the nature of the project.</p>
<h3 id="test">Automated Tests</h3>
<p>Automated unit tests provide a convenient way to test the software's functionality both during initial development and later as the software is maintained. This is especially essential during maintenance when the original developers are no longer around. Another benefit of automated tests is that they impose a design constraint upon the software that it be testable. This frequently helps improve the overall design of the software by reducing the amount of coupling between different components.</p>
<p>In order to be effective at finding defects, automated tests need to be written effectively. I have come across many examples of poorly written unit tests that are ineffective at finding defects. My article <a href="http://www.basilv.com/psd/blog/2006/how-to-write-good-unit-tests">How to write good unit tests</a> discusses this in detail.</p>
<h3 id="versioncontrol">Version Control</h3>
<p>The use of version control software to manage changes to the software is indispensable for teams larger than one person. Some of the more important benefits of version control include helping coordinate concurrent changes to the code base, providing a history of changes, tracking the versions making up a release, and supporting parallel development on different versions of the software. I even use version control for my personal projects at home, where I am the sole developer. (Read about <a href="http://www.basilv.com/psd/blog/2006/my-experience-with-subversion">my experience using Subversion</a>.)</p>
<p>Some of the problems I have observed when version control is not used are: each team member developing with a slightly different version of the software, resulting in chaos when it is time to deploy the software, and variations in the software installed in different environments, with no one able to explain for sure what the correct version is.</p>
<h3 id="refactoring">Refactoring</h3>
<p>The design of a piece of software is a critical attribute for determining its quality. While good design does not imply good software, bad design generally does imply bad software. Refactoring is the key practice by which the quality of the design can be maintained and even incrementally improved as the software changes. Refactoring is a potentially risky activity because of the possibility of introducing defects. This risk is mitigated when the software has a comprehensive suite of automated tests.</p>
<h3 id="builddeploy">Repeatable Build and Deploy</h3>
<p>Every software team has some kind of method for building and deploying their software. I wanted to emphasize repeatability because that is the essential aspect of this practice. A build and deploy process that you can repeat consistently across team members, across environments, and across different versions of the software is critical to successfully shipping your software or deploying it into production. This practice only works effectively when version control is used to define the official version of the software being built and deployed.</p>
<p>A related aspect of this practice is keeping your active development mainline in good shape, which I define as having the code compile and pass all unit tests. This allows developers to reliably check out, build, and work with the latest changes, which helps avoid integration hell.</p>
<p>For the last while I have been involved with software deployment and I have written a couple of articles on the topic: <a href="http://www.basilv.com/psd/blog/2007/architecting-for-deployability">Architecting for Deployability</a> and <a href="http://www.basilv.com/psd/blog/2007/designing-for-deployability">Designing for Deployability</a>.</p>
<p>I have encountered teams using ad-hoc build and deploy processes. I have observed such teams often experiencing production failures due to the incorrect implementation of changes into the production environment.</p>
<h3 id="communication">Communication</h3>
<p>I see the other practices frequently mentioned by software consultants and software development books, but the practice of communication seems to receive less attention. However, I consider it equally essential. Frequent and open communication between team members, across teams, and across layers of the organization are critical to producing good software. Successful large open source software projects are excellent examples of communication in action: they have multiple mailing lists, standards for discussing changes and informing others of patches, and defect or task tracking tools for communicating issues and task assignments.</p>
<p>When communication is lacking or ineffective within a team, then I have observed work being done by one team member conflicting with or disrupting the work of other team members. Poor communication between teams can be more serious: teams working on interdependent applications or components need to keep the other teams informed and involved when the interfaces between them change. I have seen failure to do so lead to schedule slippages due to the additional work being identified too late, and even production failures.</p>
<p>You may feel that some of these practices are so obvious that they are not worth discussing. For every one of these practices, however, I have encountered individuals who did not see the value of the practice or who only adopted it grudgingly. If you or your team does not follow one of these practices, I strongly recommend giving it a try.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.basilv.com/psd/blog/2007/top-five-essential-practices-for-developing-software/feed</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>The Reuse Trap in Software Design</title>
		<link>http://www.basilv.com/psd/blog/2006/the-reuse-trap-in-software-design</link>
		<comments>http://www.basilv.com/psd/blog/2006/the-reuse-trap-in-software-design#comments</comments>
		<pubDate>Thu, 07 Sep 2006 15:00:39 +0000</pubDate>
		<dc:creator>Basil Vandegriend</dc:creator>
				<category><![CDATA[design]]></category>
		<category><![CDATA[refactoring]]></category>
		<category><![CDATA[reuse]]></category>
		<category><![CDATA[software development]]></category>

		<guid isPermaLink="false">http://www.basilv.com/psd/blog/2006/the-reuse-trap-in-software-design</guid>
		<description><![CDATA[I stared at my code on the screen, but inspiration wouldn't come. I was trying to design a new feature which shared some commonalities with the existing code base. In particular, there were a couple classes that I knew I could reuse. I just wasn't sure how they would have to be modified because I [...]]]></description>
			<content:encoded><![CDATA[<p>I stared at my code on the screen, but inspiration wouldn't come. I was trying to design a new feature which shared some commonalities with the existing code base. In particular, there were a couple classes that I knew I could reuse. I just wasn't sure how they would have to be modified because I was still figuring out the structure of the new feature. This also was difficult - I didn't have a clear picture of how those reused classes would fit in. Around and around my thoughts went, without any progress. I was stuck in the reuse trap.</p>
<p>Does this story sound familiar? I have been ensnared by the reuse trap many times, especially early in my career. At first I labored in vain, wondering why I was making no progress, oblivious of the trap I was in. As I gained experience, I become aware of the reuse trap and learned techniques and skills to avoid or escape it. </p>
<p>The <em>reuse trap</em> is a term I coined to describe the situation when one becomes stuck trying to design new functionality while simultaneously attempting to reuse existing code that needs some modifications. I believe this happens because we are trying to solve two separate yet interrelated problems: one, implementing the new functionality, and two, modifying the code to be reused. The new functionality depends on the reusable code, and the way we modify this code depends on how it will be used by the new functionality. Trying to reason about both issues at the same time imposes too high a cognitive load, so we fail to make progress on either front. </p>
<p>How can we escape the reuse trap? Simply put, don't try to do two things at the same time. You need to produce the new functionality, so you can't avoid working on this problem. The solution, therefore, is to defer the code reuse problem. Trying to achieve reuse is the <a href="http://www.basilv.com/psd/blog/2006/how-to-do-root-cause-analysis">root cause</a> of this trap, and is the key to escaping it. The first step is to just start developing the new functionality. You can reuse code, but only as is, like you would do for a third party library. If you need to modify it, then just ignore it (for now). When you reach points where you could reuse existing code with some modification, feel free to take a copy of this existing code and change it as needed. This is also called cut-and-paste reuse, which is generally frowned upon. The use of it here is only temporary, as you'll see. Your goal is to finish enough of the new functionality to know that the design will work. This may mean finishing it completely, or just writing a basic skeleton. In either case, once you reach this point the next step is to eliminate duplication in the code base. Any sections of new code that you copied (cut-and-pasted) from existing code will be primary targets for your efforts. During this step, it is helpful to follow a disciplined refactoring process as described in <a href="http://www.amazon.ca/exec/obidos/redirect?link_code=as2&#038;path=ASIN/0201485672&#038;tag=basilvandegri-20&#038;camp=15121&#038;creative=330641">Martin Fowler's refactoring book</a><img src="http://www.assoc-amazon.ca/e/ir?t=basilvandegri-20&#038;l=as2&#038;o=15&#038;a=0201485672" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />. </p>
<p>In this second refactoring step, I deliberately omitted the word <em>reuse</em> and instead used the term <em>eliminating duplication</em>. Reuse implies thinking about the future - how can this code be re-used in a different context? By its very nature, it is more abstract, more uncertain, and thus more difficult to reason about. Eliminating duplication is more concrete and focused on what exists now, in the present. Adopting a mindset of eliminating duplication rather than up-front reuse therefore helps you avoid the reuse trap. This relates closely to some of the principles of <a href="http://www.amazon.ca/exec/obidos/redirect?link_code=as2&#038;path=ASIN/0321278658&#038;tag=basilvandegri-20&#038;camp=15121&#038;creative=330641">Extreme Programming</a><img src="http://www.assoc-amazon.ca/e/ir?t=basilvandegri-20&#038;l=as2&#038;o=15&#038;a=0321278658" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />: "You ain't gonna need it", "Do the simplest thing that could possibly work", and "Once and only once".</p>
<p>As your design experience grows, it becomes easier to avoid the reuse trap. You become more adept at knowing how to modify existing code to reuse it without really having to think hard about the problem. This allows you to focus on the problem of developing the new functionality, which is also likely easier. Therefore, your overall cognitive load is reduced - you can solve both problems at once - and the reuse trap is avoided. However, even experienced developers will still encounter difficult situations for which their experience is insufficient. That is when you need to know how to escape the reuse trap.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.basilv.com/psd/blog/2006/the-reuse-trap-in-software-design/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>

