<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>Tim Barcz - Agile</title>
    <link>http://www.timbarcz.com/blog/</link>
    <description>My Code is My Craft</description>
    <image>
      <url>http://www.timbarcz.com/blog/content/binary/channelImage.jpg</url>
      <title>Tim Barcz - Agile</title>
      <link>http://www.timbarcz.com/blog/</link>
    </image>
    <language>en-us</language>
    <copyright>Tim Barcz</copyright>
    <lastBuildDate>Thu, 05 Mar 2009 18:48:42 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.0.7226.0</generator>
    <managingEditor>blog@timbarcz.com</managingEditor>
    <webMaster>blog@timbarcz.com</webMaster>
    <item>
      <trackback:ping>http://www.timbarcz.com/blog/Trackback.aspx?guid=89065ec0-8d2d-48b8-8803-ad6942160f2c</trackback:ping>
      <pingback:server>http://www.timbarcz.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.timbarcz.com/blog/PermaLink,guid,89065ec0-8d2d-48b8-8803-ad6942160f2c.aspx</pingback:target>
      <dc:creator>Tim Barcz</dc:creator>
      <wfw:comment>http://www.timbarcz.com/blog/CommentView,guid,89065ec0-8d2d-48b8-8803-ad6942160f2c.aspx</wfw:comment>
      <wfw:commentRss>http://www.timbarcz.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=89065ec0-8d2d-48b8-8803-ad6942160f2c</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
        </p>
        <p>
The following is an email I wrote to the upper management in our company when asked
about things we can do to improve the process and what are the next steps of things
we need to fix in our application.  It remains mostly unedited and contains my
thoughts on what will make our company better when it comes to the software we're
writing.  It wasn't written as a blog post.  It wasn't until after I finished
with it that I realized that it was decent content for a blog post.  You'll find
a very "XP-ish" theme throughout, and that isn't necessarily an accident. 
Hope you enjoy! Please leave feedback if something moves you.
</p>
        <h2>Overview
</h2>
        <p>
The following contains my thoughts on software development at Super Awesome Company.
While I can address the specifics of the project that I see need to be fixed and modified
(the “what”), I am instead going to focus on how these items get fixed.
I am choosing to do this because over time the new website will have bugs that need
to be fixed, enhancements that need to be made, or new features requested. For the
long term health of the project it does not matter so much “what” is implemented
but rather “how”. For that reason I am avoiding specific project level
tasks in this document and speaking at a higher level.
</p>
        <p>
Software has been being developed for over 30 years. While the internet is relatively
young, software development by comparison is not. Super Awesome Company will benefit
from a commitment to good software development practices. Further, it takes a great
deal of commitment and discipline to reap the benefits these practices can bring.
Many of my suggestions are based on these principles, which are principles I have
committed to learning and adopting over the last several years.
</p>
        <p>
The overarching suggestion I would make is make quality the focus. In order to produce
quality, we must slow down. In order to go fast you must go slowly. Sacrificing quality
should never be an option. Consider a car manufacturer who needs to get 100 cars built
in a single day. If they can only build 80 cars a day, is it better for them in the
long run to get 100 cars out the door but have problems or 80 problem free cars? Building
deficient cars carries more expense that just fixing the broken cars, such diminished
brand reputation. If the goal is 100 cars per day, measures should be sought to increase
production while keeping quality high.
</p>
        <p>
We don't need to look too far to see where in a rush we've done something that we've
had to revisit several more times because we were "going fast". We've been
rushed for nearly a year and I can't say that we are any further along than we would
have been had we approached the project more methodically. In some areas we may be
further behind where we would have been since we "made sacrifices" to get
things done, which have ultimately only put us further behind. Again, to go fast we
must go "slow" (methodical). Put another way, quality breeds speed.
</p>
        <p>
          <b>Any process, principle, practice we choose should have quality at its heart. Regardless
of what process, principles, practices we adopt they will only be successful if we
are disciplined enough to follow them. </b>
        </p>
        <h2>Planning
</h2>
        <h3>Requirements 
</h3>
        <p>
Requirements need to be clear and understood by all parties. Before developers set
out to coding we need to have a clear understanding of what the problem is. The developer
is not able to provide a solution until the problem is fully known and understood.
Often the perceived solution to a problem is not the best solution. Failure to fully
understand the problem/scenario results in rework.
</p>
        <h3>Releases
</h3>
        <p>
We need to have planned releases. The timeframe can be discussed and agreed upon by
the team. In order to have successful releases we need to plan each release. Each
release should be broken down into smaller time frames, iterations. During the iteration
the work should be stable for each developer. In other words, they know what they’re
going to work on and accomplish (see requirements above) for any given time period.
</p>
        <h3>Metrics
</h3>
        <p>
We need to be measuring metrics for the purposes of planning. If we get 10 units of
work done each week on average and we have 20 units of work to do, we can easily figure
out what is left to do. Without any metrics gathering we can’t do any planning
and we’re really flying blind. This will also help with project post mortems.
For example, the “web order manager” project was originally estimated
to take a week worth of development effort. Three months later, it is still not finished.
This is a combination of putting someone with limited knowledge of the business estimating
the project, an overly aggressive developer estimate, and having no metric to pull
from on how long something should take.
</p>
        <h3>Flexibility
</h3>
        <p>
We need to be disciplined in the process of building software, but also realize when
the process needs tweaking that we should respond and not be afraid to tweak the process
to meet the needs of our team
</p>
        <h2>Design
</h2>
        <h3>Simplicity
</h3>
        <p>
We should strive for simplicity in our designs. “Clever hacks” are often
not healthy for the life time of the project. Simple designs are easier to understand
and improve upon. Simple designs also allow other developers ease in working on code.
This is much harder to do in practice but it always pays off in the long run.
</p>
        <p>
Design aspects dovetail with testing (later in this document). Typically complex designs
prove to be hard to test. When we write code based on simpler designs we’ll
find that our code is easier to test. We want both, simple designs and easy-to-test
code.
</p>
        <h2>Coding
</h2>
        <h3>Standards
</h3>
        <p>
We should implement a standard for code development. Right now you can find three
different styles/methods of coding in the code base. This makes it hard for developers
to work on code they did not author. Projects I work on outside of work require all
new code meet the standard, otherwise it is rejected until it meets this standard.
As a consumer of these projects I’m always grateful when I can move through
any of the project pieces and the code always looks the same.
</p>
        <h3>Testing
</h3>
        <p>
Given the environment and complexity of the code, we need to require the developers
to be able to test their code in an automated fashion. Visual verification is orders
of magnitude slower than automated testing. Once an automated test is written, it
runs every time. By having a large collection of tests we can makes changes to certain
parts of the application and use existing tests as a safety net to verify nothing
else has broken. We currently have over 1,150 tests (about 30% of code has tests)
that run whenever someone commits code into source control. Those tests run in about
20 seconds. Imagine how long it would take a user to test each of those cases visually
every time a piece of code changes.
</p>
        <p>
Two weeks ago I sat in a meeting adding functionality to shipping and enhancing rules
around shipping hazardous items to Canada while people were finding issues because
of a solid base of tests. Before the meeting was over both issues discovered were
fixed and tests were added for these specific issues so we would be guarded against
this happening again.
</p>
        <h3>Unit Tests
</h3>
        <p>
All code must have unit tests that can be run in an automated fashion. If the code
cannot be unit tested (tested in isolation from other components) it should be restructured
in such a way that it can be tested. Very few pieces of code are truly not testable.
As such we should have very few areas in our code base which are not tested.
</p>
        <h3>Proving Bug Fixes Through Tests
</h3>
        <p>
When bug is found a test should be written before any attempt to fix the bug. This
test proves to the developer the bug exists but secondly gives the developer a marker
to know when the bug is fixed. As a benefit, this new test acts as a guard against
this particular bug ever happening again. This test, when first written, should fail
because the developer has not fixed the bug yet. The developer should then work to
make the test pass, and by extension fixing the bug. The cost of adding the test is
very small when compared against having the test guard against this condition ever
happening again. 
</p>
        <h3>Code Coverage
</h3>
        <p>
We should implement a standard for new code coverage, code that is tested by an automated
test. I would recommend somewhere in the 80%-90% range for code coverage. In order
to write tests the developers will be forced to think about their code a bit more
thoroughly.
</p>
        <h3>Pair Programming
</h3>
        <p>
