<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>MPD &#187; Software Development</title>
	<atom:link href="http://blog.mpdaugherty.com/category/software-development/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.mpdaugherty.com</link>
	<description>Mike&#039;s in China, doing tech stuff</description>
	<lastBuildDate>Fri, 16 Jul 2010 13:28:55 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='blog.mpdaugherty.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://www.gravatar.com/blavatar/75d78ca4874576a82c347ee3ad1b0d45?s=96&#038;d=http://s2.wp.com/i/buttonw-com.png</url>
		<title>MPD &#187; Software Development</title>
		<link>http://blog.mpdaugherty.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://blog.mpdaugherty.com/osd.xml" title="MPD" />
	<atom:link rel='hub' href='http://blog.mpdaugherty.com/?pushpress=hub'/>
		<item>
		<title>JSLint&#8217;s &#8216;unexpected end of line&#8217; vs. JQuery style</title>
		<link>http://blog.mpdaugherty.com/2010/06/10/jslints-ambiguous-end-of-line-vs-jquery-style/</link>
		<comments>http://blog.mpdaugherty.com/2010/06/10/jslints-ambiguous-end-of-line-vs-jquery-style/#comments</comments>
		<pubDate>Thu, 10 Jun 2010 09:21:12 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[tech]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[jslint]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://blog.mpdaugherty.com/?p=291</guid>
		<description><![CDATA[I recently added a script to run JSLint over any javascript files that were changed in my last batch of commits when I push changes to our main repository (if you&#8217;re interested, you can take a look).  Immediately, I had my feelings hurt when it started reporting a bunch of errors and warnings. Most of [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.mpdaugherty.com&blog=1126752&post=291&subd=mpdaugherty&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<p>I recently added a script to run JSLint over any javascript files that were changed in my last batch of commits when I push changes to our main repository (if you&#8217;re interested, you can <a title="gitsafepush script" href="http://gist.github.com/432727">take a look</a>).  Immediately, I had my feelings hurt when it started reporting a bunch of errors and warnings.</p>
<p>Most of them I agreed with, but the ambiguous end of line warning when the line was catching syntax that I had very purposefully used to increase readability (for me). <span id="more-291"></span> Basically, this warning appears if a line doesn&#8217;t end with an operator like &#8216;+&#8217; or &#8216;.&#8217; that indicates there&#8217;s another part required.  However, I like to use these operators at the beginning of a new line in order to make it easy to scan and see which lines are continuations.</p>
<p>For example, I would write my jQuery code like this:</p>
<pre class="brush: jscript;">
$(&quot;#someId&quot;).after(&quot;&lt;br /&gt;&quot;)
     .css(&quot;color&quot;,&quot;red&quot;)
     .show();
</pre>
<p>However, this will generate &#8220;<code>lint warning: unexpected end of line; it is ambiguous whether these lines are part of the same statement</code>&#8221; for the last two lines.  Instead, JSLint expects the code to be written like this:</p>
<pre class="brush: jscript;">
$(&quot;#someId&quot;).after(&quot;&lt;br /&gt;&quot;).
     css(&quot;color&quot;,&quot;red&quot;).
     show();
</pre>
<p>To me, this makes it too easy to not notice that methods like &#8216;css&#8217; and &#8216;show&#8217; are properties of an object and not just individual methods.  On the other hand, I wasn&#8217;t sure whether it would be a good idea to just ignore a warning from lint because it would look prettier.</p>
<p>Therefore, I talked it over with my coworker, <a href="http://www.the-xavi.com/">Xavi</a>, and he suggested we turn off the Lint check for this &#8216;error&#8217;.  In addition to us, pretty much the whole jQuery community agrees with our formatting.  As long as we pay attention to the other errors in Lint, we shouldn&#8217;t be writing code with missing semi-colons.</p>
<p>To fix this, I just added a configuration file with a single line: &#8220;-ambiguous_newline&#8221;.  Once I referenced the config file in our script, these errors stopped being reported.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mpdaugherty.wordpress.com/291/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mpdaugherty.wordpress.com/291/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mpdaugherty.wordpress.com/291/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mpdaugherty.wordpress.com/291/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mpdaugherty.wordpress.com/291/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mpdaugherty.wordpress.com/291/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mpdaugherty.wordpress.com/291/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mpdaugherty.wordpress.com/291/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mpdaugherty.wordpress.com/291/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mpdaugherty.wordpress.com/291/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.mpdaugherty.com&blog=1126752&post=291&subd=mpdaugherty&ref=&feed=1" />]]></content:encoded>
			<wfw:commentRss>http://blog.mpdaugherty.com/2010/06/10/jslints-ambiguous-end-of-line-vs-jquery-style/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1789bf112f20b2b53047372a84803581?s=96&#38;d=wavatar&#38;r=G" medium="image">
			<media:title type="html">Mike</media:title>
		</media:content>
	</item>
		<item>
		<title>Vistaprint Lessons Learned &#8211; Part 1: Software Development</title>
		<link>http://blog.mpdaugherty.com/2010/02/09/vistaprint-lessons-learned-software-development/</link>
		<comments>http://blog.mpdaugherty.com/2010/02/09/vistaprint-lessons-learned-software-development/#comments</comments>
		<pubDate>Wed, 10 Feb 2010 04:05:07 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[career]]></category>

		<guid isPermaLink="false">http://blog.mpdaugherty.com/?p=191</guid>
		<description><![CDATA[Over the last two years at Vistaprint, I&#8217;ve grown a lot &#8211; both as a developer and in general.  I learned some lessons through mistakes I&#8217;ve made, things that I saw being done correctly, and by observing processes that could have been more efficient. Over the this and the next two blog posts, I&#8217;ll cover [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.mpdaugherty.com&blog=1126752&post=191&subd=mpdaugherty&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<p>Over the last two years at Vistaprint, I&#8217;ve grown a lot &#8211; both as a developer and in general.  I learned some lessons through mistakes I&#8217;ve made, things that I saw being done correctly, and by observing processes that could have been more efficient.</p>
<p>Over the this and the next two blog posts, I&#8217;ll cover the lessons I learned in three different categories &#8211; software development, career and personal development, and lessons that could be applied to a company.<span id="more-191"></span></p>
<h2>Software Development Lessons</h2>
<p><em>Lots of little bugs waste lots of time</em></p>
<p>This is similar to Jeff Atwood&#8217;s &#8220;<a title="Have You Met Your Dog, Patches?" href="http://www.codinghorror.com/blog/archives/001299.html">My Dog Patches</a>&#8221; post.  Sometimes it&#8217;s tempting to just fix the immediate symptom of a bug because it will be a quick fix.  However, a day or a week later, a similar bug will pop up again.  Even if these bugs only take a few minutes to cover up, if they have the same root cause, it&#8217;s probably worth just fixing the root.</p>
<p>I fell into the &#8216;patch, patch, patch&#8217; trap at least twice at Vistaprint.  The first one was on my first really large project when we were adding hats and dark t-shirts.  After the initial implementation of the system that changed user colors based on their chosen substrate (so text that might be black on a white background would be white on black backgrounds, etc.), we started having a lot of bugs in which a user could do some complicated series of actions and end up with the wrong color text on a given background.  We couldn&#8217;t tell if it was because the user had chosen that particular color or if we had an adjustment bug.  Most of the times that the bug came up, we&#8217;d change some path through the site to keep track of user colors.  Then, another bug would show up somewhere else.  Eventually, I realized that I was wasting at least a few hours every week and in order to do more work, I needed to stop spending time on substrates.</p>
<p>In the end, I just took a day to think about the problem and came up with a system that split some information in user documents into two parts.  This was a deep change in our model, but it allowed us to look at a document at any stage and prove an invariant &#8211; we could see what the original user-chosen colors were and that we were only overriding the non-customized colors with our substrate variants.  Thinking about this problem from an invariant model helped me prove that we would have no more problems in the future and saved me hundreds of hours in the long run.</p>
<p>The second time I can think of was when I was trying to add a lot of new functionality to one of our controls.  I decided to try to just add the new elements on top of the old code and modify that as little as possible.  Afterward, I was going to have a phase two in which I&#8217;d merge the old code and the new code completely.  However, the first version kept breaking and I kept patching local fixes to bugs in the old code that were causing bugs in the new code.  Eventually, I had wasted a week and I missed the first release.  At that point, I realized I just had to rewrite the old code from scratch.  I spent three days and rewrote the whole control to use my new components even for the old functionality.  In the process, I fixed a lot of existing bugs and finished the new requirements.  I had wasted a week trying to get something done in a day, then continually seeing each fix as a three-hour event.  Instead, I should have seen the bigger picture that I would have saved time by investing the three days up front and skipping the week of patches.</p>
<p><em>Code safely the first time</em></p>
<p>When I first started at Vistaprint, I was fresh out of school and had never worked on such a large application before.  I ended up with a lot of null-pointer exceptions in my code because I kept assuming I would get valid values from other code.  After a month of fixing these (particularly in javascript), I finally figured out that any time I have a question about a value, I should verify it first.  It&#8217;s easy code to write and it will save so much debugging time.  I also try to prove that APIs I write will always return valid values or have an explicit failure condition.  This is a much more general problem than null pointers, but that&#8217;s what really made me start checking.</p>
<p><em>Use a third party framework where applicable</em></p>
<p>Vistaprint has a lot of home-grown javascript code which is really good and well written.  However, many of it duplicates what&#8217;s available in open-source javascript frameworks like jQuery.  Every time we had to fix a bug or performance problem in our framework, that was time we may have been able to avoid if we had been using code that has been built and tested by a community.  Luckily, right as I was leaving, Vistaprint was starting to recognize this and move towards replacing some of our common code with jQuery.</p>
<p><em>Requirements will change and code will live longer than you expect</em></p>
<p>Make your work maintainable.  If you are working at a large company, one thing you should always try is searching your code base for words like &#8220;temp&#8221; or &#8220;hack&#8221;.  you&#8217;ll be shocked at how much throwaway code people thought they were writing two years ago that&#8217;s still in the code base.</p>
<p>In general, this isn&#8217;t terrible; sometimes the most important thing to do is to move forward with new work.  However, when the hack is unmaintainable, it will keep costing you time and effort over and over for the rest of its lifetime.  Vistaprint had a few places in the codebase that I can think of in particular that were written so quickly and haphazardly (large pieces of copy/paste, etc.) that they now suck the time out of anyone that has to modify them.  It&#8217;s so hard to understand and to find all the places that have to be modified to make one small change that projects take twice as long as they should.</p>
<p><em>Retire old code early and often</em></p>
<p>Part of a project is retiring whatever it is the new project is replacing.  At Vistaprint, I was stuck maining two APIs because we never had any time budgeted for upgrading the rest of the website to no longer use the legacy code.  We constantly had bugs because other teams would still use the old APIs to access new documents, and the old APIs had too many abstraction violations and were no longer being updated with new features that we were adding in the new APIs.  This went on for the entire two years and a half I was there.  Next time I replace some code, I&#8217;ll make sure we budget time for proving that the new code works just as well as the old, then I&#8217;ll upgrade everything.</p>
<p><em>Backwards compatibility is a big concern</em></p>
<p>This is somewhat related to the last point, because even when you have a plan for upgrading, you will have overlap and you can&#8217;t break a user&#8217;s experience just because they&#8217;ve saved something in an old format.  Even if your upgrade breaks some user&#8217;s information, you need to know how many and how valuable those items are.  At Vistaprint, we had too many documents to upgrade all of them whenever we made a small change to the storage format, but we made sure that documents were upgraded while they loaded.  We also had other ways to ensure backwards compatibility; it was never something we glossed over.</p>
<p><em>Large builds waste time</em></p>
<p>My friend Jim was fond of pointing out how much time we wasted at Vistaprint waiting for code to compile.  With hundreds of projects in our build, any of which might break during the nightly update from SVN, I think he has a valid point.  Even more than that, if we had used a technology that didn&#8217;t require a compilation step, we might be able to go through many more iterations of code in the same amount of time, because we could code, check localhost, code again without compile steps in the middle.  My next environment will definitely be one that does not require compilations for all web code.</p>
<p><em>If you want to unit test, do it from the beginning</em></p>
<p>Coding for testability requires a different type of architecture than just coding for features.  About a year into my tenure at Vistaprint, I tried to help out in a big push to add unit tests to our code, but I found adding tests required massive amounts of rearchitecture to allow us to mock important components.  I was able to get some unit tests in, but the effort mostly faded out because of the difficulty in creating them.</p>
<p>I&#8217;m not entirely convinced of the utility of having comprehensive unit testing coverage, either.  I hear a main benefit of unit tests is that they enable fearless refactoring, because you know the components still fulfill their contracts.  However, most of the time we did any significant refactoring, it involved changing APIs and therefore the unit tests also had to be rewritten.  If we&#8217;re rewriting the tests when we change the code, I&#8217;m not sure their actually preventing mistakes, since we&#8217;ll probably make a similar mistake in the test as we did in the code.  I&#8217;ll probably go with a strong set of functional tests in my next project.</p>
<p><em>Performance counts, and applications should be performance tested</em></p>
<p>This can make a big difference to user experience, as well as affecting the bottom line of things like CPU usage.  However, this is not to say that you should try to pre-optimize code while you write it.  Some of the most productive days I spent at Vistaprint involved running code with a profiler.  We were always able to significantly increase performance, and the places we made the performance gains were not necessarily where we would have guessed at first.  Moreover, we were able to keep the code readable and maintainable while still increasing the performance.  I read a great quote the other day in &#8216;Coders at Work&#8217; &#8211; &#8220;It&#8217;s much easier to optimize correct code than it is to correct optimized code.&#8221;</p>
<p><em>When optimizing, know when to stop</em></p>
<p>This applies to optimizing anything, not just performance.  If you get sucked into making something the &#8216;best possible&#8217;, you can quickly reach diminishing returns and end up paying for it in other ways.  I did this one time when trying to determine the best algorithm for manipulating images to print correctly on hats.  I spend a week trying different parameters and algorithms to make the image perfect, but in the end, my final result was hardly noticeably different than what I had on the second day.  If I&#8217;d stopped then, no one would have been less satisfied, and I would have had three days to work on other projects.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mpdaugherty.wordpress.com/191/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mpdaugherty.wordpress.com/191/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mpdaugherty.wordpress.com/191/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mpdaugherty.wordpress.com/191/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mpdaugherty.wordpress.com/191/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mpdaugherty.wordpress.com/191/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mpdaugherty.wordpress.com/191/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mpdaugherty.wordpress.com/191/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mpdaugherty.wordpress.com/191/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mpdaugherty.wordpress.com/191/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.mpdaugherty.com&blog=1126752&post=191&subd=mpdaugherty&ref=&feed=1" />]]></content:encoded>
			<wfw:commentRss>http://blog.mpdaugherty.com/2010/02/09/vistaprint-lessons-learned-software-development/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1789bf112f20b2b53047372a84803581?s=96&#38;d=wavatar&#38;r=G" medium="image">
			<media:title type="html">Mike</media:title>
		</media:content>
	</item>
		<item>
		<title>SVN Haiku</title>
		<link>http://blog.mpdaugherty.com/2009/03/10/svn-haiku/</link>
		<comments>http://blog.mpdaugherty.com/2009/03/10/svn-haiku/#comments</comments>
		<pubDate>Tue, 10 Mar 2009 14:36:02 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[miscellaneous]]></category>
		<category><![CDATA[programming haiku]]></category>

		<guid isPermaLink="false">http://mpdaugherty.wordpress.com/2009/03/10/svn-haiku/</guid>
		<description><![CDATA[Here&#8217;s my comment for my latest SVN commit: How can I forget? Don&#8217;t access variables, Unless they&#8217;re not null. Bug-ID GD-34785<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.mpdaugherty.com&blog=1126752&post=167&subd=mpdaugherty&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s my comment for my latest SVN commit:</p>
<p>How can I forget?<br />
Don&#8217;t access variables,<br />
Unless they&#8217;re not null.<br />
Bug-ID GD-34785</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mpdaugherty.wordpress.com/167/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mpdaugherty.wordpress.com/167/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mpdaugherty.wordpress.com/167/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mpdaugherty.wordpress.com/167/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mpdaugherty.wordpress.com/167/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mpdaugherty.wordpress.com/167/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mpdaugherty.wordpress.com/167/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mpdaugherty.wordpress.com/167/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mpdaugherty.wordpress.com/167/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mpdaugherty.wordpress.com/167/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.mpdaugherty.com&blog=1126752&post=167&subd=mpdaugherty&ref=&feed=1" />]]></content:encoded>
			<wfw:commentRss>http://blog.mpdaugherty.com/2009/03/10/svn-haiku/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1789bf112f20b2b53047372a84803581?s=96&#38;d=wavatar&#38;r=G" medium="image">
			<media:title type="html">Mike</media:title>
		</media:content>
	</item>
	</channel>
</rss>