<?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>zobie&#039;s blog &#187; Software Development</title>
	<atom:link href="http://blog.zobie.com/category/software_development/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.zobie.com</link>
	<description>I create software, I like music and I&#039;m mildly(?) OCD.</description>
	<lastBuildDate>Thu, 13 Oct 2011 14:32:09 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<item>
		<title>zVision is the future!</title>
		<link>http://blog.zobie.com/2011/10/zvision-is-the-future/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=zvision-is-the-future</link>
		<comments>http://blog.zobie.com/2011/10/zvision-is-the-future/#comments</comments>
		<pubDate>Thu, 13 Oct 2011 14:27:33 +0000</pubDate>
		<dc:creator>zobie</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[saas]]></category>
		<category><![CDATA[soa]]></category>
		<category><![CDATA[srs]]></category>
		<category><![CDATA[srswp]]></category>

		<guid isPermaLink="false">http://blog.zobie.com/?p=258</guid>
		<description><![CDATA[This internal memo was sent to SRS Software this morning. The points are important enough that I wanted to cross-post here. Team, I know there has been a lot of frustration over the last year as we have been working on zVision, the web platform, and ReEn. The shift we are making takes us from [...]]]></description>
			<content:encoded><![CDATA[<p>This internal memo was sent to SRS Software this morning. The points are important enough that I wanted to cross-post here.<br />
</p>
<hr />
<br />
Team,</p>
<p>I know there has been a lot of frustration over the last year as we have been working on zVision, the web platform, and ReEn. The shift we are making takes us from creating products to the creation of a platform.</p>
<p>So far, most have only felt the pain of the transition and have not seen the advantages. I promise you that this transition will be worth the pain and frustration. We are on the cusp of realizing a payout and it will be huge!</p>
<p>A guy who worked at Amazon and is currently at Google recently posted what was intended to be an internal memo on this topic. <strong><em>Everyone should take time to study the attached memo (<a href="http://steverant.pen.io">http://steverant.pen.io</a>) and understand the points that are made.</em></strong></p>
<p>Here are a couple of threads where people are discussing Stevey’s memo that you may find useful:</p>
<ul>
<li><a href="https://plus.google.com/112678702228711889851/posts/eVeouesvaVX">https://plus.google.com/112678702228711889851/posts/eVeouesvaVX</a></li>
<li><a href="http://www.reddit.com/r/programming/comments/l9ehj/steves_google_platform_rant/">http://www.reddit.com/r/programming/comments/l9ehj/steves_google_platform_rant/</a></li>
</li>
</ul>
<p>I will continue to do everything I can to clearly communicate the amazing direction we are headed.</p>
<ul>
<li>zVision puts us at the forefront of the technology industry!</li>
<li>zVision is the platform we need to carry us for the next 10+ years!</li>
<li>zVision will give SRS the flexibility and agility to dominate in our chosen market!</li>
</li>
</ul>
<p>You are welcome to send me questions or comments privately. Alternatively, I have cross-posted this to my blog and you are also welcome to publically comment there.</p>
<ul>
<li><a href="http://blog.zobie.com">http://blog.zobie.com</a></li>
</ul>
<p>- Nate</p>
<p>Nate Zobrist | VP of Software Architecture<br />
Service Repair Solutions, Inc. — Revolutionizing the Delivery of Service and Repair&trade;</p>
<p>770 East Technology Avenue, Building F | Orem, Utah 84097<br />
Phone: (801) 437-5846 | Fax: (801) 437-5899 | Cell: (801) 788-4789<br />
www.servicerepairsolutions.com</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.zobie.com/2011/10/zvision-is-the-future/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Creating Apps Should Be Trivial!</title>
		<link>http://blog.zobie.com/2011/09/creating-apps-should-be-trivial/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=creating-apps-should-be-trivial</link>
		<comments>http://blog.zobie.com/2011/09/creating-apps-should-be-trivial/#comments</comments>
		<pubDate>Mon, 26 Sep 2011 21:07:43 +0000</pubDate>
		<dc:creator>zobie</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[archiecture]]></category>
		<category><![CDATA[soa]]></category>
		<category><![CDATA[srs]]></category>
		<category><![CDATA[srswp]]></category>

		<guid isPermaLink="false">http://blog.zobie.com/?p=243</guid>
		<description><![CDATA[At Dreamforce '11, a presentation I particularly enjoyed was given by Ryan Smith from Heroku. Titled Designing for the Cloud: The 12 Factor App, Ryan discussed some fundamental design patterns and practices that have made Heroku successful. An interesting analogy that was made compares applications to swiss army knives. The analogy is relevant to SRS [...]]]></description>
			<content:encoded><![CDATA[<p>At Dreamforce '11, a presentation I particularly enjoyed was given by <a href="http://twitter.com/ryandotsmith">Ryan Smith</a> from <a href="http://heroku.com">Heroku</a>. Titled <em><a href="https://dreamevent.my.salesforce.com/a093000000CeqeV">Designing for the Cloud: The 12 Factor App</a></em>, Ryan discussed some fundamental design patterns and practices that have made Heroku successful.</p>
<p>An interesting analogy that was made compares applications to swiss army knives. The analogy is relevant to SRS and provides a great visual depiction of the work we are doing as part of our SaaS and SRSWP initiatives.</p>
<p><img class="alignright" style="border-style: initial; border-color: initial; border-width: 0px;" src="http://blog.zobie.com/wp-content/uploads/2011/09/swiss_army_knife_giant.png" alt="swiss_army_knife_giant.png" width="250" height="185" border="0" />Historically our applications were designed as large, monolithic beasts. Like this knife, every feature that could be imagined was rolled into one of our flagship products. This design meant:</p>
<ul>
<li>Duplicated effort because there were no shared components between product lines.</li>
<li>Intense effort required to join the team due to the large, interconnected designs.</li>
<li>Even small changes were risky and had the potential of destabilizing anentire product.</li>
<li>Management of each product line required enormous effort to tightly coordinate development and release of new features.</li>
</ul>
<p><img class="alignright" style="border-style: initial; border-color: initial; border-width: 0px;" src="http://blog.zobie.com/wp-content/uploads/2011/09/swiss_army_classic.png" alt="swiss_army_classic.png" width="250" height="169" border="0" />Contrast that complexity with a design where:</p>
<ul>
<li>Components are small, independent apps that work together (like Linux tools).</li>
<li>Each component delivers specific functionality.</li>
<li>Touch points between components are<a href="http://blog.zobie.com/2011/09/contract-definition-and-stability">well-defined contracts</a>.</li>
</ul>
<p>The workflow enabled by this component-based architecture is truly liberating.</p>
<ul>
<li>Small teams (perhaps even a single-person team) can build on top of the shared platform to quickly create new products.
<ul>
<li>Most products do not need to worry about operational infrastructure, databases, etc.</li>
<li>Products can take advantage of shared services to quickly enable powerful features in innovative ways.</li>
<li>Products can tap into shared repositories of both customer-generated and catalog data.</li>
</ul>
</li>
<li>Existing products are simpler to maintain and introducing change is far less risky.
<ul>
<li>A smaller codebase means that the project is much easier to grok.</li>
<li>Well-defined contracts that have robust automated tests written against them mean that each component can be released independently with confidence.</li>
</ul>
</li>
<li>Teams can work more efficiently by choosing technologies and frameworks that are tailored to fit specific needs.
<ul>
<li>Using standards-compliant web services for an API means that apps written in Java, Ruby on Rails or Node.js can access shared services as easily as a legacy, .NET application.</li>
</ul>
</li>
</ul>
<p>Following a component-based approach will make the creation of new apps a trivial exercise. It will free us to focus on solving interesting problems rather than being bogged down by operational overhead. The quality of our offering will increase as we become much more responsive to customers.</p>
<p>Applying these principles means something different for each of our existing projects and teams. What remains to be done for your team to fully benefit from this component-based design? What new functionality would you like to see exposed by the SRSWP?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.zobie.com/2011/09/creating-apps-should-be-trivial/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Contract Definition and Stability</title>
		<link>http://blog.zobie.com/2011/09/contract-definition-and-stability/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=contract-definition-and-stability</link>
		<comments>http://blog.zobie.com/2011/09/contract-definition-and-stability/#comments</comments>
		<pubDate>Sat, 17 Sep 2011 18:39:34 +0000</pubDate>
		<dc:creator>zobie</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[saas]]></category>
		<category><![CDATA[soa]]></category>
		<category><![CDATA[srs]]></category>
		<category><![CDATA[srswp]]></category>

		<guid isPermaLink="false">http://blog.zobie.com/?p=238</guid>
		<description><![CDATA[In my first zVision presentation that was recently given at each of the SRS offices, I identified one of Engineering's current problems as an "absence of trust" between teams. This phrase caused some confusion that I would like to clarify. Let's say I want to write an app that integrates with the del.icio.us bookmarking service. [...]]]></description>
			<content:encoded><![CDATA[<p>In my first zVision presentation that was recently given at each of the SRS offices, I identified one of Engineering's current problems as an "absence of trust" between teams. This phrase caused some confusion that I would like to clarify.</p>
<p>Let's say I want to write an app that integrates with the <a href="http://del.icio.us">del.icio.us</a> bookmarking service. My application will be reliant on their <a href="http://www.delicious.com/help/api">public API</a>. So, for this venture to be successful:</p>
<p>The API's <strong><em>Contract Definition</em></strong> is essential:</p>
<ul>
<li>Method descriptions, examples, limitations and assumptions are all necessary and are included as part of the API documentation.</li>
</ul>
<p>The API's <strong><em>Contract Stability</em></strong> is essential:</p>
<ul>
<li>Breaking changes should be very rare. Even with a disclaimer stating that it may change at any time, there is an implied level of stability in any published API.</li>
<li>When a breaking change to the API is necessary, backwards compatibility will be provided. That's why their APIs all have "v1" in them!</li>
</ul>
<p>Within SRS we should think about cross-project integration similarly to integrating with external services like del.icio.us. Except in very rare situations, touch points between products are limited to APIs (i.e. massively-versioned web services).</p>
<p>When I referred to "absence of trust" in zVision, I call attention to the fact that we do not yet have the requisite level of Contract Definition and Contract Stability in our APIs. Without both definition and stability, I could not trust the del.icio.us API enough to base my app on it. The same is true for building on SRS-internally produced services.</p>
<p>Since the end of 2010 and through 2012 we are making a large investment in re-architecting our products based on principles of SOA and SaaS. Absolutely essential to success are APIs which are both well defined and stable. Once we have those things, we can trust the services provided by other SRS teams as much as we would trust del.icio.us.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.zobie.com/2011/09/contract-definition-and-stability/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Source Code Management</title>
		<link>http://blog.zobie.com/2010/02/source-code-management/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=source-code-management</link>
		<comments>http://blog.zobie.com/2010/02/source-code-management/#comments</comments>
		<pubDate>Wed, 10 Feb 2010 00:12:46 +0000</pubDate>
		<dc:creator>zobie</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[srs]]></category>
		<category><![CDATA[tfs]]></category>

		<guid isPermaLink="false">http://blog.zobie.com/?p=210</guid>
		<description><![CDATA[Note: This blog post was originally posted to an internal SRS blog on February 09, 2010. The post was intended to address specific issues, but I do strongly support the idea of "commit early and often" as a general principle. Source Code Management Source control is a fundamental part of software development. The benefits of [...]]]></description>
			<content:encoded><![CDATA[<p><em>Note: This blog post was originally posted to an <a href="http://home.mpifix.com/Teams/development/blog/Lists/Posts/Post.aspx?ID=56">internal SRS blog</a> on February 09, 2010. The post was intended to address specific issues, but I do strongly support the idea of "commit early and often" as a general principle.</em></p>
<h2>Source Code Management</h2>
<p>Source control is a fundamental part of software development. The benefits of using a source control management (SCM) system are numerous and worthy of their own blog post. But, I have noticed two significant problems with the way that SCM is currently being used on many of our projects:</p>
<ol>
<li>ChangeSets are frequently too large</li>
<li>ChangeSets often contain code that shouldn't be committed</li>
</ol>
<h3>ChangeSets Are Too Large</h3>
<p>I am frequently guilty of working for days on a particular task without committing any changes to source control. I like to wait until my task is completed. I don't want to break the build, and I don't want to commit broken code that might impede others. But, the biggest reason that I avoid committing my working code is that I don't want anyone to see it until I'm finished.</p>
<p>There are several problems with monolithic commits, including:</p>
<ul>
<li>Integration headaches: large ChangeSets increase the odds that changes will conflict with someone else's changes</li>
<li>Useless file history: comments on large ChangeSets are, of necessity, more vague and less likely to convey useful information</li>
</ul>
<p>My preferred <a href="http://git-scm.com">version control software</a> at the moment is a <a href="http://en.wikipedia.org/wiki/Distributed_Version_Control_System">DVCS</a>. DVCSs offer many benefits over traditional SCMs, but one of the best is easy branching and merging. A DVCS allows me to work like this:</p>
<blockquote><p><strong>Branch per Task</strong></p>
<p>Every development task is a new, independent branch. Tasks are merged into the permanent main branch as they are completed.</p>
<p><img src="http://blog.zobie.com/wp-content/uploads/2011/09/branch-per-task.png" alt="Branch Per Task" width="432" height="145" border="0" /></p>
<p>(from <a href="http://www.codinghorror.com/blog/2007/10/software-branching-and-parallel-universes.html">Coding Horror</a>)</p></blockquote>
<p>Each time I am ready to begin a new task I create a branch for all work on that task. I generally have several active working branches that I can easily switch between. I check in code often to my working branch, rarely going more than a few hours between commits. Once I have finished working on a particular task, I merge my completed code back into the shared master branch. I am able to make frequent commits without breaking the master branch due to incomplete code.</p>
<p>Unfortunately, TFS does not easily support this style of development. Creating branches is inconvenient, and merging code between branches is torture. Although I would love to recommend that SRS adopt the style of development that I've described, I just don't believe that it is feasible with current versions of TFS. Given the painful nature of branching and merging in TFS, I don't see a better alternative to our current branch per-release strategy.</p>
<p>Given that TFS doesn't provide easy branching and merging, here's what we can do to find a happy medium. We should not check in broken code, but we shouldn't hesitate to check in code that is incomplete. Especially for new functionality, there shouldn't be any problem checking in a stub method that doesn't do anything. There are very few, if any, situations where we would be unable to commit our working code to TFS once a day.</p>
<p>There will no doubt be times where checking in small, granular ChangeSets will not be practical. There will be times when some of our tasks require us to break the application (not the build though!) in order to complete a task. However, it is my belief that with a little planning these times should be brief and infrequent.</p>
<p>It would be foolhardy to ignore the problems that accompany frequent check-ins. As the number of developers working in the same code base increases, so too does the probability that someone will check in something that will disrupt everyone else's work. This leads directly into my second topic: We must be aware of the code that we are checking in.</p>
<h3>ChangeSets Contain Code They Shouldn't</h3>
<p>When it is time to commit code to TFS, it is not uncommon for developers to simply check every file listed in VisualStudio's "Pending Changes" window and commit all outstanding changes. Although VisualStudio makes it incredibly easy to follow this bad practice (Why are all modified files checked by default?!?), we need to stop doing it. Sometimes debug code is committed and leads to problems that are only discovered after our customers have the release. Sometimes builds are broken as csproj and sln files are inadvertently modified. Sometimes it simply messes up the file's history (TFS always increments the version and updates the file's history, regardless of whether anything in the file has changed). These things should not happen. <em>When checking code into SCM it is the developer's responsibility to verify every change that is being made. The developer should diff <strong>all</strong> changed files and verify <strong>every</strong> change that will be committed.</em></p>
<p>If anyone has found and enabled the option in VisualStudio to "Check in everything when closing a solution or project," please disable it immediately. No good can come from that option!</p>
<p style="text-align: center;"><a href="http://blog.zobie.com/wp-content/uploads/2010/02/CheckInEverythingWhenClosingASolutionOrProject.png"><img class="size-full wp-image-211 aligncenter" src="http://blog.zobie.com/wp-content/uploads/2010/02/CheckInEverythingWhenClosingASolutionOrProject.png" alt="Check in everything when closing a solution or project" width="543" height="321" /></a></p>
<p>In some cases you may imagine that these procedures don't apply to you because you are the only developer on your team. That is a false assumption. Code should always be written for the long-term. Code should <em>always</em> be written and commented in such a way that another developer can pick up your tasks at any time. Julian Bucknall, the CTO of Developer Express, recently posted a thought to his blog that precisely expresses the point I am trying to make: <a href="http://community.devexpress.com/blogs/ctodx/archive/2010/01/27/devexpress-newsletter-20-message-from-the-cto.aspx">Assume your code will be public</a>. I am as guilty as anyone — probably more so, actually — of some of the bad practices that Mr. Bucknall describes. Edge Legacy is full of funny names and informal comments that I wrote to amuse myself. As we consider publishing more of our APIs for external consumption, it is increasingly important that the code we write properly represents the professional nature of SRS and increases the trust that our customers have in us.</p>
<h3>See Also</h3>
<ul>
<li><a href="http://msdn.microsoft.com/en-us/library/aa730834(VS.80).aspx">MSDN: Branching and Merging Primer</a></li>
<li><a href="http://www.codinghorror.com/blog/archives/001165.html">Coding Horror: Check In Early, Check In Often</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.zobie.com/2010/02/source-code-management/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using P4Merge with Team Foundation Server</title>
		<link>http://blog.zobie.com/2009/04/using-p4merge-with-team-foundation-server/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=using-p4merge-with-team-foundation-server</link>
		<comments>http://blog.zobie.com/2009/04/using-p4merge-with-team-foundation-server/#comments</comments>
		<pubDate>Thu, 30 Apr 2009 10:04:49 +0000</pubDate>
		<dc:creator>zobie</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[tfs]]></category>

		<guid isPermaLink="false">http://blog.zobie.com/?p=157</guid>
		<description><![CDATA[I've found that the best way to deal with merging is to avoid it completely! Unfortunately that is rarely realistic. So, assuming you don't want to take any radical measures to completely avoid merging in TFS, you should at least use the best tools available. My favorite merge tool is the freely available (and cross-platform) [...]]]></description>
			<content:encoded><![CDATA[<p>I've found that the best way to deal with merging is to avoid it completely! Unfortunately that is rarely realistic. So, assuming you don't want to take <a href="http://blog.zobie.com/2009/04/using-git-to-avoid-problems-with-tfs">any radical measures</a> to completely avoid merging in TFS, you should at least use the best tools available. My favorite merge tool is the freely available (and cross-platform) <a href="http://www.perforce.com/perforce/downloads/platform.html">P4Merge</a>.</p>
<p>Getting TFS to use P4Merge isn't difficult but neither is it intuitive. For a merge operation P4Merge expects four files to exist:</p>
<ol>
<li>the original, base file</li>
<li>file with conflicting change #1</li>
<li>file with conflicting change #2</li>
<li>final, merged file</li>
</ol>
<p>Unfortunately TFS doesn't create the merged file (#4) until after the merge tool is invoked. A simple batch script will solve the problem though. Save this as <code>p4merge.bat</code>.</p>

<div class="wp_syntax"><div class="code"><pre class="winbatch" style="font-family:monospace;"><span style="color: #66cc66;">@</span>ECHO <span style="color: #0080FF; font-weight: bold;">OFF</span>
COPY <span style="color: #66cc66;">/</span>Y NUL <span style="color: #ff0000;">&quot;&quot;</span><span style="color: #66cc66;">%</span>4<span style="color: #ff0000;">&quot;&quot;</span>
START <span style="color: #66cc66;">/</span><span style="color: #0080FF; font-weight: bold;">WAIT</span> <span style="color: #66cc66;">/</span>D <span style="color: #ff0000;">&quot;C:\Program Files\Perforce\&quot;</span> p4merge.exe <span style="color: #ff0000;">&quot;&quot;</span><span style="color: #66cc66;">%</span>1<span style="color: #ff0000;">&quot;&quot;</span> <span style="color: #ff0000;">&quot;&quot;</span><span style="color: #66cc66;">%</span>2<span style="color: #ff0000;">&quot;&quot;</span> <span style="color: #ff0000;">&quot;&quot;</span><span style="color: #66cc66;">%</span>3<span style="color: #ff0000;">&quot;&quot;</span> <span style="color: #ff0000;">&quot;&quot;</span><span style="color: #66cc66;">%</span>4<span style="color: #ff0000;">&quot;&quot;</span></pre></div></div>

<p>This script will create the merge file and invoke p4merge.exe.</p>
<p>Now you can configure TFS to use P4Merge by running this command from a Visual Studio command prompt: <code>tf diff /configure</code></p>
<p><a title="Visual Studio Command Prompt" href="http://www.flickr.com/photos/zobrist/3464483878/"><img src="http://farm4.static.flickr.com/3520/3464483878_e82493ea2e.jpg" alt="Visual Studio Command Prompt" width="500" height="253" /></a></p>
<p>That will bring up a dialog:</p>
<p><a title="Configure User Tools" href="http://www.flickr.com/photos/zobrist/3464483882/"><img src="http://farm4.static.flickr.com/3553/3464483882_f839fe46e4_o.png" alt="Configure User Tools" width="402" height="247" /></a></p>
<p>If an entry already exists for the Merge operation you can add it. Otherwise just modify the existing entry to point to the batch file we created:</p>
<p><a title="Configure Tool" href="http://www.flickr.com/photos/zobrist/3464483884/"><img src="http://farm4.static.flickr.com/3494/3464483884_c1dea28349_o.png" alt="Configure Tool" width="355" height="196" /></a></p>
<p>Note that you must set the command to be your batch file, not the executable.</p>
<p>And that's it! Next time TFS launches a merge tool, it will use P4Merge.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.zobie.com/2009/04/using-p4merge-with-team-foundation-server/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Using git to avoid problems with TFS</title>
		<link>http://blog.zobie.com/2009/04/using-git-to-avoid-problems-with-tfs/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=using-git-to-avoid-problems-with-tfs</link>
		<comments>http://blog.zobie.com/2009/04/using-git-to-avoid-problems-with-tfs/#comments</comments>
		<pubDate>Tue, 21 Apr 2009 05:29:24 +0000</pubDate>
		<dc:creator>zobie</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[tfs]]></category>

		<guid isPermaLink="false">http://blog.zobie.com/?p=148</guid>
		<description><![CDATA[For the past few months I've been using Team Foundation Server (TFS) at work. I'm certainly not a TFS expert; I probably don't even quality as a power-user. But I've used TFS enough to have found a handful of things that I like about it. Revision control is not among those things. As a software [...]]]></description>
			<content:encoded><![CDATA[<p>For the past few months I've been using <a href="http://en.wikipedia.org/wiki/Team_Foundation_Server">Team Foundation Server (TFS)</a> at work. I'm certainly not a TFS expert; I probably don't even quality as a power-user. But I've used TFS enough to have found a handful of things that I like about it. Revision control is <strong>not</strong> among those things.</p>
<p>As a software version control system, I dislike TFS intensely.</p>
<p>In the short time I've been using TFS I've had several problems with code that was merged incorrectly. I've seen problems where TFS silently allowed older versions of code to overwrite newer versions. I could probably fill an entire blog post airing grievances with TFS but I thought it would be more interesting to describe how I use git on top of TFS to solve some of these problems.</p>
<p>First, to use git to track a TFS repository it is really important that all your source code be on a Fat32 partition. TFS locks files and NTFS respects that lock. Fat32 will track the lock but doesn't enforce it. This allows git to modify files (change to different versions of files) without necessarily having those files checked out in TFS.</p>
<p>Using TFS I checked out all my code into <code>s:\src</code>. I then created a new git repository in that same directory and added everything into the git repository.</p>
<p>For working I maintain at least two branches. My <code>master</code> branch always matches TFS. When I need the latest code from TFS I switch to the git <code>master</code> branch, pull from TFS then commit all changes into git. My <code>working</code> branch contains my current code changes. I also have one branch <code>dev</code> that contains a single commit consisting of all my debug code that should never be checked in to TFS.</p>
<p>When I'm ready to start coding I get the latest code from TFS and commit those changes into git's master branch. I create a new git branch, <code>working</code>. I cherry pick my development code from <code>dev</code> into <code>working</code>. Then I do all my coding on that branch. When I need to get code from TFS I can swtich to <code>master</code>, update from TFS, check that code in to git then either merge or rebase the changes back into <code>working</code>.</p>
<p>Once all of my changes in <code>working</code> are complete I need to merge the changes back into <code>master</code> so that I can commit them to TFS. I can't do a straight merge becuase my cherry-picked dev code would be included. So I have two ways of doing this:</p>
<ol>
<li>cherry-pick changes from <code>working</code>, applying them to <code>master</code></li>
<li>backout the development code (using <code>git rebase -i</code>) then merge changes back into <code>master</code></li>
</ol>
<p>After going through one of these two options I end up back on <code>master</code> with all of my code changes. I then commit the changes to TFS. Once that is done I delete <code>working</code> and recreate it from <code>master</code> next time I need it.</p>
<p>Working like this has been great for me. If there are conflicts when merging my code changes, git takes care of it. This way I can almost always avoid having to let TFS merge anything.</p>
<p>This is my general way of working but you can easily see how to apply these same principles when you want to work on multiple different changes using multiple different branches in git.</p>
<p>One thing to note: When you're working like this git's history isn't great. This isn't like git-svn where you get a seperate git revision for every svn revision. For me, using git with TFS isn't about being able to track my changes over time. I just want to make sure that my changes aren't lost and I don't want to clobber anyone else's changes.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.zobie.com/2009/04/using-git-to-avoid-problems-with-tfs/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Thoughts on Doing Contract Work as a Software Developer</title>
		<link>http://blog.zobie.com/2009/03/thoughts-on-doing-contract-work-as-a-software-developer/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=thoughts-on-doing-contract-work-as-a-software-developer</link>
		<comments>http://blog.zobie.com/2009/03/thoughts-on-doing-contract-work-as-a-software-developer/#comments</comments>
		<pubDate>Wed, 11 Mar 2009 07:07:21 +0000</pubDate>
		<dc:creator>zobie</dc:creator>
				<category><![CDATA[Personal]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[business]]></category>
		<category><![CDATA[job search]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[startup]]></category>

		<guid isPermaLink="false">http://blog.zobie.com/?p=131</guid>
		<description><![CDATA[As I was recently looking for new employment I spent quite a bit of time deciding wether I might enjoy doing contract work full-time. I enjoy working on different projects and learning new things but there is one major roadblock to becoming a full-time contract developer. My personality doesn't let me write software that is [...]]]></description>
			<content:encoded><![CDATA[<p>As I was recently looking for new employment I spent quite a bit of time deciding wether I might enjoy doing contract work full-time. I enjoy working on different projects and learning new things but there is one major roadblock to becoming a full-time contract developer. My personality doesn't let me write software that is anything less than my best.</p>
<p><strong>WARNING:</strong> Gross generalizations and simplifications below. I'm not trying to offend anyone, just describe my experiences.</p>
<p>Most of the contract work I've done has been for people who are not technically savvy. They come to me with a <em>very</em> vague idea of the software they want. They expect me to tell them how much it will cost before we've discussed specific requirements. When the requirements are incomplete or incorrect they expect that I'll just fix it without additional cost to them.</p>
<p>Not all of my contract experience has been negative. In fact, most of it has worked out quite well. Usually both my client and myself are pleased with the software and the cost of building it. But I've had enough negative experiences to be careful when considering a new job.</p>
<p>Part of the problem is that it is nearly impossible for anyone to completely define the scope of a project. There is always some miscommunication or misunderstanding, there is always some unforseen problem.</p>
<blockquote><p>"You want me to setup a blog for your company? No problem, I can get WordPress setup for you in an hour."</p>
<p>"Wait, I didn't realize that by 'blog' you meant store front application that can accept payments, handle accounts payable, accounts receivable and inventory tracking. That will take slightly more than an hour."</p>
</blockquote>
<p>That kind of situation actually isn't bothersome to me. As a contractor it is part of my job to understand what you want before making a bid. If a potential client obviously doesn't know what they want, I can either decline to bid on that job or I can adjust my bid to account for a large amount of unknown. I don't love it, but that type of risk is manageable.</p>
<p>The part of contract work that I dislike is being forced to compromise quality. When I'm working on a fixed cost contract, it is in my best interest to deliver exactly what is specified, as quickly as possible. As long as my client is reasonably happy with the deliverable, I am going to get paid $20k regardless of whether it took two days, two weeks or two months to create. I don't get additional money for clean code. I don't get extra for having good test coverage.</p>
<p>When I complete a project more quickly than I had anticipated there is no problem. I can spend time verifying that the code is tight and that everything is working as expected. But if I am running behind schedule, it becomes more difficult to care about testing the code or fixing "little" bugs.</p>
<p>There may be a bug in the code where order totals aren't calculated correctly, but what are the odds that my client will notice the bug before he signs off on the project? If he does find the problem and I correct it, will he think to test for that same bug in every release?</p>
<p>This is the dilemma that makes contract work difficult for me. If I see a bug in my code, I'm going to fix it. If I'm writing a tricky or important calculation (like calculating totals), I'm going to write a test. I need to have confidence that my code is doing what I expect. I've never shipped any software that didn't have a list of known bugs but I have also never shipped any software in which I didn't have a high level of confidence that it was working correctly.</p>
<p>For me, doing the bare minimum isn't an option for two reasons:</p>
<ol>
<li>Quality is <em>extremely</em> important to me. I can't just hack something together that meets the contract requirements. When I write software, I want to deliver my personal best.</li>
<li>Most of the time, the fast/crappy way of implementing something simply doesn't occur to me.</li>
</ol>
<p>I understand a company's need to understand cost before approving custom softare. But if you want me to do contract work, pay me on an hourly basis. I'll give you a projected timeline for project completion.</p>
<p>With an hourly rate, you only pay me for the time I actually spend working. With an hourly rate I know that I won't lose money just because I insist on high-quality code. We'll both be happier in the long run.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.zobie.com/2009/03/thoughts-on-doing-contract-work-as-a-software-developer/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>The Rest of My Development Environment</title>
		<link>http://blog.zobie.com/2009/02/the-rest-of-my-development-environment/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=the-rest-of-my-development-environment</link>
		<comments>http://blog.zobie.com/2009/02/the-rest-of-my-development-environment/#comments</comments>
		<pubDate>Fri, 27 Feb 2009 07:22:01 +0000</pubDate>
		<dc:creator>zobie</dc:creator>
				<category><![CDATA[Personal]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[cocoa]]></category>
		<category><![CDATA[objective-c]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://blog.zobie.com/?p=126</guid>
		<description><![CDATA[As a professional software developer the vast majority of my experience has been working on C#.NET WinForm applications. I started using .NET shortly before the 1.0 framework was released. I can't remember if I ever did .NET development under Windows 2000; I generally use Windows XP. If you're wondering why I don't use Vista I [...]]]></description>
			<content:encoded><![CDATA[<p>As a professional software developer the vast majority of my experience has been working on <a href="http://en.wikipedia.org/wiki/C_Sharp_(programming_language)">C#</a><a href="http://en.wikipedia.org/wiki/.NET_Framework">.NET</a> <a href="http://en.wikipedia.org/wiki/Windows_Forms">WinForm</a> applications. I started using .NET shortly before the 1.0 framework was released. I can't remember if I ever did .NET development under Windows 2000; I generally use Windows XP. If you're wondering why I don't use Vista I have to assume that you've never tried Vista yourself. It's not good. I'm waiting for Windows 7 and hoping for the best.</p>
<p>The tools that I use for C#.NET are pretty standard:</p>
<ul>
<li><a href="http://en.wikipedia.org/wiki/Microsoft_Visual_Studio#Visual_Studio_2008">Microsoft Visual Studio 2008</a> (with <a href="http://www.jetbrains.com/resharper/">ReSharper</a>)</li>
<li><a href="http://en.wikipedia.org/wiki/SQL_Server_Management_Studio">SQL Server Management Studio</a></li>
<li><a href="http://memprofiler.com/">.NET Memory Profiler</a> to chase down memory leaks</li>
<li><a href="http://www.automatedqa.com/products/aqtime/">AQtime</a> to help locate performance problems</li>
<li><a href="http://en.wikipedia.org/wiki/Microsoft_Outlook">Outlook</a> and <a href="http://skype.com">Skype</a> to stay connected to coworkers</li>
<li><a href="http://en.wikipedia.org/wiki/Team_Foundation_Server">Team Foundation Server</a> (TFS) for tracking work items and for version control</li>
<li><a href="http://www.cygwin.com/">cygwin</a> to make the command line in Windows behave somewhat normally</li>
</ul>
<p><a href="http://www.flickr.com/photos/21254914@N04/3314417978" title="View 'C# Development' on Flickr.com">
<div style="text-align:center;"><img src="http://farm4.static.flickr.com/3298/3314417978_72c581d0ce.jpg" alt="C# Development" border="0" width="500" height="313" /></div>
<p></a></p>
<p>The one thing that is sorta strange about how I do my C#.NET work is that I do everything on a Mac Pro with XP running in <a href="http://www.vmware.com/products/fusion/">VMWare Fusion</a>. I've had a similar setup at home for a couple of years but I've only had this setup at work since January.</p>
<p>There are definitely a few quirks that I had to get used to, working in Windows running in a VM on OS X. But the benefits of this setup <em>far</em> outweigh any inconvenience. The ability to take snapshots of the entire VM is awesome! If a program screws with my registry and Windows starts acting funky I just roll back to the last snapshot!</p>
<p>The other huge benefit to working in VMWare is memory. Unless you're using 64-bit Windows (which can be problematic for many reasons) you are limited to 2 GB of memory. Windows sucks at managing virtual memory so I always try to keep my open applications below that 2 GB limit. Since my Mac has 12 GB of memory, if I need to do something else, I can just boot up a second VM.</p>
<p>Most of the software that I've written for OS X has been personal projects. Nothing fancy, just various tools to scratch some itch. Since getting my iPhone I've been doing more work in <a href="http://en.wikipedia.org/wiki/Objective-C">Objective-C</a> and <a href="http://en.wikipedia.org/wiki/Cocoa_(API)">Cocoa</a>.</p>
<p>Because I've done so much work with managed and interpreted languages, it feels a little weird to work in unmanaged C/ObjC. But it is kinda cool too. Objective-C is a fairly simple language and Cocoa is a very nice framework. There are some things that I don't like about Obj-C (not having namespaces and gimpy string manipulation come immediately to mind) but I <em>really</em> appreciate being able to actually use Cocoa controls for UI work. It is almost unthinkable to do GUI development for Windows without buying a set of <a href="http://devexpress.com/">third-party controls</a>.</p>
<p>My must-have software for writing Mac/iPhone applications:</p>
<ul>
<li><a href="http://developer.apple.com/TOOLS/xcode/">XCode</a> and <a href="http://developer.apple.com/tools/interfacebuilder.html">Interface Builder</a></li>
<li><a href="http://www.apple.com/macosx/developertools/instruments.html">Instruments</a></li>
<li><a href="http://www.macports.org/">MacPorts</a> to install all of the software that is missing from the base OS X install</li>
<li><a href="http://www.apple.com/macosx/features/mail.html">Mail.app</a>, <a href="http://www.mrrsoftware.com/MRRSoftware/Syrinx.html">Syrinx</a>, <a href="http://www.adiumx.com/">Adium</a> and <a href="http://colloquy.info/">Colloquy</a> to keep in touch with other developers</li>
</ul>
<p><a href="http://www.flickr.com/photos/21254914@N04/3312845171" title="View 'Cocoa Development' on Flickr.com">
<div style="text-align:center;"><img src="http://farm4.static.flickr.com/3616/3312845171_b6fbb0c611.jpg" alt="Cocoa Development" border="0" width="500" height="313" /></div>
<p></a></p>
<p>And finally, a few additional pieces of software that are invaluable to me. These are helpful regardless of what type of software I am writing.</p>
<ul>
<li><a href="http://www.omnigroup.com/applications/omnifocus/">OmniFocus</a> to help me Get Things Done</li>
<li><a href="http://git-scm.com/">git</a> for source control (don't tell anyone but I keep my TFS repositories checked into git too)</li>
<li><a href="http://en.wikipedia.org/wiki/Apple_Terminal">Terminal.app</a> for a whole bunch of things</li>
<li><a href="http://www.cocoatech.com/">PathFinder</a> because Finder doesn't always cut it</li>
<li><a href="http://projects.tynsoe.org/en/geektool/">GeekTool</a> to keep an eye on logs</li>
<li><a href="http://www.vim.org/">vim</a></li>
<li><a href="http://www.gnu.org/software/screen/">screen</a></li>
<li><a href="http://en.wikipedia.org/wiki/Photoshop">Photoshop</a></li>
<li><a href="http://www.apple.com/itunes/">iTunes</a> to help keep me in <a href="http://www.randsinrepose.com/archives/2006/07/10/a_nerd_in_a_cave.html">The Zone</a>!</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.zobie.com/2009/02/the-rest-of-my-development-environment/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Web Development Environment</title>
		<link>http://blog.zobie.com/2009/02/web-development-environment/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=web-development-environment</link>
		<comments>http://blog.zobie.com/2009/02/web-development-environment/#comments</comments>
		<pubDate>Mon, 16 Feb 2009 07:13:33 +0000</pubDate>
		<dc:creator>zobie</dc:creator>
				<category><![CDATA[Personal]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://blog.zobie.com/?p=121</guid>
		<description><![CDATA[During 2008 I spent most of my time doing web development. There was some Java, PHP and Python, but most of my time was spent working in Ruby on Rails. Rails is a lot of fun and (I know this sounds cheesy, but...) it helped me to enjoy doing web development again. When I'm working [...]]]></description>
			<content:encoded><![CDATA[<p>During 2008 I spent most of my time doing web development. There was some Java, PHP and Python, but most of my time was spent working in Ruby on Rails. Rails is <em>a lot</em> of fun and (I know this sounds cheesy, but...) it helped me to enjoy doing web development again.</p>
<p>When I'm working in Java I always prefer to use <a href="http://www.jetbrains.com/">JetBrains'</a> excellent <a href="http://www.jetbrains.com/idea/">IntelliJ IDEA</a>. However, this past year I didn't have a license for IntelliJ. I tried every free IDE I could find and wound up choosing <a href="http://www.eclipse.org/">Eclipse</a>. I've used Eclipse periodically over the last several years. I don't really like it but I dislike it less than the other free alternatives.</p>
<p>My work was completely server-side and didn't involve developing a database component. Most of my development was done on OS X but I was deploying to Ubuntu so I did work there also. I used <a href="http://maven.apache.org/">maven</a> to build, test and deploy. I'm not a unit-test fanatic but, in this case unit testing was invaluable.</p>
<p><a href="http://www.flickr.com/photos/21254914@N04/3283428513" title="View 'Java Development' on Flickr.com">
<div style="text-align:center;"><img src="http://farm4.static.flickr.com/3287/3283428513_cef4107e92.jpg" alt="Java Development" border="0" width="500" height="313" /></div>
<p></a></p>
<p>My setup for both PHP and Python is the same. When I'm working on Mac I use either <a href="http://macromates.com/">TextMate</a> or <a href="http://www.vim.org/">vim</a>. I haven't done a great deal of Python work but over the past several years I've tried to find a PHP IDE that I like... I'm still looking.</p>
<p><a href="http://www.flickr.com/photos/21254914@N04/3284249898" title="View 'PHP Development' on Flickr.com">
<div style="text-align:center;"><img src="http://farm4.static.flickr.com/3453/3284249898_9d15fb09fb.jpg" alt="PHP Development" border="0" width="500" height="313" /></div>
<p></a></p>
<p>I started out doing my Ruby work using TextMate and Terminal.app. I didn't have any major complaints. There are some nice plugins and various tricks that are handy. But personally, I prefer an IDE. I've heard some people say that IDEs make us lazy. Ok, I'm lazy. But I'm also far more productive when I have a good IDE. When JetBrains started issung beta releases of <a href="http://www.jetbrains.com/ruby/">RubyMine</a>, TextMate was history!</p>
<p>RubyMine's GUI for easily stepping through code in the debugger is great. The inline code analysis is nice for quickly catching typos and the code completion can be useful too. But for me, the best part about having RubyMine is the navigation and documentation.</p>
<p>When I'm working with other developers (or even with frameworks that I didn't write), I don't always know exactly what a method does. Being able to instantly bring up documentation is awesome! If I need more information, I hate wasting time trying to hunt down a method buried in code that I am not familiar with. With one key-stroke RubyMine takes me to the code I'm looking for.</p>
<p><a href="http://www.flickr.com/photos/21254914@N04/3284249934" title="View 'Rails Development' on Flickr.com">
<div style="text-align:center;"><img src="http://farm4.static.flickr.com/3513/3284249934_1cab946dfd.jpg" alt="Rails Development" border="0" width="500" height="313" /></div>
<p></a></p>
<p>I am definitely a fan of JetBrains' production. IntelliJ is awesome, RubyMine is awesome, and VisualStudio is just broken without <a href="http://www.jetbrains.com/resharper/">ReSharper</a>. There is certainly a learning curve to these tools but once you've memorized the key strokes, the code you need is always right in front of you. And the best part part is that the key bindings are the same across each of JetBrain's products!</p>
<p>One last application that deserves to be mentioned is <a href="http://mysql.navicat.com/">Navicat</a>. Navicat is by far the best application that I've found for working with MySQL or PostgreSQL. Unfortunately, that's not saying much. I have spent a lot of time using SQL Server and Microsoft's related tools and, as far as I can tell, there is nothing for MySQL that is even in the same league.</p>
<p>Don't misunderstand me. Navicat is a great tool. Allowing me to save connections to different servers with many different login credentials is a lifesaver, especially the ability to tunnel the connections over ssh. Being able to do basic server management via a GUI is nice too. But when I need to design a database, I always turn back to <a href="http://en.wikipedia.org/wiki/SQL_Server_Management_Studio">SQL Server Management Studio</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.zobie.com/2009/02/web-development-environment/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>My Development Environment</title>
		<link>http://blog.zobie.com/2009/01/my-development-environment/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=my-development-environment</link>
		<comments>http://blog.zobie.com/2009/01/my-development-environment/#comments</comments>
		<pubDate>Wed, 28 Jan 2009 08:11:06 +0000</pubDate>
		<dc:creator>zobie</dc:creator>
				<category><![CDATA[Personal]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[hardware]]></category>
		<category><![CDATA[life]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://blog.zobie.com/?p=112</guid>
		<description><![CDATA[Last month I found something new on Facebook, it's called Puzzle Master. I don't know for certain, but Puzzle Master seems to be run by Facebook (the corporation) as a way to find new development talent. When I first discovered Puzzle Master the running contest was: To enter the contest, upload to our fan photo [...]]]></description>
			<content:encoded><![CDATA[<p>Last month I found something new on Facebook, it's called <a href="http://www.facebook.com/jobs_puzzles">Puzzle Master</a>. I don't know for certain, but Puzzle Master seems to be run by Facebook (the corporation) as a way to find new development talent.</p>
<p>When I first discovered Puzzle Master <a href="http://www.facebook.com/home.php#/note.php?note_id=38587514414">the running contest was</a>:</p>
<blockquote><p>To enter the contest, upload to our fan photo album, a screenshot of your desktop and development environment (including as many editors and tools as you can, and your desktop wallpaper) along with a short essay of 250 words or less explaining why and how you use it.</p></blockquote>
<p>I don't generally participate in this type of contest but I always find it interesting to see how other developers work. There were some cool prizes available and not many entrants so I decided to upload a <a href="http://www.facebook.com/home.php#/photo.php?pid=1620204&#038;op=1&#038;view=all&#038;subj=15325934266&#038;id=669671291">screenshot of my desktop</a>.</p>
<p>I was disappointed because the picture was scaled down so much that the apps were indistinguishable. So, I decided that it might be fun to do a few posts on my development environments.</p>
<p>First up... my physical setup!<br />
<a href="http://www.flickr.com/photos/21254914@N04/3175003022" title="View 'My Desk' on Flickr.com">
<div style="text-align:center;"><img src="http://farm4.static.flickr.com/3095/3175003022_7dc2bdffa9.jpg" alt="My Desk" border="0" width="500" height="375" /><br /><em>The picture is a link to flickr where I've attached some notes to the image.</em></div>
<p></a></p>
<ul>
<li>MacPro (2 x 2.66GHz Dual-core Xeon) with 8 GB and ~2.5 TB</li>
<li>Two 24" Dell monitors, both at 1920x1200</li>
<li>Mac OS X 10.5</li>
<li>VMWare Fusion running XP SP3</li>
</ul>
<p>This is my home office but my work setup is similar. At work my MacPro is 2 x 2.8 GHz Quad-core. It has 12 GB memory and a single 500 GB disk. Maybe I'll try to update this post later with a picture of my desk at work.</p>
<hr />
<p><strong>Update:</strong><br />
Here's my desk at work!<br />
<a href="http://www.flickr.com/photos/21254914@N04/3254045787" title="View 'My Desk at Work' on Flickr.com">
<div style="text-align:center;"><img src="http://farm4.static.flickr.com/3334/3254045787_707b5f5c5c.jpg" alt="My Desk at Work" border="0" width="500" height="375" /></div>
<p></a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.zobie.com/2009/01/my-development-environment/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