We should adopt pair programming as a method to both increase shared knowledge but
also as a means to quality. Pair programming is two developers sitting at one computer
for a period of time while code is written. From the outside it may seem impractical
to devote two developers to a single computer, thinking it is inefficient. Industry
studies however show that code written in a pair has a four-fold benefit:
</p>
        <ol>
          <li>
15% less code– Studies showed that less code is written in order to implement
the same functionality. Less code means less to maintain and understand. Less code
is also typically simpler. 
</li>
          <li>
Less bugs – Developers, when working in pairs, can catch each other’s
bugs before they ever make it to production. We therefore save time that it would
take to fix the bugs that would otherwise go undiscovered. 
</li>
          <li>
Shared domain knowledge – When “pairing”, each developer is training
the other and sharing knowledge and rules around the business. This avoids silos and
situations where only one person knows the code. 
</li>
          <li>
Increased Skill – When “pairing”, design, coding, and testing techniques
are transferred between developers. This is often why many development shops pair
their senior developers with junior developers; to raise the skill level of the junior
developer. 
</li>
        </ol>
        <h3>Collective Code Ownership
</h3>
        <p>
No one person should be a silo/bottleneck for any area of the code. Any person should
be free to make suggestions, fix bugs, or refactor any part of the code. Pair programming
(see above) is one tool which seeks to address this.
</p>
        <h2>Conclusion
</h2>
        <p>
While the above recommendations may seem like a lot, the above items all really go
hand-in-hand. Consider:
</p>
        <ul>
          <li>
            <b>Collective Code Ownership</b> is had through <b>Pair Programming</b></li>
          <li>
            <b>Standards</b> are enforced by developers when <b>Pair Programming</b></li>
          <li>
Writing <b>Unit Tests</b> typically leads to <b>Simple Designs</b></li>
          <li>
A commitment to <b>Code Coverage</b> leads to more <b>Unit Tests</b></li>
          <li>
Gathering <b>Metrics</b> leads to better estimates and <b>Release </b>planning 
</li>
        </ul>
        <p>
Adopting the above will move us in a positive direction and ensure that all projects
coming from our department will be of ever heightening quality. Once the quality bar
is set, then we will begin to see the pace pick up; Remember, quality is a prerequisite
to speed.
</p>
        <img width="0" height="0" src="http://www.timbarcz.com/blog/aggbug.ashx?id=89065ec0-8d2d-48b8-8803-ad6942160f2c" />
      </body>
      <title>Improving Software Process - A Letter to Upper Management</title>
      <guid isPermaLink="false">http://www.timbarcz.com/blog/PermaLink,guid,89065ec0-8d2d-48b8-8803-ad6942160f2c.aspx</guid>
      <link>http://www.timbarcz.com/blog/ImprovingSoftwareProcessALetterToUpperManagement.aspx</link>
      <pubDate>Thu, 05 Mar 2009 18:48:42 GMT</pubDate>
      <description>&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
The following is an email I wrote to the upper management in our company when asked
about things we can do to improve the process and what are the next steps of things
we need to fix in our application.&amp;#160; It remains mostly unedited and contains my
thoughts on what will make our company better when it comes to the software we're
writing.&amp;#160; It wasn't written as a blog post.&amp;#160; It wasn't until after I finished
with it that I realized that it was decent content for a blog post.&amp;#160; You'll find
a very &amp;quot;XP-ish&amp;quot; theme throughout, and that isn't necessarily an accident.&amp;#160;
Hope you enjoy! Please leave feedback if something moves you.
&lt;/p&gt;
&lt;h2&gt;Overview
&lt;/h2&gt;
&lt;p&gt;
The following contains my thoughts on software development at Super Awesome Company.
While I can address the specifics of the project that I see need to be fixed and modified
(the &amp;#8220;what&amp;#8221;), I am instead going to focus on how these items get fixed.
I am choosing to do this because over time the new website will have bugs that need
to be fixed, enhancements that need to be made, or new features requested. For the
long term health of the project it does not matter so much &amp;#8220;what&amp;#8221; is implemented
but rather &amp;#8220;how&amp;#8221;. For that reason I am avoiding specific project level
tasks in this document and speaking at a higher level.
&lt;/p&gt;
&lt;p&gt;
Software has been being developed for over 30 years. While the internet is relatively
young, software development by comparison is not. Super Awesome Company will benefit
from a commitment to good software development practices. Further, it takes a great
deal of commitment and discipline to reap the benefits these practices can bring.
Many of my suggestions are based on these principles, which are principles I have
committed to learning and adopting over the last several years.
&lt;/p&gt;
&lt;p&gt;
The overarching suggestion I would make is make quality the focus. In order to produce
quality, we must slow down. In order to go fast you must go slowly. Sacrificing quality
should never be an option. Consider a car manufacturer who needs to get 100 cars built
in a single day. If they can only build 80 cars a day, is it better for them in the
long run to get 100 cars out the door but have problems or 80 problem free cars? Building
deficient cars carries more expense that just fixing the broken cars, such diminished
brand reputation. If the goal is 100 cars per day, measures should be sought to increase
production while keeping quality high.
&lt;/p&gt;
&lt;p&gt;
We don't need to look too far to see where in a rush we've done something that we've
had to revisit several more times because we were &amp;quot;going fast&amp;quot;. We've been
rushed for nearly a year and I can't say that we are any further along than we would
have been had we approached the project more methodically. In some areas we may be
further behind where we would have been since we &amp;quot;made sacrifices&amp;quot; to get
things done, which have ultimately only put us further behind. Again, to go fast we
must go &amp;quot;slow&amp;quot; (methodical). Put another way, quality breeds speed.
&lt;/p&gt;
&lt;p&gt;
&lt;b&gt;Any process, principle, practice we choose should have quality at its heart. Regardless
of what process, principles, practices we adopt they will only be successful if we
are disciplined enough to follow them. &lt;/b&gt;
&lt;/p&gt;
&lt;h2&gt;Planning
&lt;/h2&gt;
&lt;h3&gt;Requirements 
&lt;/h3&gt;
&lt;p&gt;
Requirements need to be clear and understood by all parties. Before developers set
out to coding we need to have a clear understanding of what the problem is. The developer
is not able to provide a solution until the problem is fully known and understood.
Often the perceived solution to a problem is not the best solution. Failure to fully
understand the problem/scenario results in rework.
&lt;/p&gt;
&lt;h3&gt;Releases
&lt;/h3&gt;
&lt;p&gt;
We need to have planned releases. The timeframe can be discussed and agreed upon by
the team. In order to have successful releases we need to plan each release. Each
release should be broken down into smaller time frames, iterations. During the iteration
the work should be stable for each developer. In other words, they know what they&amp;#8217;re
going to work on and accomplish (see requirements above) for any given time period.
&lt;/p&gt;
&lt;h3&gt;Metrics
&lt;/h3&gt;
&lt;p&gt;
We need to be measuring metrics for the purposes of planning. If we get 10 units of
work done each week on average and we have 20 units of work to do, we can easily figure
out what is left to do. Without any metrics gathering we can&amp;#8217;t do any planning
and we&amp;#8217;re really flying blind. This will also help with project post mortems.
For example, the &amp;#8220;web order manager&amp;#8221; project was originally estimated
to take a week worth of development effort. Three months later, it is still not finished.
This is a combination of putting someone with limited knowledge of the business estimating
the project, an overly aggressive developer estimate, and having no metric to pull
from on how long something should take.
&lt;/p&gt;
&lt;h3&gt;Flexibility
&lt;/h3&gt;
&lt;p&gt;
We need to be disciplined in the process of building software, but also realize when
the process needs tweaking that we should respond and not be afraid to tweak the process
to meet the needs of our team
&lt;/p&gt;
&lt;h2&gt;Design
&lt;/h2&gt;
&lt;h3&gt;Simplicity
&lt;/h3&gt;
&lt;p&gt;
We should strive for simplicity in our designs. &amp;#8220;Clever hacks&amp;#8221; are often
not healthy for the life time of the project. Simple designs are easier to understand
and improve upon. Simple designs also allow other developers ease in working on code.
This is much harder to do in practice but it always pays off in the long run.
&lt;/p&gt;
&lt;p&gt;
Design aspects dovetail with testing (later in this document). Typically complex designs
prove to be hard to test. When we write code based on simpler designs we&amp;#8217;ll
find that our code is easier to test. We want both, simple designs and easy-to-test
code.
&lt;/p&gt;
&lt;h2&gt;Coding
&lt;/h2&gt;
&lt;h3&gt;Standards
&lt;/h3&gt;
&lt;p&gt;
We should implement a standard for code development. Right now you can find three
different styles/methods of coding in the code base. This makes it hard for developers
to work on code they did not author. Projects I work on outside of work require all
new code meet the standard, otherwise it is rejected until it meets this standard.
As a consumer of these projects I&amp;#8217;m always grateful when I can move through
any of the project pieces and the code always looks the same.
&lt;/p&gt;
&lt;h3&gt;Testing
&lt;/h3&gt;
&lt;p&gt;
Given the environment and complexity of the code, we need to require the developers
to be able to test their code in an automated fashion. Visual verification is orders
of magnitude slower than automated testing. Once an automated test is written, it
runs every time. By having a large collection of tests we can makes changes to certain
parts of the application and use existing tests as a safety net to verify nothing
else has broken. We currently have over 1,150 tests (about 30% of code has tests)
that run whenever someone commits code into source control. Those tests run in about
20 seconds. Imagine how long it would take a user to test each of those cases visually
every time a piece of code changes.
&lt;/p&gt;
&lt;p&gt;
Two weeks ago I sat in a meeting adding functionality to shipping and enhancing rules
around shipping hazardous items to Canada while people were finding issues because
of a solid base of tests. Before the meeting was over both issues discovered were
fixed and tests were added for these specific issues so we would be guarded against
this happening again.
&lt;/p&gt;
&lt;h3&gt;Unit Tests
&lt;/h3&gt;
&lt;p&gt;
All code must have unit tests that can be run in an automated fashion. If the code
cannot be unit tested (tested in isolation from other components) it should be restructured
in such a way that it can be tested. Very few pieces of code are truly not testable.
As such we should have very few areas in our code base which are not tested.
&lt;/p&gt;
&lt;h3&gt;Proving Bug Fixes Through Tests
&lt;/h3&gt;
&lt;p&gt;
When bug is found a test should be written before any attempt to fix the bug. This
test proves to the developer the bug exists but secondly gives the developer a marker
to know when the bug is fixed. As a benefit, this new test acts as a guard against
this particular bug ever happening again. This test, when first written, should fail
because the developer has not fixed the bug yet. The developer should then work to
make the test pass, and by extension fixing the bug. The cost of adding the test is
very small when compared against having the test guard against this condition ever
happening again. 
&lt;/p&gt;
&lt;h3&gt;Code Coverage
&lt;/h3&gt;
&lt;p&gt;
We should implement a standard for new code coverage, code that is tested by an automated
test. I would recommend somewhere in the 80%-90% range for code coverage. In order
to write tests the developers will be forced to think about their code a bit more
thoroughly.
&lt;/p&gt;
&lt;h3&gt;Pair Programming
&lt;/h3&gt;
&lt;p&gt;
We should adopt pair programming as a method to both increase shared knowledge but
also as a means to quality. Pair programming is two developers sitting at one computer
for a period of time while code is written. From the outside it may seem impractical
to devote two developers to a single computer, thinking it is inefficient. Industry
studies however show that code written in a pair has a four-fold benefit:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
15% less code&amp;#8211; Studies showed that less code is written in order to implement
the same functionality. Less code means less to maintain and understand. Less code
is also typically simpler. 
&lt;/li&gt;
&lt;li&gt;
Less bugs &amp;#8211; Developers, when working in pairs, can catch each other&amp;#8217;s
bugs before they ever make it to production. We therefore save time that it would
take to fix the bugs that would otherwise go undiscovered. 
&lt;/li&gt;
&lt;li&gt;
Shared domain knowledge &amp;#8211; When &amp;#8220;pairing&amp;#8221;, each developer is training
the other and sharing knowledge and rules around the business. This avoids silos and
situations where only one person knows the code. 
&lt;/li&gt;
&lt;li&gt;
Increased Skill &amp;#8211; When &amp;#8220;pairing&amp;#8221;, design, coding, and testing techniques
are transferred between developers. This is often why many development shops pair
their senior developers with junior developers; to raise the skill level of the junior
developer. 
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Collective Code Ownership
&lt;/h3&gt;
&lt;p&gt;
No one person should be a silo/bottleneck for any area of the code. Any person should
be free to make suggestions, fix bugs, or refactor any part of the code. Pair programming
(see above) is one tool which seeks to address this.
&lt;/p&gt;
&lt;h2&gt;Conclusion
&lt;/h2&gt;
&lt;p&gt;
While the above recommendations may seem like a lot, the above items all really go
hand-in-hand. Consider:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;b&gt;Collective Code Ownership&lt;/b&gt; is had through &lt;b&gt;Pair Programming&lt;/b&gt; 
&lt;/li&gt;
&lt;li&gt;
&lt;b&gt;Standards&lt;/b&gt; are enforced by developers when &lt;b&gt;Pair Programming&lt;/b&gt; 
&lt;/li&gt;
&lt;li&gt;
Writing &lt;b&gt;Unit Tests&lt;/b&gt; typically leads to &lt;b&gt;Simple Designs&lt;/b&gt; 
&lt;/li&gt;
&lt;li&gt;
A commitment to &lt;b&gt;Code Coverage&lt;/b&gt; leads to more &lt;b&gt;Unit Tests&lt;/b&gt; 
&lt;/li&gt;
&lt;li&gt;
Gathering &lt;b&gt;Metrics&lt;/b&gt; leads to better estimates and &lt;b&gt;Release &lt;/b&gt;planning 
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Adopting the above will move us in a positive direction and ensure that all projects
coming from our department will be of ever heightening quality. Once the quality bar
is set, then we will begin to see the pace pick up; Remember, quality is a prerequisite
to speed.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.timbarcz.com/blog/aggbug.ashx?id=89065ec0-8d2d-48b8-8803-ad6942160f2c" /&gt;</description>
      <comments>http://www.timbarcz.com/blog/CommentView,guid,89065ec0-8d2d-48b8-8803-ad6942160f2c.aspx</comments>
      <category>Agile</category>
      <category>Musings</category>
      <category>Principles</category>
    </item>
    <item>
      <trackback:ping>http://www.timbarcz.com/blog/Trackback.aspx?guid=f10961b9-add0-4ddc-a15d-1bf4561a4efb</trackback:ping>
      <pingback:server>http://www.timbarcz.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.timbarcz.com/blog/PermaLink,guid,f10961b9-add0-4ddc-a15d-1bf4561a4efb.aspx</pingback:target>
      <dc:creator>Tim Barcz</dc:creator>
      <wfw:comment>http://www.timbarcz.com/blog/CommentView,guid,f10961b9-add0-4ddc-a15d-1bf4561a4efb.aspx</wfw:comment>
      <wfw:commentRss>http://www.timbarcz.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=f10961b9-add0-4ddc-a15d-1bf4561a4efb</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I don't typically link blog and I do my best to write substantive original material,
but the following is too good to pass up.  It's how I feel and how I've approach
work in the last year or so.  From <a href="http://www.ayende.com">Ayende's</a><a href="http://ayende.com/Blog/archive/2008/11/13/reducing-the-cost-of-change.aspx">Reducing
The Cost Of Change blog post</a> this morning:
</p>
        <blockquote>
          <p>
That mindset, at least for me, starts from the first line of code. I treat each piece
of the project as utterly disposable. Since I don't really care how each individual
piece works, I am able to roughly sketch a fair amount of the application very rapidly,
and then focus on each of the items in isolation, and replace that with a much better
implementation. I think that I stated before that I tend to rewrite most of my application
core at least two or three times before I am happy with them.
</p>
          <p>
When you have disposable pieces, it is no big deal if you mess up and need to start
over, because the whole project is structured in a way that <em>allows</em> you to
do so. Going back to using my current project as an example, the algorithm used for
the core part of the system is crap. I thought it up while being on a coffee break,
and it is enough to demonstrate what the software is supposed to be doing. I don't
really care, because the moment that I do need the real algorithm, I can drop it in
(need to change the implementation of a single method).
</p>
        </blockquote>
        <p>
I can't improve on that, so I won't try.
</p>
        <img width="0" height="0" src="http://www.timbarcz.com/blog/aggbug.ashx?id=f10961b9-add0-4ddc-a15d-1bf4561a4efb" />
      </body>
      <title>How To Approach Development</title>
      <guid isPermaLink="false">http://www.timbarcz.com/blog/PermaLink,guid,f10961b9-add0-4ddc-a15d-1bf4561a4efb.aspx</guid>
      <link>http://www.timbarcz.com/blog/HowToApproachDevelopment.aspx</link>
      <pubDate>Thu, 13 Nov 2008 15:51:25 GMT</pubDate>
      <description>&lt;p&gt;
I don't typically link blog and I do my best to write substantive original material,
but the following is too good to pass up.&amp;#160; It's how I feel and how I've approach
work in the last year or so.&amp;#160; From &lt;a href="http://www.ayende.com"&gt;Ayende's&lt;/a&gt; &lt;a href="http://ayende.com/Blog/archive/2008/11/13/reducing-the-cost-of-change.aspx"&gt;Reducing
The Cost Of Change blog post&lt;/a&gt; this morning:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
That mindset, at least for me, starts from the first line of code. I treat each piece
of the project as utterly disposable. Since I don't really care how each individual
piece works, I am able to roughly sketch a fair amount of the application very rapidly,
and then focus on each of the items in isolation, and replace that with a much better
implementation. I think that I stated before that I tend to rewrite most of my application
core at least two or three times before I am happy with them.
&lt;/p&gt;
&lt;p&gt;
When you have disposable pieces, it is no big deal if you mess up and need to start
over, because the whole project is structured in a way that &lt;em&gt;allows&lt;/em&gt; you to
do so. Going back to using my current project as an example, the algorithm used for
the core part of the system is crap. I thought it up while being on a coffee break,
and it is enough to demonstrate what the software is supposed to be doing. I don't
really care, because the moment that I do need the real algorithm, I can drop it in
(need to change the implementation of a single method).
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
I can't improve on that, so I won't try.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.timbarcz.com/blog/aggbug.ashx?id=f10961b9-add0-4ddc-a15d-1bf4561a4efb" /&gt;</description>
      <comments>http://www.timbarcz.com/blog/CommentView,guid,f10961b9-add0-4ddc-a15d-1bf4561a4efb.aspx</comments>
      <category>Agile</category>
      <category>Musings</category>
    </item>
    <item>
      <trackback:ping>http://www.timbarcz.com/blog/Trackback.aspx?guid=be7953f5-7018-4d43-8811-3ff070cb3253</trackback:ping>
      <pingback:server>http://www.timbarcz.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.timbarcz.com/blog/PermaLink,guid,be7953f5-7018-4d43-8811-3ff070cb3253.aspx</pingback:target>
      <dc:creator>Tim Barcz</dc:creator>
      <wfw:comment>http://www.timbarcz.com/blog/CommentView,guid,be7953f5-7018-4d43-8811-3ff070cb3253.aspx</wfw:comment>
      <wfw:commentRss>http://www.timbarcz.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=be7953f5-7018-4d43-8811-3ff070cb3253</wfw:commentRss>
      <slash:comments>4</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://www.timbarcz.com/blog/content/binary/WindowsLiveWriter/IrreducibleComplexityandEvolutionarySoft_DDA4/image_4.png">
            <img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="180" alt="image" src="http://www.timbarcz.com/blog/content/binary/WindowsLiveWriter/IrreducibleComplexityandEvolutionarySoft_DDA4/image_thumb_1.png" width="260" align="right" border="0" />
          </a>In
church last week we were talking about evolution when the term "Irreducible Complexity"
came up.  For those who aren't familiar with the concept <a href="http://en.wikipedia.org/wiki/Irreducible_complexity">irreducible
complexity</a> is a term coined by Michael Behe to illustrate that complex system
could not have evolved and therefore must have been created intelligently.  Behe
defines irreducible complexity as:
</p>
        <blockquote>
          <p>
A single system which is composed of several interacting parts that contribute to
the basic function, and where the removal of any one of the parts causes the system
to effectively cease functioning. (<i><a href="http://en.wikipedia.org/wiki/Darwin%27s_Black_Box">Darwin's
Black Box</a></i> p39 in the 2006 edition)
</p>
        </blockquote>
        <p>
In his book Behe uses a mousetrap to illustrate an irreducible complex system.  
</p>
        <blockquote>
          <p>
"If any one of the components of the mousetrap (the base, hammer, spring, catch,
or holding bar) is removed, then the trap does not function. In other words, the simple
little mousetrap has no ability to trap a mouse until several separate parts are all
assembled. Because the mousetrap is necessarily composed of several parts, it is irreducibly
complex." (Behe, 1996).
</p>
        </blockquote>
        <p>
(This post does not seek to discuss the controversy of evolution vs. creationism vs.
intelligent design)
</p>
        <p>
How does this translate to software?  An irreducibly complex software is software
that cannot be easily tested.  The "removal of any one of the parts causes
the system to effectively cease functioning" really points to dependencies in
software.  Do your tests rely on a database being there?  Do you get emails
whenever some piece of code runs because as part of the method an email is sent?
</p>
        <h2>
        </h2>
        <h2>Creationist Design
</h2>
        <p>
How often have you stepped into some code and have seen a method calling database,
sending an email, doing some validation, and then returning some value.  Here's
an example I pulled from <a href="http://www.lostechies.com/blogs/jimmy_bogard/">Jimmy
Bogard's</a> <a href="http://www.lostechies.com/blogs/jimmy_bogard/archive/2008/06/19/separation-of-concerns-by-example-part-1.aspx">post
on separation of concerns</a>:
</p>
        <div>
          <div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 1:</span> [DataObjectMethod(DataObjectMethodType.Select, <span style="color: #0000ff">false</span>)]</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 2:</span>
              <span style="color: #0000ff">public</span>
              <span style="color: #0000ff">static</span> List&lt;Customer&gt;
GetCustomers(<span style="color: #0000ff">int</span> startRowIndex, <span style="color: #0000ff">int</span> maximumRows)</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 3:</span> {</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 4:</span> List&lt;Customer&gt;
customers = <span style="color: #0000ff">null</span>;</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 5:</span>
              <span style="color: #0000ff">string</span> key
= <span style="color: #006080">"Customers_Customers_"</span> + startRowIndex
+ <span style="color: #006080">"_"</span> + maximumRows;</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 6:</span>  </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 7:</span>
              <span style="color: #0000ff">if</span> (HttpContext.Current.Cache[key]
!= <span style="color: #0000ff">null</span>)</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 8:</span> {</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 9:</span> customers
= (List&lt;Customer&gt;) HttpContext.Current.Cache[key];</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 10:</span> }</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 11:</span>
              <span style="color: #0000ff">else</span>
            </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 12:</span> {</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 13:</span> customers
=</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 14:</span> (</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 15:</span> from</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 16:</span> c <span style="color: #0000ff">in</span> DataGateway.Context.Customers</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 17:</span> orderby</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 18:</span> c.CustomerID
descending</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 19:</span> select</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 20:</span> c</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 21:</span> ).Skip(startRowIndex).Take(maximumRows).ToList();</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 22:</span>  </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 23:</span>
              <span style="color: #0000ff">if</span> ((customers
!= <span style="color: #0000ff">null</span>) &amp;&amp; (customers.Count &gt; 0))</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 24:</span> HttpContext.Current.Cache.Insert(key,
customers, <span style="color: #0000ff">null</span>, DateTime.Now.AddDays(1), TimeSpan.Zero);</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 25:</span> }</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 26:</span>  </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 27:</span>
              <span style="color: #0000ff">return</span> customers;</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 28:</span> }</pre>
          </div>
        </div>
        <p>
The code above will work however it's a bear to test, the code absolutely requires
other items (database, HttpContext, ect) to be there in order to work.  I would
venture to say that the person who wrote it did not build up the code through small
iterations, but rather wrote it all in one fell swoop.
</p>
        <h2>Evolutionary Design
</h2>
        <p>
In software, <strong>reducible complexity</strong> should be a goal.  A reducible
complex system allows for pieces to be substituted for others so you can focus on
one particular area.  Don't have a database in place, no problem, simply put
a placeholder object in for all calls made to the database.  (Yes I'm alluding
to mocking).  You can approach creating a reducibly complex system in two ways:
</p>
        <ul>
          <li>
Create the system as a whole, then reduce it's complexity 
</li>
          <li>
Create the system incrementally 
</li>
        </ul>
        <p>
I prefer the former to the latter as I'm working on my TDD skillz.
</p>
        <h2>Conclusion
</h2>
        <p>
While the analogies used here are not quite perfect, I do feel they illustrate the
point adequately.  As a developer your goal shouldn't be to simply write code. 
You should concern yourself with the lifetime of your application/code base. 
Irreducibly complex systems, while working, can also have short life spans. 
Think about the last time you've ever seen someone fix a broken mousetrap.  All
the parts are too interconnected, the mousetrap is simply replaced.  If you're
not careful your code may be viewed <a href="http://devlicio.us/blogs/tim_barcz/archive/2008/08/11/the-tortoise-and-the-hare.aspx">too
difficult and time consuming to fix, and simply replaced</a>.
</p>
        <img width="0" height="0" src="http://www.timbarcz.com/blog/aggbug.ashx?id=be7953f5-7018-4d43-8811-3ff070cb3253" />
      </body>
      <title>Irreducible Complexity and Evolutionary Design</title>
      <guid isPermaLink="false">http://www.timbarcz.com/blog/PermaLink,guid,be7953f5-7018-4d43-8811-3ff070cb3253.aspx</guid>
      <link>http://www.timbarcz.com/blog/IrreducibleComplexityAndEvolutionaryDesign.aspx</link>
      <pubDate>Tue, 02 Sep 2008 14:49:36 GMT</pubDate>
      <description>&lt;p&gt;
&lt;a href="http://www.timbarcz.com/blog/content/binary/WindowsLiveWriter/IrreducibleComplexityandEvolutionarySoft_DDA4/image_4.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="180" alt="image" src="http://www.timbarcz.com/blog/content/binary/WindowsLiveWriter/IrreducibleComplexityandEvolutionarySoft_DDA4/image_thumb_1.png" width="260" align="right" border="0" /&gt;&lt;/a&gt;In
church last week we were talking about evolution when the term &amp;quot;Irreducible Complexity&amp;quot;
came up.&amp;#160; For those who aren't familiar with the concept &lt;a href="http://en.wikipedia.org/wiki/Irreducible_complexity"&gt;irreducible
complexity&lt;/a&gt; is a term coined by Michael Behe to illustrate that complex system
could not have evolved and therefore must have been created intelligently.&amp;#160; Behe
defines irreducible complexity as:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
A single system which is composed of several interacting parts that contribute to
the basic function, and where the removal of any one of the parts causes the system
to effectively cease functioning. (&lt;i&gt;&lt;a href="http://en.wikipedia.org/wiki/Darwin%27s_Black_Box"&gt;Darwin's
Black Box&lt;/a&gt;&lt;/i&gt; p39 in the 2006 edition)
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
In his book Behe uses a mousetrap to illustrate an irreducible complex system.&amp;#160; 
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
&amp;quot;If any one of the components of the mousetrap (the base, hammer, spring, catch,
or holding bar) is removed, then the trap does not function. In other words, the simple
little mousetrap has no ability to trap a mouse until several separate parts are all
assembled. Because the mousetrap is necessarily composed of several parts, it is irreducibly
complex.&amp;quot; (Behe, 1996).
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
(This post does not seek to discuss the controversy of evolution vs. creationism vs.
intelligent design)
&lt;/p&gt;
&lt;p&gt;
How does this translate to software?&amp;#160; An irreducibly complex software is software
that cannot be easily tested.&amp;#160; The &amp;quot;removal of any one of the parts causes
the system to effectively cease functioning&amp;quot; really points to dependencies in
software.&amp;#160; Do your tests rely on a database being there?&amp;#160; Do you get emails
whenever some piece of code runs because as part of the method an email is sent?
&lt;/p&gt;
&lt;h2&gt;
&lt;/h2&gt;
&lt;h2&gt;Creationist Design
&lt;/h2&gt;
&lt;p&gt;
How often have you stepped into some code and have seen a method calling database,
sending an email, doing some validation, and then returning some value.&amp;#160; Here's
an example I pulled from &lt;a href="http://www.lostechies.com/blogs/jimmy_bogard/"&gt;Jimmy
Bogard's&lt;/a&gt;&amp;#160;&lt;a href="http://www.lostechies.com/blogs/jimmy_bogard/archive/2008/06/19/separation-of-concerns-by-example-part-1.aspx"&gt;post
on separation of concerns&lt;/a&gt;:
&lt;/p&gt;
&lt;div&gt;
&lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 1:&lt;/span&gt; [DataObjectMethod(DataObjectMethodType.Select, &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;)]&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 2:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; List&amp;lt;Customer&amp;gt;
GetCustomers(&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; startRowIndex, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; maximumRows)&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 3:&lt;/span&gt; {&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 4:&lt;/span&gt; List&amp;lt;Customer&amp;gt;
customers = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 5:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; key
= &lt;span style="color: #006080"&gt;&amp;quot;Customers_Customers_&amp;quot;&lt;/span&gt; + startRowIndex
+ &lt;span style="color: #006080"&gt;&amp;quot;_&amp;quot;&lt;/span&gt; + maximumRows;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 6:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 7:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (HttpContext.Current.Cache[key]
!= &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 8:&lt;/span&gt; {&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 9:&lt;/span&gt; customers
= (List&amp;lt;Customer&amp;gt;) HttpContext.Current.Cache[key];&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 10:&lt;/span&gt; }&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 11:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 12:&lt;/span&gt; {&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 13:&lt;/span&gt; customers
=&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 14:&lt;/span&gt; (&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 15:&lt;/span&gt; from&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 16:&lt;/span&gt; c &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; DataGateway.Context.Customers&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 17:&lt;/span&gt; orderby&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 18:&lt;/span&gt; c.CustomerID
descending&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 19:&lt;/span&gt; select&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 20:&lt;/span&gt; c&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 21:&lt;/span&gt; ).Skip(startRowIndex).Take(maximumRows).ToList();&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 22:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 23:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; ((customers
!= &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;) &amp;amp;&amp;amp; (customers.Count &amp;gt; 0))&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 24:&lt;/span&gt; HttpContext.Current.Cache.Insert(key,
customers, &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;, DateTime.Now.AddDays(1), TimeSpan.Zero);&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 25:&lt;/span&gt; }&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 26:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 27:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; customers;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 28:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
The code above will work however it's a bear to test, the code absolutely requires
other items (database, HttpContext, ect) to be there in order to work.&amp;#160; I would
venture to say that the person who wrote it did not build up the code through small
iterations, but rather wrote it all in one fell swoop.
&lt;/p&gt;
&lt;h2&gt;Evolutionary Design
&lt;/h2&gt;
&lt;p&gt;
In software, &lt;strong&gt;reducible complexity&lt;/strong&gt; should be a goal.&amp;#160; A reducible
complex system allows for pieces to be substituted for others so you can focus on
one particular area.&amp;#160; Don't have a database in place, no problem, simply put
a placeholder object in for all calls made to the database.&amp;#160; (Yes I'm alluding
to mocking).&amp;#160; You can approach creating a reducibly complex system in two ways:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Create the system as a whole, then reduce it's complexity 
&lt;/li&gt;
&lt;li&gt;
Create the system incrementally 
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
I prefer the former to the latter as I'm working on my TDD skillz.
&lt;/p&gt;
&lt;h2&gt;Conclusion
&lt;/h2&gt;
&lt;p&gt;
While the analogies used here are not quite perfect, I do feel they illustrate the
point adequately.&amp;#160; As a developer your goal shouldn't be to simply write code.&amp;#160;
You should concern yourself with the lifetime of your application/code base.&amp;#160;
Irreducibly complex systems, while working, can also have short life spans.&amp;#160;
Think about the last time you've ever seen someone fix a broken mousetrap.&amp;#160; All
the parts are too interconnected, the mousetrap is simply replaced.&amp;#160; If you're
not careful your code may be viewed &lt;a href="http://devlicio.us/blogs/tim_barcz/archive/2008/08/11/the-tortoise-and-the-hare.aspx"&gt;too
difficult and time consuming to fix, and simply replaced&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.timbarcz.com/blog/aggbug.ashx?id=be7953f5-7018-4d43-8811-3ff070cb3253" /&gt;</description>
      <comments>http://www.timbarcz.com/blog/CommentView,guid,be7953f5-7018-4d43-8811-3ff070cb3253.aspx</comments>
      <category>Agile</category>
      <category>Musings</category>
      <category>Testing</category>
    </item>
    <item>
      <trackback:ping>http://www.timbarcz.com/blog/Trackback.aspx?guid=82ccc2de-3ce6-4115-a015-95620cd8f787</trackback:ping>
      <pingback:server>http://www.timbarcz.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.timbarcz.com/blog/PermaLink,guid,82ccc2de-3ce6-4115-a015-95620cd8f787.aspx</pingback:target>
      <dc:creator>Tim Barcz</dc:creator>
      <wfw:comment>http://www.timbarcz.com/blog/CommentView,guid,82ccc2de-3ce6-4115-a015-95620cd8f787.aspx</wfw:comment>
      <wfw:commentRss>http://www.timbarcz.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=82ccc2de-3ce6-4115-a015-95620cd8f787</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Here's a conversation I just had with another developer who is struggling to get his
team to adopt some agile practices:
</p>
        <blockquote>
          <p>
            <strong>developer</strong>: if you were starting from scratch, which would you think
is more important to setup first? CI or a unit testing process? 
<br /><strong>me</strong>: unit testing 
<br /><strong>developer</strong>: wow 
<br /><strong>developer</strong>:  ok 
<br /><strong>me</strong>: why is that surprising? 
<br /><strong>developer</strong>: i look at the mess i'm in everyday and i'd think getting
a good build system in place would be first... 
<br /><strong>me</strong>: I think unit testing provides more value in that it allows you
to add features knowing you haven't broken other features 
<br /><strong>developer</strong>: testing above a development process? 
<br /><strong>me</strong>: yes 
<br /><strong>me</strong>: testing provides more customer value
</p>
        </blockquote>
        <p>
Let me be clear in stating that I think both are great value and a necessity, however
the challenge was to choose one, presumably the most important.  I chose unit
testing because one of the reasons I enjoy writing software that meets someone's needs. 
As a developer one of the most nervous moments is when your code is released into
the wild.  Will it work?  Will users they use it how you intended? 
As a developer one of the most satisfying experiences is watching a user fire up a
program you've written and it works flawlessly.  I think most customers would
agree with that as well.  Having code that works is what they want.  Having
code that works builds their confidence in you and reassures them that know what you're
doing.  Testing provides this for me.  In advance I can test different scenarios
and program that in and put my program through it's paces.
</p>
        <p>
Now let me speak a bit about CI.  While I believe that testing is a component
of CI, the developer in this instance meant a build server that kicks off automated
builds.  While an automated build is nice, it doesn't nearly provide the value
that unit testing does.  It's the things your build server does that increases
it's value.  One of those things in our build system is running automated tests. 
If you remove automated tests from a build server all you have is a dummy machine
that compiles code.  That provides some benefit, but minimally.  You can
replicate the behavior simply by updating your code often and doing a compile on your
own machine.
</p>
        <p>
As an agile developer I seek deliver value to stakeholders.  When viewed through
that lens, I think unit testing clearly wins.
</p>
        <p>
What about you?  Would you test before build server?  Or would you choose
the build server?  Why?
</p>
        <img width="0" height="0" src="http://www.timbarcz.com/blog/aggbug.ashx?id=82ccc2de-3ce6-4115-a015-95620cd8f787" />
      </body>
      <title>What First  - CI or Unit Testing?</title>
      <guid isPermaLink="false">http://www.timbarcz.com/blog/PermaLink,guid,82ccc2de-3ce6-4115-a015-95620cd8f787.aspx</guid>
      <link>http://www.timbarcz.com/blog/WhatFirstCIOrUnitTesting.aspx</link>
      <pubDate>Tue, 19 Aug 2008 19:13:21 GMT</pubDate>
      <description>&lt;p&gt;
Here's a conversation I just had with another developer who is struggling to get his
team to adopt some agile practices:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
&lt;strong&gt;developer&lt;/strong&gt;: if you were starting from scratch, which would you think
is more important to setup first? CI or a unit testing process? 
&lt;br /&gt;
&lt;strong&gt;me&lt;/strong&gt;: unit testing 
&lt;br /&gt;
&lt;strong&gt;developer&lt;/strong&gt;: wow 
&lt;br /&gt;
&lt;strong&gt;developer&lt;/strong&gt;:&amp;#160; ok 
&lt;br /&gt;
&lt;strong&gt;me&lt;/strong&gt;: why is that surprising? 
&lt;br /&gt;
&lt;strong&gt;developer&lt;/strong&gt;: i look at the mess i'm in everyday and i'd think getting
a good build system in place would be first... 
&lt;br /&gt;
&lt;strong&gt;me&lt;/strong&gt;: I think unit testing provides more value in that it allows you
to add features knowing you haven't broken other features 
&lt;br /&gt;
&lt;strong&gt;developer&lt;/strong&gt;: testing above a development process? 
&lt;br /&gt;
&lt;strong&gt;me&lt;/strong&gt;: yes 
&lt;br /&gt;
&lt;strong&gt;me&lt;/strong&gt;: testing provides more customer value
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Let me be clear in stating that I think both are great value and a necessity, however
the challenge was to choose one, presumably the most important.&amp;#160; I chose unit
testing because one of the reasons I enjoy writing software that meets someone's needs.&amp;#160;
As a developer one of the most nervous moments is when your code is released into
the wild.&amp;#160; Will it work?&amp;#160; Will users they use it how you intended?&amp;#160;
As a developer one of the most satisfying experiences is watching a user fire up a
program you've written and it works flawlessly.&amp;#160; I think most customers would
agree with that as well.&amp;#160; Having code that works is what they want.&amp;#160; Having
code that works builds their confidence in you and reassures them that know what you're
doing.&amp;#160; Testing provides this for me.&amp;#160; In advance I can test different scenarios
and program that in and put my program through it's paces.
&lt;/p&gt;
&lt;p&gt;
Now let me speak a bit about CI.&amp;#160; While I believe that testing is a component
of CI, the developer in this instance meant a build server that kicks off automated
builds.&amp;#160; While an automated build is nice, it doesn't nearly provide the value
that unit testing does.&amp;#160; It's the things your build server does that increases
it's value.&amp;#160; One of those things in our build system is running automated tests.&amp;#160;
If you remove automated tests from a build server all you have is a dummy machine
that compiles code.&amp;#160; That provides some benefit, but minimally.&amp;#160; You can
replicate the behavior simply by updating your code often and doing a compile on your
own machine.
&lt;/p&gt;
&lt;p&gt;
As an agile developer I seek deliver value to stakeholders.&amp;#160; When viewed through
that lens, I think unit testing clearly wins.
&lt;/p&gt;
&lt;p&gt;
What about you?&amp;#160; Would you test before build server?&amp;#160; Or would you choose
the build server?&amp;#160; Why?
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.timbarcz.com/blog/aggbug.ashx?id=82ccc2de-3ce6-4115-a015-95620cd8f787" /&gt;</description>
      <comments>http://www.timbarcz.com/blog/CommentView,guid,82ccc2de-3ce6-4115-a015-95620cd8f787.aspx</comments>
      <category>Agile</category>
      <category>Musings</category>
    </item>
    <item>
      <trackback:ping>http://www.timbarcz.com/blog/Trackback.aspx?guid=964ca953-e91e-484f-a3f8-8b98817f9f7b</trackback:ping>
      <pingback:server>http://www.timbarcz.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.timbarcz.com/blog/PermaLink,guid,964ca953-e91e-484f-a3f8-8b98817f9f7b.aspx</pingback:target>
      <dc:creator>Tim Barcz</dc:creator>
      <wfw:comment>http://www.timbarcz.com/blog/CommentView,guid,964ca953-e91e-484f-a3f8-8b98817f9f7b.aspx</wfw:comment>
      <wfw:commentRss>http://www.timbarcz.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=964ca953-e91e-484f-a3f8-8b98817f9f7b</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
When I first graduated from college I worked on embedded systems where the process
was a formal, military grade process.  When developing software I typically thought
about what document I had to write next and what document(s) I may be missing. 
In general, the MIL standards turned me off a bit to process, and for awhile left
me thinking that process is an obstruction to true development.  As a 21 year
old, you think code = development.  That was/is an immature point of view, but
it was not a viewpoint that I was easily dissuaded from.  Further it's a point
of view that many out there still hold dear, and not all who hold that view are recent
college graduates.
</p>
        <p>
Recently a small group of us decided to give <a href="http://www.controlchaos.com/">Scrum</a> a
try and are using it to drive our current project.  Other than this effort, there
is no formal process methodology in place.  My goal is to help change that in
my new position.  Over the past several years many high value projects have never
been worked on because there was no common backlog of all of the things that need
to be done.
</p>
        <p>
In my last job at Geonetric we adopted Scrum after the absence of a formal methodology
and it provided a much needed framework around which to develop.  Many CEO's
are not this up front with their deficiencies, but <a href="http://www.geonetric.com/about/leadership.asp">Eric</a> is
pretty awesome and <a href="http://geovoices.wordpress.com/2008/05/13/adopting-agile-processes/">very
honest in his evaluation</a> of <a href="http://www.geonetric.com">Geonetric</a>:
</p>
        <blockquote>
          <p>
As we were in the middle of developing the newest version of our VitalSite product
last fall, we weren’t making the progress we wanted-even though the whole team
was running full tilt and putting in its best efforts. We had always been a bit informal
about how we developed software-somewhere between draconian rigid requirements and
completely freeform cowboy (and cowgirl!) coding practices. The problem was that being
in the middle wasn’t working. So, we looked at some of the newest practices
in the industry.
</p>
        </blockquote>
        <p>
Eric goes on to list the benefits he's seen since adopting Scrum:
</p>
        <blockquote>
          <ul>
            <li>
Since adopting Scrum, the first two releases of VitalSite 5 have been on-target, meeting
both scope and deadline requirements (5.0 in January and 5.1 in May). 
</li>
            <li>
Software development is accelerating each sprint - we’re approaching twice the
speed we had last year. 
</li>
            <li>
There’s much more collaboration between disciplines 
</li>
            <li>
The morale of the software team is higher 
</li>
            <li>
Quality of the software we’re delivering is better 
</li>
          </ul>
        </blockquote>
        <p>
With results like that I can see why a CEO would like scrum.  As developer though,
I like scrum in that it doesn't get in my way.  There is administrative overhead
to Scrum to be sure.  However it's very "XP" in that there aren't scads
of documentation to write.  Generally as a software professional I like to write
code and solve problems and for the most part Scrum allows me to do that.  My
development does not feel slowed down by Scrum, which I believe for most developers,
is a must in order to be adopted willingly.
</p>
        <p>
One side effect of scrum is that is causes me to think about the process in a pleasant
way.  This morning at our standup meeting, a fellow developer and I got into
a discussion about how his extra exploratory work in the evenings should be factored
into our sprint.  Should we could his work towards our sprint commitment? 
Will his work negatively/positively affect our velocity for future sprints? 
From my experience, developers typically don't worry about this stuff however with
Scrum the sprint commitment is something that should be taken seriously.  As
such it was good to see developers, of which I was one, having talks about other things
that just the code.
</p>
        <p>
I'm sure many other processes out there could achieve the same thing.  Scrum
for us, both in this job and the previous, provided a nice framework that was palatable
to developers. In that respect I'm perfectly happy using Scrum.  I will keep
my ears open for new ideas and processes, but I think for any development methodology
to be successful in an organization, it has to be readily and whole-heartedly adopted. 
We've enjoyed Scrum so far and as such, it's a not-so-bad development methodology. 
If you aren't using a methodology or your current process isn't working, you should
give Scrum a try.
</p>
        <img width="0" height="0" src="http://www.timbarcz.com/blog/aggbug.ashx?id=964ca953-e91e-484f-a3f8-8b98817f9f7b" />
      </body>
      <title>Scrum - A Not-so-bad Development Methodology</title>
      <guid isPermaLink="false">http://www.timbarcz.com/blog/PermaLink,guid,964ca953-e91e-484f-a3f8-8b98817f9f7b.aspx</guid>
      <link>http://www.timbarcz.com/blog/ScrumANotsobadDevelopmentMethodology.aspx</link>
      <pubDate>Mon, 18 Aug 2008 19:48:56 GMT</pubDate>
      <description>&lt;p&gt;
When I first graduated from college I worked on embedded systems where the process
was a formal, military grade process.&amp;#160; When developing software I typically thought
about what document I had to write next and what document(s) I may be missing.&amp;#160;
In general, the MIL standards turned me off a bit to process, and for awhile left
me thinking that process is an obstruction to true development.&amp;#160; As a 21 year
old, you think code = development.&amp;#160; That was/is an immature point of view, but
it was not a viewpoint that I was easily dissuaded from.&amp;#160; Further it's a point
of view that many out there still hold dear, and not all who hold that view are recent
college graduates.
&lt;/p&gt;
&lt;p&gt;
Recently a small group of us decided to give &lt;a href="http://www.controlchaos.com/"&gt;Scrum&lt;/a&gt; a
try and are using it to drive our current project.&amp;#160; Other than this effort, there
is no formal process methodology in place.&amp;#160; My goal is to help change that in
my new position.&amp;#160; Over the past several years many high value projects have never
been worked on because there was no common backlog of all of the things that need
to be done.
&lt;/p&gt;
&lt;p&gt;
In my last job at Geonetric we adopted Scrum after the absence of a formal methodology
and it provided a much needed framework around which to develop.&amp;#160; Many CEO's
are not this up front with their deficiencies, but &lt;a href="http://www.geonetric.com/about/leadership.asp"&gt;Eric&lt;/a&gt; is
pretty awesome and &lt;a href="http://geovoices.wordpress.com/2008/05/13/adopting-agile-processes/"&gt;very
honest in his evaluation&lt;/a&gt; of &lt;a href="http://www.geonetric.com"&gt;Geonetric&lt;/a&gt;:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
As we were in the middle of developing the newest version of our VitalSite product
last fall, we weren&amp;#8217;t making the progress we wanted-even though the whole team
was running full tilt and putting in its best efforts. We had always been a bit informal
about how we developed software-somewhere between draconian rigid requirements and
completely freeform cowboy (and cowgirl!) coding practices. The problem was that being
in the middle wasn&amp;#8217;t working. So, we looked at some of the newest practices
in the industry.
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Eric goes on to list the benefits he's seen since adopting Scrum:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;ul&gt;
&lt;li&gt;
Since adopting Scrum, the first two releases of VitalSite 5 have been on-target, meeting
both scope and deadline requirements (5.0 in January and 5.1 in May). 
&lt;/li&gt;
&lt;li&gt;
Software development is accelerating each sprint - we&amp;#8217;re approaching twice the
speed we had last year. 
&lt;/li&gt;
&lt;li&gt;
There&amp;#8217;s much more collaboration between disciplines 
&lt;/li&gt;
&lt;li&gt;
The morale of the software team is higher 
&lt;/li&gt;
&lt;li&gt;
Quality of the software we&amp;#8217;re delivering is better 
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
With results like that I can see why a CEO would like scrum.&amp;#160; As developer though,
I like scrum in that it doesn't get in my way.&amp;#160; There is administrative overhead
to Scrum to be sure.&amp;#160; However it's very &amp;quot;XP&amp;quot; in that there aren't scads
of documentation to write.&amp;#160; Generally as a software professional I like to write
code and solve problems and for the most part Scrum allows me to do that.&amp;#160; My
development does not feel slowed down by Scrum, which I believe for most developers,
is a must in order to be adopted willingly.
&lt;/p&gt;
&lt;p&gt;
One side effect of scrum is that is causes me to think about the process in a pleasant
way.&amp;#160; This morning at our standup meeting, a fellow developer and I got into
a discussion about how his extra exploratory work in the evenings should be factored
into our sprint.&amp;#160; Should we could his work towards our sprint commitment?&amp;#160;
Will his work negatively/positively affect our velocity for future sprints?&amp;#160;
From my experience, developers typically don't worry about this stuff however with
Scrum the sprint commitment is something that should be taken seriously.&amp;#160; As
such it was good to see developers, of which I was one, having talks about other things
that just the code.
&lt;/p&gt;
&lt;p&gt;
I'm sure many other processes out there could achieve the same thing.&amp;#160; Scrum
for us, both in this job and the previous, provided a nice framework that was palatable
to developers. In that respect I'm perfectly happy using Scrum.&amp;#160; I will keep
my ears open for new ideas and processes, but I think for any development methodology
to be successful in an organization, it has to be readily and whole-heartedly adopted.&amp;#160;
We've enjoyed Scrum so far and as such, it's a not-so-bad development methodology.&amp;#160;
If you aren't using a methodology or your current process isn't working, you should
give Scrum a try.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.timbarcz.com/blog/aggbug.ashx?id=964ca953-e91e-484f-a3f8-8b98817f9f7b" /&gt;</description>
      <comments>http://www.timbarcz.com/blog/CommentView,guid,964ca953-e91e-484f-a3f8-8b98817f9f7b.aspx</comments>
      <category>Agile</category>
      <category>Scrum</category>
    </item>
    <item>
      <trackback:ping>http://www.timbarcz.com/blog/Trackback.aspx?guid=fb255463-50aa-449f-a1bc-a8ab7ea62a9b</trackback:ping>
      <pingback:server>http://www.timbarcz.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.timbarcz.com/blog/PermaLink,guid,fb255463-50aa-449f-a1bc-a8ab7ea62a9b.aspx</pingback:target>
      <dc:creator>Tim Barcz</dc:creator>
      <wfw:comment>http://www.timbarcz.com/blog/CommentView,guid,fb255463-50aa-449f-a1bc-a8ab7ea62a9b.aspx</wfw:comment>
      <wfw:commentRss>http://www.timbarcz.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=fb255463-50aa-449f-a1bc-a8ab7ea62a9b</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://www.timbarcz.com/blog/content/binary/WindowsLiveWriter/TheTortoiseandtheHare_EC7E/image_10.png">
            <img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="327" alt="image" src="http://www.timbarcz.com/blog/content/binary/WindowsLiveWriter/TheTortoiseandtheHare_EC7E/image_thumb_4.png" width="475" align="right" border="0" />
          </a> We're
all familiar with the <a href="http://www.storyarts.org/library/aesops/stories/tortoise.html">Aesop's
fable of the tortoise and the hare</a>.  In the story, the hare, who is in every
way is faster than the tortoise, loses a race to the tortoise.  The main principle
of the story is that slow and steady wins the race.
</p>
        <p>
In my development I am shooting to be a tortoise, really I am.  Read on and let
me explain.
</p>
        <p>
A few weeks ago I got some evil glares when I suggested at our .NET user group meeting
that in enterprise systems that you don't have time <strong>not</strong> to test. 
It's a common hurdle for those new to testing to say, "I don't have time to write
tests."  Let's face it, we're all busy, that excuse is tired.  As an
agile and lean practitioner I seek out ways to improve velocity and reduce waste,
not take my already busy schedule and cram in another tool for the sake of another
tool.  While writing tests does slow me down, it brings on tortoise like speed,
which I would argue is a good thing.  Writing unit tests is one tool that provide
me the ability to keep a more consistent velocity over the course of development. 
Without tests I can surely write things faster, the problem arises as the codebase
grows and each new feature or fix takes increasingly more time. Eventually, even simple
requests become arduous to implement.  Slowly you see your velocity come to a
crawl.
</p>
        <p>
It's an insidious cycle that I've seen before and am currently in the throes of; an
application is built from scratch implementing everything the business requires. The
application is enhanced and bolted on to, until you realize that you could move much
faster if you could start from scratch.  You make pleas to your boss and explain
how much productivity would improve if you could shed the hideous code base. 
One day he gives in, you rejoice and you make the leap, start from scratch, breathing
a sigh of relief at how easy implementing the features are all the while reminiscing
about the old framework and how poorly it was written.  And now that the application
is rewritten from scratch the cycle, unless you were aware of it all the while, starts
again.
</p>
        <p>
You see, no one sets out to write crap code.  People do the best they can with
the knowledge they have.  Code, following the <a href="http://en.wikipedia.org/wiki/Laws_of_thermodynamics">second
law of thermodynamics</a>, tends towards chaos over time.  With unit tests in
place I can refactor with more confidence and implement new features without the fear
of breaking existing code.  If you have the ability to refactor, new code is
no longer "bolted on" but rather "grafted in" becoming part of
the system.  With a solid framework with tests in place you can much better stop
the cycle of rewrites.  Quickly writing applications that degrade is the way
of the hare.  Developing purposefully using unit tests causes me to be slow in
the short run, but over the life of the application comes out far ahead.  In
that way, I strive to be the tortoise.
</p>
        <img width="0" height="0" src="http://www.timbarcz.com/blog/aggbug.ashx?id=fb255463-50aa-449f-a1bc-a8ab7ea62a9b" />
      </body>
      <title>The Tortoise and the Hare</title>
      <guid isPermaLink="false">http://www.timbarcz.com/blog/PermaLink,guid,fb255463-50aa-449f-a1bc-a8ab7ea62a9b.aspx</guid>
      <link>http://www.timbarcz.com/blog/TheTortoiseAndTheHare.aspx</link>
      <pubDate>Mon, 11 Aug 2008 17:14:13 GMT</pubDate>
      <description>&lt;p&gt;
&lt;a href="http://www.timbarcz.com/blog/content/binary/WindowsLiveWriter/TheTortoiseandtheHare_EC7E/image_10.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="327" alt="image" src="http://www.timbarcz.com/blog/content/binary/WindowsLiveWriter/TheTortoiseandtheHare_EC7E/image_thumb_4.png" width="475" align="right" border="0" /&gt;&lt;/a&gt; We're
all familiar with the &lt;a href="http://www.storyarts.org/library/aesops/stories/tortoise.html"&gt;Aesop's
fable of the tortoise and the hare&lt;/a&gt;.&amp;#160; In the story, the hare, who is in every
way is faster than the tortoise, loses a race to the tortoise.&amp;#160; The main principle
of the story is that slow and steady wins the race.
&lt;/p&gt;
&lt;p&gt;
In my development I am shooting to be a tortoise, really I am.&amp;#160; Read on and let
me explain.
&lt;/p&gt;
&lt;p&gt;
A few weeks ago I got some evil glares when I suggested at our .NET user group meeting
that in enterprise systems that you don't have time &lt;strong&gt;not&lt;/strong&gt; to test.&amp;#160;
It's a common hurdle for those new to testing to say, &amp;quot;I don't have time to write
tests.&amp;quot;&amp;#160; Let's face it, we're all busy, that excuse is tired.&amp;#160; As an
agile and lean practitioner I seek out ways to improve velocity and reduce waste,
not take my already busy schedule and cram in another tool for the sake of another
tool.&amp;#160; While writing tests does slow me down, it brings on tortoise like speed,
which I would argue is a good thing.&amp;#160; Writing unit tests is one tool that provide
me the ability to keep a more consistent velocity over the course of development.&amp;#160;
Without tests I can surely write things faster, the problem arises as the codebase
grows and each new feature or fix takes increasingly more time. Eventually, even simple
requests become arduous to implement.&amp;#160; Slowly you see your velocity come to a
crawl.
&lt;/p&gt;
&lt;p&gt;
It's an insidious cycle that I've seen before and am currently in the throes of; an
application is built from scratch implementing everything the business requires. The
application is enhanced and bolted on to, until you realize that you could move much
faster if you could start from scratch.&amp;#160; You make pleas to your boss and explain
how much productivity would improve if you could shed the hideous code base.&amp;#160;
One day he gives in, you rejoice and you make the leap, start from scratch, breathing
a sigh of relief at how easy implementing the features are all the while reminiscing
about the old framework and how poorly it was written.&amp;#160; And now that the application
is rewritten from scratch the cycle, unless you were aware of it all the while, starts
again.
&lt;/p&gt;
&lt;p&gt;
You see, no one sets out to write crap code.&amp;#160; People do the best they can with
the knowledge they have.&amp;#160; Code, following the &lt;a href="http://en.wikipedia.org/wiki/Laws_of_thermodynamics"&gt;second
law of thermodynamics&lt;/a&gt;, tends towards chaos over time.&amp;#160; With unit tests in
place I can refactor with more confidence and implement new features without the fear
of breaking existing code.&amp;#160; If you have the ability to refactor, new code is
no longer &amp;quot;bolted on&amp;quot; but rather &amp;quot;grafted in&amp;quot; becoming part of
the system.&amp;#160; With a solid framework with tests in place you can much better stop
the cycle of rewrites.&amp;#160; Quickly writing applications that degrade is the way
of the hare.&amp;#160; Developing purposefully using unit tests causes me to be slow in
the short run, but over the life of the application comes out far ahead.&amp;#160; In
that way, I strive to be the tortoise.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.timbarcz.com/blog/aggbug.ashx?id=fb255463-50aa-449f-a1bc-a8ab7ea62a9b" /&gt;</description>
      <comments>http://www.timbarcz.com/blog/CommentView,guid,fb255463-50aa-449f-a1bc-a8ab7ea62a9b.aspx</comments>
      <category>Agile</category>
      <category>Musings</category>
    </item>
  </channel>
</rss>