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

<channel>
	<title>Software Creation Mystery &#187; Design</title>
	<atom:link href="http://softwarecreation.org/category/design/feed/" rel="self" type="application/rss+xml" />
	<link>http://softwarecreation.org</link>
	<description>What are the forces behind software development?</description>
	<lastBuildDate>Wed, 07 Jul 2010 04:34:52 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>The Elements of Pragmatic Programming Style. Composition.</title>
		<link>http://softwarecreation.org/2009/the-elements-of-pragmatic-programming-style-composition/</link>
		<comments>http://softwarecreation.org/2009/the-elements-of-pragmatic-programming-style-composition/#comments</comments>
		<pubDate>Mon, 19 Jan 2009 02:25:56 +0000</pubDate>
		<dc:creator>Andriy Solovey</dc:creator>
				<category><![CDATA[Concepts]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[Practices]]></category>
		<category><![CDATA[Process]]></category>
		<category><![CDATA[Productivity]]></category>
		<category><![CDATA[Skills]]></category>

		<guid isPermaLink="false">http://softwarecreation.org/2009/the-elements-of-pragmatic-programming-style-composition/</guid>
		<description><![CDATA[ShareA really great talent finds its happiness in execution. &#8211; Johann Wolfgang von Goethe
 
source
Qualities of well composed code:

  Quick discovery and understanding of programming logic and components
  Clear organization (for human brains)
  Ease of reuse, modification and evolution
  Close connection between customer ideas and system implementation


Style Components:

Intention - understand your [...]]]></description>
			<content:encoded><![CDATA[<div class='dd_post_share'><div class='dd_buttons'><div class='dd_button'><iframe src='http://api.tweetmeme.com/button.js?url=http://softwarecreation.org/2009/the-elements-of-pragmatic-programming-style-composition/&source=AndriySolovey&service=&service_api=&style=compact' height='20' width='90' frameborder='0' scrolling='no'></iframe></div><div class='dd_button'><a name='fb_share' type='button_count' share_url='http://softwarecreation.org/2009/the-elements-of-pragmatic-programming-style-composition/' href='http://www.facebook.com/sharer.php'>Share</a><script src='http://static.ak.fbcdn.net/connect.php/js/FB.Share' type='text/javascript'></script></div><div class='dd_button'><script src='http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://softwarecreation.org/2009/the-elements-of-pragmatic-programming-style-composition/'></script></div><div class='dd_button'><a title='Post on Google Buzz' class='google-buzz-button' href='http://www.google.com/buzz/post' data-button-style='small-count' data-url='http://softwarecreation.org/2009/the-elements-of-pragmatic-programming-style-composition/'></a><script type='text/javascript' src='http://www.google.com/buzz/api/button.js'></script></div><div class='dd_button'><iframe src='http://widgets.dzone.com/links/widgets/zoneit.html?url=http://softwarecreation.org/2009/the-elements-of-pragmatic-programming-style-composition/&amp;title=The+Elements+of+Pragmatic+Programming+Style.+Composition.&amp;t=2' height='18' width='120' frameborder='0' scrolling='no'></iframe></div></div></div><div style='clear:both'></div><p id="ua_7" style="padding: 1em 0pt; text-align: left"><em><span class="huge">A really great talent finds its happiness in execution.</span></em> &#8211; <span class="bodybold">Johann Wolfgang von Goethe</span></p>
<p id="ua_7" style="padding: 1em 0pt; text-align: left"> <img src="http://softwarecreation.org/images/2009/architect.png" /></p>
<p><a href="http://upload.wikimedia.org/wikipedia/commons/thumb/f/fb/Architect.png/485px-Architect.png" class="photocredit">source</a></p>
<p>Qualities of well composed code:</p>
<ol>
<li>  Quick discovery and understanding of programming logic and components</li>
<li>  Clear organization (for human brains)</li>
<li>  Ease of reuse, modification and evolution</li>
<li>  Close connection between customer ideas and system implementation</li>
</ol>
<p><span id="more-80"></span></p>
<p>Style Components:</p>
<ul>
<li><strong><a href="http://softwarecreation.org/2008/the-elements-of-pragmatic-programming-style-intention/">Intention</a> </strong>- understand your task and how to get it done</li>
<li><strong><a href="http://softwarecreation.org/2008/the-elements-of-pragmatic-programming-style-approach">Approach</a> </strong>- basic principles of writing code</li>
<li><strong>Composition </strong>- organization of code</li>
<li><strong>Expression </strong>- expressing ideas in code</li>
<li><strong>Object Oriented Pragmatic Style</strong></li>
</ul>
<p style="margin-top: 30px; margin-bottom: 0px">  <strong>1. Design for customer problems<br />
</strong>Make the customer problem space a core for the software system design. Make every line of code accountable for solving customer needs. It is true that any software system requires a lot of plumbing beyond pure implementation of customer needs. However, technology concerns shouldn&#8217;t prevail. High-level languages and modern programming platforms give us a power to concentrate on customer problems more than on solving technical problems.</p>
<p style="margin-top: 0px; margin-bottom: 0px"> Code could be divided into two categories:</p>
<ul>
<li>  <strong>customer oriented</strong> &#8211; solves customer problems directly, e.g. implementing domain logic, UI interactions and display of information;</li>
<li>  <strong>system oriented</strong> &#8211; solves technical and application specific problems &#8211; data access, event handling, interfaces between subsystem, utilities and other code required for using libraries, systems and platforms.</li>
</ul>
<p style="margin-top: 0px; margin-bottom: 0px">Customer-oriented code brings most value and should be primary design concern.  System-oriented code puts in place infrastructure and support for running customer oriented code.</p>
<p style="margin-top: 0px; margin-bottom: 0px"> <em>Therefore, start with design of customer-oriented code and support it with minimal system-oriented code.</em> This doesn&#8217;t mean that system-oriented code is not important. Complex system environments, sophisticated user interfaces and challenging non-functional requirements (performance, availability, reliability, etc.) could demand major system-oriented development effort. But still customers needs should pull and direct this effort and the whole implementation.<br />
There are many ways to make technical problems dominant over customer problems:</p>
<ol>
<li> Making predetermined technical decisions (databases, programming platforms, messaging systems, expensive middle tier etc.) without considering simpler alternatives.</li>
<li>  Coming up with complex up-front design instead of evolving a simple design into optimal design.</li>
<li>  Starting programming around interesting technical problems forgetting what is important for a customer.</li>
<li>  Building frameworks and system-oriented code before writing code for immediate customer problems.</li>
</ol>
<p>For a example, some teams could start with this picture in mind stretching customer requirements to fit it (even for relatively simple applications).</p>
<p id="faph" style="padding: 1em 0pt; text-align: left"><img src="http://softwarecreation.org/images/2009/microsoft-esb.png" width="60%" height="60%" /></p>
<p> <a href="http://msdn.microsoft.com/en-us/library/bb264584.aspx" class="photocredit">source</a><br />
<strong>2. </strong><strong>Organize and evolve code around domain concepts and customer ideas</strong><br />
Make system design reflecting customer domain and problem space. Keep customer ideas and system implementation connected and synchronized all the time. This is as important as refactoring practice for effective creation of the software system.<br />
<a href="http://domaindrivendesign.org/" title="Domain-driven design" id="myqk">Domain-driven design</a> is an excellent way to build software systems. It puts emphasis on ubiquitous language, distilled domain knowledge and shared domain models that drive software development.</p>
<p><strong>3. Think as a customer<br />
</strong><em>What we see depends mainly on what we look for</em> &#8211; John Lubbock<br />
A programmer often considers programming as an opportunity for solving interesting technical problems. Often a programmer even doesn&#8217;t understand what customers really want. There are 2 consequences. First, the programmer is not interested in simpler solutions focused on the customer problem. Second, the programmer is missing coherent view on the customer problems and purpose of the software system. Over-engineered, complex and misaligned code is one of the most serious problems in software development. An army of business analysts, stressed project managers and smart customer proxies will not force indifferent and ignorant programmers to write code in the best interest of customer.<br />
The programmer should constantly ask himself: &#8220;Will this solution work for my customer?&#8221;. To give correct answer on this simple question the programmer should understand a lot &#8211; customer language, needs, problems, a big picture and business purpose.</p>
<p>Certainly, it is difficult to think as a customer if you are at the bottom of software creation chain:</p>
<ul>
<li> separated from a customer by project and product managers, architects, designers, consultants, experts and panels of stakeholders</li>
<li>  pressed by the heavy process, rigid organization structure and inability to make decisions</li>
<li>  fed with over-processed, distorted and disjointed doses of information coming down through long chain</li>
</ul>
<p>Beautiful software ideas <a href="http://softwarecreation.org/2008/how-a-beautiful-software-system-becomes-frankenstein/" title="can turn into monster applications" id="b2hi">can turn into monster applications</a> &#8211; unusable and disconnected from real needs. Did you feel (as a user) frustrated by complex confusing and irrational program screens and logic? Yes, we, programmers, can easily produce bad stuff if we cannot think as people who need our systems.</p>
<p><strong>4. Sketch programming ideas with unit tests.</strong><br />
Write unit tests first. Any programmer should understand what he is trying to solve with the new code and how it will be used &#8211; possible input, expected output and public interface. A programmer should think about behavior in isolation, under border conditions or within context of existing code. An unit test is an excellent place to sketch nonexistent code, play with it without compilation and see if it is convenient and makes sense. Once the programmer likes sketched ideas in unit tests, he just need to build simple implementation to satisfy these unit tests. The process of writing unit tests focuses a programmer on solving customer problems, understanding code intent and making optimal design decisions. As an additional side effect, the programmer receives comprehensive suite of automated regression tests and executable specifications.</p>
<p>For a example,<br />
<code><br />
CustomerDB.Save(TEST_USER, TEST_PWD)<br />
Customer customer = CustomerDB.Login(TEST_USER, TEST_PWD);<br />
Assert.IsNotNull(customer, "customer should be logged in");<br />
customer.Purchase(TEST_PRODUCT);<br />
List&lt;Order&gt; orders = OrderDB.LoadFor(customer) or maybe... customer.Orders //what is better?<br />
Assert.AreEqual(1, orders.Count, "count");<br />
</code><br />
There are many design decision are made in this unit test without writing any production code. And now programmer can concentrate on implemention without throes of creation.</p>
<p><strong>5. Eliminate duplication</strong><br />
<em>Simplification is ultimate sophistication</em> &#8211; da Vinci<br />
Elimination of duplication is the moving force of evolutionary design. This is straightforward and powerful method to grow an optimal system. Duplication in the code tells that you need better design. Many interesting design ideas are born from the simple need to eliminate duplication in the growing system. These ideas are based on deeper understanding and gained experience as oppose to speculative up-front design ideas.<br />
The main goals of removing duplication are</p>
<ul>
<li>  reduce code</li>
<li>  simplify solution</li>
<li>  make the system more manageable for programmers&#8217; minds.</li>
</ul>
<p>Some sources of duplication:</p>
<ul>
<li>  copy and paste &#8211; <a href="http://softwarecreation.org/2008/a-few-words-in-defense-of-copy-and-paste-programming/" title="acceptable only temporary" id="ml24">acceptable only temporary</a></li>
<li>  similar logic different in details &#8211; generalization is required</li>
<li>  another implementation for the same problem &#8211; better team communication and reuse are required</li>
</ul>
<p><em>Master the core skill of good evolutionary designers &#8211; how to detect and eliminate duplication.</em><br />
The knowledge of design patterns is the most useful on this step. The <a href="http://softwarecreation.org/2008/the-elements-of-pragmatic-programming-style-approach/" id="ucd5" title="initial simple solution">initial simple solution</a> rarely requires design patterns. But as a system grows, design patterns can effectively and elegantly solve new complex design problems.<br />
Example of elimination of high level duplication with Template method design pattern<br />
This code was used in many data access classes almost the same way, but with different inner steps</p>
<pre>
        using (SqlConnection conn = NewSqlConnection())

        {

            SqlCommand cmd = conn.CreateCommand();

            cmd.CommandType = CommandType.StoredProcedure;

            cmd.CommandText = "SearchCustomers";

            cmd.Parameters.Add(new SqlParameter("@city", city));

            ... //long list of parameters

            conn.Open();

            try

            {

                using (SqlDataReader reader = cmd.ExecuteReader())

                {

                    foreach (DbDataRecord record in reader)

                        customers.Add(new Customer(record["id"], record["name"]))

                }

            }

            catch (Exception e)

            {

                //error handling logic here

            }

        }</pre>
<p>The common logic could be moved into one template method with placeholders for different steps:</p>
<pre>
List&lt;Customer&gt; customers =  LoadRecordsFromSP&lt;Customer&gt;("SearchCustomers",

    (SqlCommand cmd) =&gt; {

         cmd.Parameters.Add(new SqlParameter("@city", city));

         ...     //long list of parameters

    },

    (DbDataRecord record) =&gt; { new Customer(record["id"], record["name"]); }

);</pre>
<p><strong>6. Reduce code smells</strong><br />
Write code that doesn&#8217;t smell. Train your sense of smell for code and design problems. They will provide hints where code is probably bad.<br />
These are common bad smells<span class="mw-headline"></span> from <a href="http://wiki.java.net/bin/view/People/SmellsToRefactorings" id="e9im" title="a long list">a long list</a></p>
<ul>
<li>  Duplicated code</li>
<li>  Large method</li>
<li>  Large class</li>
<li>  Long parameter list</li>
<li>  Dead Code</li>
<li>  Over-generalized code</li>
<li>  Lazy class</li>
</ul>
<p><strong>7. Use design patterns and abstractions to make code simpler</strong><br />
Learn <a href="http://en.wikipedia.org/wiki/Design_pattern_%28computer_science%29" title="design patterns" id="j72i">design patterns</a>. At some level of complexity they will provide excellent solutions and simplify design.<br />
However, wrong abstractions and over used design patterns will make code more complex and less manageable. So, apply them carefully.</p>
<p><strong>8. Decouple and isolate components</strong><br />
<em>Only talk to your immediate friends; Don&#8217;t talk to strangers</em> &#8211; <a href="http://www.ccs.neu.edu/research/demeter/demeter-method/LawOfDemeter/general-formulation.html" title="Law of Demeter" id="z1sj">Law of Demeter</a>.<br />
Reduce connections between programming units &#8211; subsystems, modules and objects &#8211; as much as possible. More relations between components make software system more complex and rigid. Decoupled and isolated system components have significant benefits:</p>
<ul>
<li><strong>better understanding</strong> &#8211; easier to keep in memory and make sense for less states and relations</li>
<li><strong>increased reuse</strong> &#8211; components with minimal well-defined public interface and relations less dependent on context and can be used in many scenarios</li>
<li><strong>decreased breakdowns</strong> &#8211; caused by unpredictable run-time combination of relations</li>
<li><strong>effective testing</strong> &#8211; highly connected system require much more testing beyond isolated testing of components</li>
</ul>
<p id="e0-1" style="padding: 1em 0pt; text-align: left"><img src="http://softwarecreation.org/images/2009/predictability.gif" /></p>
<p><strong>9. Keep related code together</strong><br />
Put related code to the same package. It will enhance</p>
<ul>
<li>  <strong>discovery </strong>- easier to find and reuse</li>
<li>  <strong>design </strong>- allows isolation, minimal interactions and consistent structure for related components</li>
<li>  <strong>maintenance and testing </strong>- reduce effect of new changes to fewer packages and system components.</li>
</ul>
<p>There are two package approaches: <strong><br />
</strong></p>
<ul>
<li>  <strong>Feature</strong> &#8211; code related to the same problem placed together</li>
<li>  <strong>Application layers</strong> &#8211; code for similar programming concepts</li>
</ul>
<p>Benefits of packaging:</p>
<ul>
<li>  Feature: related code in one place, changes together and form self-sufficient granule for reuse and release</li>
<li>  Application: separation of concerns, logical layering and reduced dependencies,  consistent global structure</li>
</ul>
<p id="f-z:" style="padding: 1em 0pt; text-align: left"><img src="http://softwarecreation.org/images/2009/packaging.jpg" width="500" height="500" /></p>
<h3>  Composing the program &#8211; Putting Things Together</h3>
<ol>
<li>Understand what customer wants and form <a href="http://softwarecreation.org/2008/the-elements-of-pragmatic-programming-style-intention/" id="i2c6" title="intent">intent</a>.</li>
<li>Translate customer ideas into programming concepts (technology, platform and language, UI, libraries, components)</li>
<li>Make them simple, minimal and clear with pragmatic <a href="http://softwarecreation.org/2008/the-elements-of-pragmatic-programming-style-approach/" id="v-gg" title="approach">approach</a>.</li>
<li>Organize code around domain concepts and customer needs; use domain-driven design.</li>
<li>Describe UI ideas with paper sketches</li>
<li>Specify program ideas with automated unit tests.</li>
<li>Merge UI and program ideas</li>
<li>Package related ideas together, isolate subsystems and components</li>
<li>Express ideas in code and UI screens</li>
<li>Remove duplication and bad code smells; improve design; consider using design patterns</li>
<li>Evolve and refactor common code into framework; emerge layers and abstractions for similar concepts</li>
</ol>
<!-- Social Buttons Shared Counts Generated by Digg Digg plugin v4.0.9, 
    Author : Yong Mook Kim
    Website : http://www.mkyong.com/blog/digg-digg-wordpress-plugin/ --><img src="http://softwarecreation.org/?ak_action=api_record_view&id=80&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://softwarecreation.org/2009/the-elements-of-pragmatic-programming-style-composition/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>The Elements of Pragmatic Programming Style. Approach.</title>
		<link>http://softwarecreation.org/2008/the-elements-of-pragmatic-programming-style-approach/</link>
		<comments>http://softwarecreation.org/2008/the-elements-of-pragmatic-programming-style-approach/#comments</comments>
		<pubDate>Wed, 03 Dec 2008 04:01:38 +0000</pubDate>
		<dc:creator>Andriy Solovey</dc:creator>
				<category><![CDATA[Concepts]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[Practices]]></category>
		<category><![CDATA[Productivity]]></category>
		<category><![CDATA[Skills]]></category>

		<guid isPermaLink="false">http://softwarecreation.org/2008/the-elements-of-pragmatic-programming-style-approach/</guid>
		<description><![CDATA[SharePerfection is achieved, not when there is nothing more to add, but when there is nothing left to take away. &#8211; Antoine De Saint Exupery
The approach to programming is concerned with finding the best ways to translate programmer&#8217;s intention into the good system design and code.

The programming is communication. The programmer continuously add, change and [...]]]></description>
			<content:encoded><![CDATA[<div class='dd_post_share'><div class='dd_buttons'><div class='dd_button'><iframe src='http://api.tweetmeme.com/button.js?url=http://softwarecreation.org/2008/the-elements-of-pragmatic-programming-style-approach/&source=AndriySolovey&service=&service_api=&style=compact' height='20' width='90' frameborder='0' scrolling='no'></iframe></div><div class='dd_button'><a name='fb_share' type='button_count' share_url='http://softwarecreation.org/2008/the-elements-of-pragmatic-programming-style-approach/' href='http://www.facebook.com/sharer.php'>Share</a><script src='http://static.ak.fbcdn.net/connect.php/js/FB.Share' type='text/javascript'></script></div><div class='dd_button'><script src='http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://softwarecreation.org/2008/the-elements-of-pragmatic-programming-style-approach/'></script></div><div class='dd_button'><a title='Post on Google Buzz' class='google-buzz-button' href='http://www.google.com/buzz/post' data-button-style='small-count' data-url='http://softwarecreation.org/2008/the-elements-of-pragmatic-programming-style-approach/'></a><script type='text/javascript' src='http://www.google.com/buzz/api/button.js'></script></div><div class='dd_button'><iframe src='http://widgets.dzone.com/links/widgets/zoneit.html?url=http://softwarecreation.org/2008/the-elements-of-pragmatic-programming-style-approach/&amp;title=The+Elements+of+Pragmatic+Programming+Style.+Approach.&amp;t=2' height='18' width='120' frameborder='0' scrolling='no'></iframe></div></div></div><div style='clear:both'></div><p><em>Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away.</em> &#8211; Antoine De Saint Exupery</p>
<p>The approach to programming is concerned with finding the best ways to translate programmer&#8217;s <a href="http://softwarecreation.org/2008/the-elements-of-pragmatic-programming-style-intention/" title="intention" id="pd51">intention</a> into the good system design and code.</p>
<p><img src="http://softwarecreation.org/images/2008/hemingway.jpg" /></p>
<p>The programming is communication. The programmer continuously add, change and refine ideas in the code. Source code has two important goals: <strong>tell a computer what to do </strong>and<strong> tell people what the computer should do</strong>. The program code is the only true medium for storing and communicating ideas about the software system behavior. Quality of the ideas expression in the code directly affects overall quality of the system.</p>
<p>So, what are characteristics of the good code?</p>
<ol>
<li><strong>clear </strong>- easier to work with ideas;</li>
<li><strong>minimal </strong>- less effort to understand and change ideas;</li>
<li><strong>testable </strong>- easier to validate ideas.</li>
</ol>
<p>These are 6 top reasons for bad design and code:</p>
<ol>
<li>lack of expertise</li>
<li>unrestrained technical curiosity and creativity</li>
<li>missing big picture: system purpose and customer goals</li>
<li>blindly following popular methods and over-using technology</li>
<li>sloppiness; lack of attention to details</li>
<li>over-complicating design to have more work or increase job security</li>
</ol>
<p>The programmer can write better code (and avoid most of these problems) by improving programming style and approach.</p>
<p><span id="more-77"></span><strong>Style Components:</strong></p>
<ul>
<li><a href="http://softwarecreation.org/2008/the-elements-of-pragmatic-programming-style-intention/"><strong>Intention </strong></a>- understand your task and how to get it done</li>
<li><strong>Approach </strong>- basic principles of writing code</li>
<li><strong><a href="http://softwarecreation.org/2009/the-elements-of-pragmatic-programming-style-composition/">Composition</a> </strong>- organization of code</li>
<li><strong>Expression </strong>- expressing ideas in code</li>
<li><strong>Object Oriented Pragmatic Style</strong></li>
</ul>
<h3>Approach</h3>
<p>Two most important rules are</p>
<ul>
<li>work from the simplest design</li>
<li>revise and refactor after each task</li>
</ul>
<p><strong>1. Work from the simplest design</strong><br />
The simplest design that solves business needs is the best design. The simplest design is the product of discipline and mastery. The simplest design requires creative thinking &#8211; it is easier to follow traditional ways than to come up the simple, but clear and powerful solution.</p>
<p>Agile development has famous principle <a href="http://c2.com/xp/DoTheSimplestThingThatCouldPossiblyWork.html" title="DTSTTCPW" id="rjki">DTSTTCPW</a> (Do The Simplest Thing That Could Possibly Work) best explained by <a href="http://www.xprogramming.com/" title="Ron Jeffries" id="oo4_">Ron Jeffries</a>:</p>
<blockquote><p>We&#8217;re saying consider all solutions to your task that could possibly work. Implement the simplest solution. Refactor from there if and when needed&#8230;  And we&#8217;re saying that when you do enhance the simple solution (and you generally will), you will always wind up with a system that is just right for what it does so far. And we&#8217;re saying that that is just where you want to be. Everything just right, nothing added that isn&#8217;t needed.</p></blockquote>
<p>For example, if you love design patterns, MVC and object oriented programming, you may end up with design below for finding orders by customer&#8217;s postal code.</p>
<p><img src="http://softwarecreation.org/images/2008/design-complex.jpg" /></p>
<p>I love these patterns too, but I would still recommend to start with the simpler design.</p>
<p>The simplest design is the most effective way to deliver business value. You spend less time, build more reliable, easier to understand and change solution. You save energy for other tasks and reduce load on your hard-working brains.</p>
<p>Why do people not go for the simplest solution all the time? There are three main reasons:</p>
<ul>
<li><em>unintentional </em>- the programmer didn&#8217;t find simpler solution (lack of experience, pressure and no time to think, relying on traditional ways, compliance with architect&#8217;s grand design and others)</li>
<li><em>intentional </em>- the programmer wants to over-complicate solution for personal benefits (play with interesting technology, build up resume or increase scope of paid work)</li>
<li><em>foretelling </em>- the programmer bets on the future advantage of more complex design</li>
</ul>
<p>The last reason is the most compelling for many programmers. What if your experience and knowledge tells you that you will need this more advanced design and additional code?<br />
Lets do cost-benefit analysis</p>
<p><img src="http://softwarecreation.org/images/2008/simplest-design.jpg" /></p>
<p>What are the chances of mismatch with our initial expectations for a non-trivial project? Big. Mismatch with expectations happens when we learn more from technology, domain and customer feedback while programming. Mismatch happens when we understand the problem deeper and come up with the better solutions. Mismatch happens when the new requirements are coming, priorities are altered and the whole world around is changing (e.g. new company opportunities or credit crunch and economic downturn).</p>
<p>As we can see <strong>the best approach is the simplest design that requires little refactoring in the future and doesn&#8217;t prohibit anticipated design evolution</strong>. Therefore, use you experience and intuition to predict direction of the design evolution. Use this knowledge not for making design more complex to accommodate this prediction, but for ensuring that the simplest solution is not stupid, prohibitive for evolution and will survive coming changes.</p>
<p>However, the level of expertise has significant impact on the choice. The novice programmer should use standard well-described solutions and learn how to simplify them later. The expert programmer should be more comfortable to design simple, sound and easy to evolve solutions from the start.</p>
<p><strong>2. Revise and refactor</strong><br />
Focus on the simplest local design and code for individual features without revisions and design improvements could sometimes create global mess and painful complexity .</p>
<p>For example, it is bad, if after adding several features, your OrderDB contains many methods like LoadForPostalCode, LoadForPostalCodeAndStatus, LoadShippedOrders and web pages are overloaded with domain logic. This kind of code calls for refactoring.</p>
<p>Revise and refactor after completing any programmer tasks.<br />
You should ask yourself 4 questions:</p>
<ul>
<li>Can I reduce code?</li>
<li>Can I make code clearer?</li>
<li>Can I make code more testable?</li>
<li>Can I make the whole system simpler?</li>
</ul>
<p>Refactor, if you answer yes to any of these questions. Learn <a href="http://c2.com/xp/CodeSmell.html" title="code smells" id="sz3_">code smells</a> to identify concrete places that need refactoring. Learn <a href="http://www.refactoring.com/" title="refactoring techniques" id="w_yn">refactoring techniques</a> to improve code.<br />
Main methods:</p>
<ul>
<li>remove duplication and increase code reuse</li>
</ul>
<ul>
<li>create abstractions to generalize individual cases</li>
<li>use design patterns to simplify design</li>
</ul>
<p>Refactoring is one the most important practice for productive software creation. Refactoring allows to keep the system in the good shape all the time &#8211; simple, well designed, ready to change. Implementing the simplest solutions without refactoring and <a href="http://softwarecreation.org/2008/selecting-the-best-strategy-for-software-teams-retreat-evolution-or-revolution/" title="evolutionary approach" id="ye41">evolutionary approach</a> is risky.</p>
<p>Other rules should enhance your approach further.</p>
<p><strong>3. Discover Form and Function in parallel. </strong><br />
<em>Form follows Function</em> is a traditional principle in design. In other words, customers requirements dictate user interface. However, discovery of complex interactions could affect what the customer wants and change understanding of needs. Sometimes starting with UI paper sketches and discussing them with customers could expose missing details, gaps in understanding and suggest better ways to satisfy customer needs.  <em>Therefore, work on discovery of Form and Function</em><em> of the system</em><em> in parallel.</em></p>
<p><strong>4. Avoid using new tools</strong><br />
<em>New Systems Mean New Problems</em> &#8211; The Fundamental Theorem of <a href="http://en.wikipedia.org/wiki/Systemantics" title="Systemantics" id="ztgg">Systemantics</a><br />
Do not use new languages, tools and libraries unless existing are bad and you can tolerate high risk and delays.<br />
Every new programming tool claim to make you more productive and powerful. Few of them really do this. But , it is guaranteed, that every new tool takes time for learning and brings new problems.<br />
I know that it is hard to continue using old tools for a long time and stay competitive in fast moving software development world. But try to limit impact on customer. It is not fair to make them victims of your learning and experiments. <em>Create separate experimental prototypes and <a href="http://en.wikipedia.org/wiki/Greenfield_project" title="greenfield" id="zl:r">greenfield</a> projects to evaluate new tools and approaches.</em> Prefer to be honest and transparent with your client about risks of new technologies, tools and approaches.</p>
<p><strong>5. Use creative ideas sparingly</strong><br />
Creative ideas can bring excellent solutions. However, any creative idea adds element of unexpectedness and departure from established ways to solve similar problems. Programmers will spend more time to understand creative ideas and will have challenges to support them. <em>Therefore, use creative ideas when they bring significant advantages (especially to simplify solution) and avoid them in trivial situations.</em> Don&#8217;t worry, you will always find where to apply your creative energy if you are productive, build good solutions and have more and more customers.</p>
<p><strong>6. Prefer standard solutions to the non-standard</strong><br />
This rule compliments the previous rule. Standard solutions are based on experience of many people. Maybe they are not the best in your particular case, but they often are safe bet if these problems are new for you. You can find many examples, quickly learn how to apply them and understand consequences beforehand. New creative solutions will make life more interesting in expense of productivity and certainty in the final results. <em>Therefore, prefer standard solutions to reinventing the wheel again.</em> Don&#8217;t forget to learn how to make them simpler.</p>
<p><strong>7. Separate production code and experiments</strong><br />
Restrain technical curiosity when writing production code. Many programmers find the joy of programming in solving complex problems. It is so tempting to solve difficult technical puzzles and try out new cool techniques without need. However, the pragmatic programmer solves complex customer problems with simple solutions, instead of creating complex solutions for the simple problems.<br />
Think first about customer requirements and simple design. <em>Experiment and look for the new solutions only if you cannot find simple solutions with familiar methods.</em> Keep your production and experimental code separately. Adopt ideas from experiments without unnecessary complication of the solution.</p>
<p><strong>8. Do not overwrite (or over-eingeneer)</strong><br />
Write minimal code relevant to present customer requests. Surprisingly, complex over-engineered solutions are easier to create &#8211; just follow recent trends and try to anticipate everything that came to mind. The simplest and clear solutions require extra effort.<br />
Over-engineering harms the software system, takes away precious time and project money. <em>Avoid over-engineering if you are motivated to build good system and satisfy your customer.</em></p>
<p><strong>9. Write own code for the core and use external components for supporting functionality.</strong><br />
Concentrate your effort on writing code for the core functions specific to customer domain or code that is bringing competitive advantage. Don&#8217;t waste too much effort on secondary supportive functions. For example, there are many good enough libraries, for solving standard dynamic web user interface needs &#8211; <a href="http://www.prototypejs.org/" title="prototype" id="rr.e">prototype</a>, <a href="http://jquery.com/" title="jQuery" id="h3g5">jQuery</a>, <a href="http://www.asp.net/ajax/" title="Microsoft AJAX" id="nbwt">Microsoft AJAX</a>, <a href="http://developer.yahoo.com/yui/" title="Yahoo user interface library" id="exel">Yahoo user interface library</a> and others &#8211; but many programmers are still building their own solutions. I like to have full control over my software systems and write as much as possible components, but <em>one cannot embrace unembraceable</em> (<a href="http://en.wikipedia.org/wiki/Kozma_Prutkov" title="Kozma Prutkov" id="sz1h">Kozma Prutkov</a>). <em>You have to trust some parts of the system to other libraries that will save time and do better job</em> (but bring new problems).</p>
<p><strong>10. Do not write code for future</strong>.<strong> </strong><br />
The dirty trick of predicting the future is that future is unpredictable. Everything else is fine. Written for the future code adds unnecessary complexity. This code is useless for the present problems. <em>Avoid writing code for the future and strive for the simplest solutions for the present needs.</em></p>
<p><strong>11. Write code for other programmers</strong><br />
Can other programmers understand your code? Do you have clear names, consistent formatting and self-explaining code? <em>Writing code for others will make code better for you.</em></p>
<p><strong>12. Switch between big picture and details</strong><br />
Good programmers can focus on the big picture and still pay attention to details. <em>Clear intention and forward thinking are as important as reliable implementation.</em></p>
<p><strong>13. Pair program for complex problems</strong><br />
Pair programming brings <a href="http://alistair.cockburn.us/Costs+and+benefits+of+pair+programming" title="significant benefits" id="xm9g">significant benefits</a>:</p>
<ul>
<li>better ideas &#8211; two brains solving the problems</li>
<li>better quality &#8211; two pair of eyes validating code</li>
<li>better knowledge &#8211; two programmers understand implementation and ideas behind</li>
<li>better productivity &#8211; problems are solved faster</li>
<li>more enjoyment &#8211; people like to communicate and work together</li>
</ul>
<p>I&#8217;m still not sure about serious benefits of pair programming for simple and routine programming tasks. But many Agile teams <a href="http://www.extremeprogramming.org/rules/pair.html" title="pair program" id="xbve">pair program</a> for all production code and like results.</p>
<p><strong>Putting It All Together</strong></p>
<p><img src="http://softwarecreation.org/images/2008/approach-to-programming.jpg" /></p>
<p><strong>Inspiring reference:</strong> <em>The Elements of Style</em>, W. Strunk Jr. and E.B. White</p>
<!-- Social Buttons Shared Counts Generated by Digg Digg plugin v4.0.9, 
    Author : Yong Mook Kim
    Website : http://www.mkyong.com/blog/digg-digg-wordpress-plugin/ --><img src="http://softwarecreation.org/?ak_action=api_record_view&id=77&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://softwarecreation.org/2008/the-elements-of-pragmatic-programming-style-approach/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>What can Software Development learn from Biological Evolution?</title>
		<link>http://softwarecreation.org/2008/what-software-development-can-learn-from-biological-evolution/</link>
		<comments>http://softwarecreation.org/2008/what-software-development-can-learn-from-biological-evolution/#comments</comments>
		<pubDate>Fri, 11 Jul 2008 17:39:07 +0000</pubDate>
		<dc:creator>Andriy Solovey</dc:creator>
				<category><![CDATA[Concepts]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[Process]]></category>
		<category><![CDATA[System]]></category>

		<guid isPermaLink="false">http://softwarecreation.org/2008/what-software-development-can-learn-from-biological-evolution/</guid>
		<description><![CDATA[ShareFrom the first sight biological evolution looks too unpredictable to have any value for the constrained software development. We just don&#8217;t have time, money and resources for these wild experiment, unlimited trials and errors. It really seems that Nature could learn from us how to make things fast and effectively.   However, there are [...]]]></description>
			<content:encoded><![CDATA[<div class='dd_post_share'><div class='dd_buttons'><div class='dd_button'><iframe src='http://api.tweetmeme.com/button.js?url=http://softwarecreation.org/2008/what-software-development-can-learn-from-biological-evolution/&source=AndriySolovey&service=&service_api=&style=compact' height='20' width='90' frameborder='0' scrolling='no'></iframe></div><div class='dd_button'><a name='fb_share' type='button_count' share_url='http://softwarecreation.org/2008/what-software-development-can-learn-from-biological-evolution/' href='http://www.facebook.com/sharer.php'>Share</a><script src='http://static.ak.fbcdn.net/connect.php/js/FB.Share' type='text/javascript'></script></div><div class='dd_button'><script src='http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://softwarecreation.org/2008/what-software-development-can-learn-from-biological-evolution/'></script></div><div class='dd_button'><a title='Post on Google Buzz' class='google-buzz-button' href='http://www.google.com/buzz/post' data-button-style='small-count' data-url='http://softwarecreation.org/2008/what-software-development-can-learn-from-biological-evolution/'></a><script type='text/javascript' src='http://www.google.com/buzz/api/button.js'></script></div><div class='dd_button'><iframe src='http://widgets.dzone.com/links/widgets/zoneit.html?url=http://softwarecreation.org/2008/what-software-development-can-learn-from-biological-evolution/&amp;title=What+can+Software+Development+learn+from+Biological+Evolution%3F&amp;t=2' height='18' width='120' frameborder='0' scrolling='no'></iframe></div></div></div><div style='clear:both'></div><p>From the first sight biological evolution looks too unpredictable to have any value for the constrained software development. We just don&#8217;t have time, money and resources for these wild experiment, unlimited trials and errors. It really seems that Nature could learn from us how to make things fast and effectively. <br id="p0h40" /> <br id="e5.s" /> However, there are some principles that helped evolution to come up with amazing and efficient designs that made life flourishing on the Earth. This post will explore what software development could learn from biological evolution. See my <a href="http://softwarecreation.org/2008/comparing-intelligent-software-evolution-to-chaotic-biological-evolution/" title="previous post" id="qpz4">previous post</a> for the review of evolution concepts and mechanisms and how they could be applied to software development.</p>
<p><img src="http://softwarecreation.org/images/2008/software-evolution.jpg" /></p>
<p><span id="more-66"></span></p>
<h3 id="e0yy0"><strong id="gz5c">1. </strong><strong id="x5we0">Evolution works</strong></h3>
<p>The evidence is richness of our flora and fauna which adapted to almost all possible conditions on our planet. <a href="http://www.astrobiology.com/extreme.html" title="Organisms live" id="a-sp">Organisms live</a> in <a href="http://www.dac.neu.edu/biology/k.bergman/WebsiteBarney/matt/psychrophiles.htm" title="polar ice" id="johi">polar ice</a>, in <a href="http://en.wikipedia.org/wiki/Hypolith" title="desert rocks" id="vhzx">desert rocks</a>, in the <a href="http://ijs.sgmjournals.org/cgi/reprint/53/2/533.pdf" title="bottom of Pacific ocean Mariana Trench" id="w-o7">bottom of Pacific ocean Mariana Trench</a> (11 km deep) and even <a href="http://www.panspermia.org/bacteria.htm" title="on the Moon" id="xau9">on the Moon</a>.</p>
<p><img src="http://softwarecreation.org/images/2008/human-evolution.gif" width="548" height="354" /></p>
<blockquote id="xi66"><p>Evolutionary approach is one of the most powerful and proven methods known to us for designing effective systems under complex uncertain conditions. There are no reasons why software teams should ignore this approach &#8211; they indeed often deal with complex <a href="http://softwarecreation.org/2007/software-requirements-are-elusive-6-reasons-why-customers-cannot-get-them-right/" title="uncertain requirements" id="qqov">uncertain requirements</a> and environment.<br id="xo_b" /></p></blockquote>
<p>There are 2 areas where evolutionary approach could be used:<br id="p245" /></p>
<ol id="p2450">
<li id="p2451">project management &#8211; enhance the way people work and interact for building a system</li>
<li id="wlgk">design and build &#8211; the growth of this software system itself.<br id="g0s3" /></li>
</ol>
<p><br id="m1_i" /> Simple Steps:<br id="uil2" /></p>
<ol id="uil20">
<li id="uil21">Generate new and modify existing ideas (increase variations).</li>
<li id="du2t">Select potentially best ideas for building software better in a specific environment (form project genotype)<br id="du2t0" /></li>
<li id="wlgk0">Make this generation of ideas work for some time (interact with environment).<br id="d6.u" /></li>
<li id="wlgk1">Learn from results &#8211; keep useful and dump harmful ideas (natural selection &#8211; improve fitness).<br id="q6k8" /></li>
<li id="wlgk2">Go to the first step and produce the new generation of ideas<br id="k6jc" /></li>
</ol>
<p><br id="kmh1" /> We can make this process more intelligent and less random and still learn a lot from biological evolution.<br id="gz5c0" /></p>
<h3 id="e0yy1"><strong id="db2n">2. Increase beneficial variations or how to generate good ideas.</strong></h3>
<p><img src="http://softwarecreation.org/images/2008/round-table.jpg" /><br id="x01c" />Organisms will not evolve without getting new variations of traits. Some new variations in a gene pool could lead to better survival and fitness, but most of them are harmful. Software development genotype is a pool of ideas applied for building a specific software system.<br id="q360" /> <br id="gb:80" /> How could we generate many good ideas and avoid harmful?<br id="qb4e" /> <br id="sxk93" /> <strong id="dxgb">Mechanisms</strong><strong id="vggg"> of idea&#8217;s evolution</strong><br id="odn2" /></p>
<ul id="xc3j4">
<li id="xc3j5"><strong id="h:ne0">Mutations </strong>- continuous invention and modification of the new approaches based on individual creative insights and team brainstorming<br id="y1x3" /></li>
<li id="xc3j7"><strong id="h:ne1">Reshuffling </strong>- recombination of existing ideas</li>
<li id="odn20"><strong id="h:ne2">Gene flow</strong> &#8211; outside expert opinions and borrowed ideas from other disciplines (engineering, art, architecture, manufacturing, etc.) and study of complex systems (physical, biological, markets, societies, etc.)<br id="u_29" /></li>
</ul>
<h4 id="fzr2">Prerequisites for generating many quality ideas:</h4>
<p><strong id="fi1z">Powerful software teams with diverse range of</strong><br id="kohz0" /></p>
<ul id="goni">
<li id="goni0"><strong id="ywwz">skills / specialization</strong> &#8211; they cover broad knowledge areas of software development: customer domain and needs, project management, UI design, development, testing<br id="goni1" /></li>
<li id="goni2"><strong id="ywwz0">expertise / experience</strong> &#8211; combination of different approaches, insights and methods of experienced professionals with fresh ideas of newcomers.<br id="goni3" /></li>
<li id="goni4"><strong id="ywwz1">personalities</strong> &#8211; various traits that complement the whole team: creativity, discipline, pragmatism, attention to details , imagination, focus and leadership.</li>
</ul>
<p><br id="q329" /> <strong id="eqyo">Decentralized control / self-organization</strong><br id="eqyo0" /> Centralized control reduces ability to come up with new ideas, which are not compliant with imposed top views. People from bottom, who implement the system, could generate better ideas, because they know environment deeply, experience it closely and receive immediate feedback from it. Independent people, who have control over project decisions and responsible for results will strive to make the best decisions.<br id="eqyo1" /> <br id="eqyo2" /> <strong id="eqyo3">Idea incubator</strong><br id="rn:x" /></p>
<ul id="q3290">
<li id="q3292">Free flow of ideas, sharing of knowledge and expertise.<br id="s28d" /></li>
<li id="q3293">Encouragement for innovative and creative thoughts and tolerance to failures.</li>
<li id="rt55">Opportunity for every team member to express ideas, be heard and respected.<br id="rt550" /></li>
</ul>
<blockquote id="xe-e"><p>Good ideas in a software project are necessary foundation of success, lack of them is disaster. Do whatever is possible to generate many good ideas.<br id="gz5c2" /></p></blockquote>
<h3 id="e0yy2"><strong id="db2n1">3. Improve Fitness &#8211; keep useful and dump harmful ideas<br id="f95t" /> </strong></h3>
<p><img src="http://softwarecreation.org/images/2008/natural-selection.png" /><br id="wx8v" /></p>
<p>Genes passed to the next generation are result of two factors: Fitness (natural selection) and Chance (genetic drift).<br id="o5_v3" /> <br id="o5_v4" /> How could we improve blind process of selecting best ideas and avoid high failure rate? <br id="o5_v5" /> <br id="kfz8" /> <strong id="t_gz0">Establish clear fitness criteria</strong><br id="x5we1" /> Every organism have clear short-term goals &#8211; survive and reproduce to accomplish the long term goal &#8211; passing and increasing share of their genes in the next generations.<br id="kfz80" /> Software projects should have clear fitness criteria, which aligns team members, guide their decisions and actions. Criteria should be relevant to the most important goals of the project. It could reflect the purpose of the system, time to market, quality or cost. It should be clear, short and really important for survival and success.<br id="r_gm" /> <br id="l1t41" /> <strong id="pl9m0">Maintain selection pressure and increase role of Fitness vs. Chance</strong><br id="pl9m1" /> Low natural selection leads to more complex solutions. Most mutations which don&#8217;t increase fitness will be eliminated in a large population with fierce competition and strong selection pressure. This process could lead to a greater simplicity keeping only useful for fitness traits. In populations without much selection pressure, genetic drift increase chances of new genes survival (even disadvantageous). So population could have increased genes complexity without much advantage for fitness.<br id="nj_8" /> <br id="s5j90" /> <strong id="y3a71">Avoid genetic drift</strong><br id="cylh0" /> Genetic drift produces random changes in the frequency of traits in a population, which results from the role chance plays in whether a given individual will survive and reproduce. Chance play enormous role in biological evolution (maybe even more important than natural selection) and a great source of inefficiency. We can do better in software development. Transparent and independent decision making, self organization and power of diverse opinions will substantially decrease the role of the Blind Chance.<br id="loi_0" /></p>
<blockquote id="xe-e0"><p>Therefore, a team with many good ideas shaped by selection pressure and fitness criteria will produce the best results.</p></blockquote>
<h3 id="yhyc">4. Pragmatic implementation</h3>
<p><img src="http://softwarecreation.org/images/2008/fins-to-limbs.jpg" /><br id="awzn" /> <strong id="vu9q0">Good enough working solutions</strong><br id="vu9q1" /> Animals shouldn&#8217;t be perfectly adapted, they just need to be in par with their competitors. Natural selection requires only requires something to work, not perfectly but work. Evolution is more likely reshape existing structures than invent new ones.<br id="z4ji0" />  The classic example is the <a href="http://pandasthumb.org/about.html" id="z4ji1" target="ns">panda&#8217;s thumb</a>, which it uses to grasp bamboo. The panda&#8217;s true thumb is committed to another role. The <a href="http://en.wikipedia.org/wiki/Sarcopterygii" title="lobed fins of early fish" id="keza">lobed fins of early fish</a> have turned into structures as diverse as wings, fins, hoofs and hands. <br id="cesb0" /></p>
<blockquote id="p7z-"><p>In software we could be satisfied with solutions which are not perfect at the beginning. We can live with them knowing that evolution forces and pressure will shape ideas behind and we will make these solutions better with more experience.<br id="ag7i" /></p></blockquote>
<p><strong id="tefk0">Practical and immediate purpose</strong><br id="om5h0" /></p>
<blockquote id="s.i.1"><p> Every new feature in the system should have some immediate purpose &#8211; evolution invented only something that has purpose.<br id="jjun0" /></p></blockquote>
<p><strong id="b1y2">Exaptation</strong> &#8211; structures and behaviors that evolved for one purpose but take on a wholly new one, while remaining useful at every intermediate stage. It means that some features cannot evolve if they are not completely useful immediately. Two way radio could be useful for animal communication, but it didn&#8217;t evolve, because half-way radio is useless &#8211; it doesn&#8217;t tell anything useful for animals about their environment. Visible light is different &#8211; any small improvement in vision can provide big advantage in many environments.<br id="ph:s" /> There is an interesting question: could we miss great design ideas if we only develop for immediate purpose? There are many useful inventions that came as a result of fundamental science curiosity without much practical need at the beginning. However, I&#8217;m inclined to believe that software development is <a href="http://softwarecreation.org/2007/is-software-development-empirical-or-rational/" title="empirical discipline" id="z4rp">empirical discipline</a> and more effective with developing for immediate purpose only.<br id="afgq" /> <strong id="wppf2"><br id="wppf3" /> </strong><strong id="a33g">Repurposing</strong><br id="a33g0" /> Repurposing a structure does not have to involve the loss of the original structure. Reptilian jaw bones turned into mammalian ear bones, without the loss of the jaw. The neural circuitry that allows us to make fine limb movements may have been adapted to produce speech as well.</p>
<p>Sometimes just one aspect of a feature can be co-opted for another use. The first hard mineralised structures to evolve in our ancestors were the teeth of early fishes known as conodonts. Once the ability to form hard hydroxyapatite had evolved, it could be exploited elsewhere in the body and may have been the basis of the bony skeletons of all vertebrates.</p>
<p>Repurposing is an interesting lesson for the software development &#8211; successful reuse of existing structures for the new functions. At the first glance, it goes against main principles of good software design &#8211; single responsibility, isolation and decoupling of components. Biological organisms don&#8217;t have much choice with mutations- which could add only small changes. But efficient and economical designs of many organisms suggest that repurposing could be a good strategy. We could maximize reuse of the components for different purposes while keeping smaller inner parts isolated. Relentless refactoring, removal of duplication and creating abstractions are the main methods. The ultimate condition is <a href="http://softwarecreation.org/2008/the-secret-of-building-effective-software-systems/" title="good understanding and mental control over the system" id="a7bp">good understanding and mental control over the system</a>.<br id="j:lf" /> <br id="afgq0" /> <strong id="wppf4">No refactoring (or elimination of unused traits)</strong><br id="tefk1" /> Lack of refactoring seems as a serious flaw of biological evolution. New organisms repurpose what exists and build new structures on top of old without cleaning and eliminating unnecessary stuff. DNA has a lot of junk. These structures are not needed<br id="sat31" /></p>
<ul id="sat32">
<li id="sat33">wings of ostriches</li>
<li id="sat34">appendix<br id="sat35" /></li>
<li id="sat36">male nipples</li>
</ul>
<p>Software team can use refactoring as an essential part of effective and pragmatic implementation and improvement of evolutionary approach.</p>
<h3 id="cs_8"><strong id="juoa">5. Making impossible possible with small continuous changes.</strong></h3>
<p><img src="http://softwarecreation.org/images/2008/making-possible.jpg" /><br id="ty1r" /> Small changes accumulated over time cause substantial changes in organisms. Continuous improvement of the genotype and small frequent changes work for all living organisms in this unpredictable and very complex world. They lead to highly fit, adapted and efficient solutions.<br id="juoa0" /> <br id="xl2v2" /> By weeding out harmful mutations and assembling beneficial ones, natural selection acts like an <strong id="z1_b">&#8220;improbability drive&#8221;</strong> that can, given enough time, produce results that appear completely impossible at first glance.<br id="ok:n" /></p>
<blockquote id="z1_b0"><p>One of the most important lessons for Software Development is possibility to arrive with great solutions without planning and predicting them in advance. It is one of the best strategies in the complex, uncertain and changing environment. <br id="z1_b1" /></p></blockquote>
<p>Agile approach is successful because it strikes the balance between adaptation to changing environment and predictability required for business. <br id="c:gf" /> <br id="b4wg" /> <strong id="b4wg0">Principles:</strong><br id="mnvc" /></p>
<ul id="b4wg1">
<li id="b4wg2">Be open and ready to changes</li>
<li id="b4wg3">Frequently get feedback, change and adjust in small steps</li>
<li id="b4wg4">Continuously learn and reflect what works and what doesn&#8217;t</li>
<li id="b4wg5">Often evaluate if your project and systems are fit for their purpose and environment.</li>
</ul>
<h3 id="c6f10">Summary</h3>
<p>Evolutionary approach works if software team<br id="x3ea" /></p>
<ul id="osa5">
<li id="osa50">can generate many good ideas <br id="sg-2" /></li>
<li id="sg-20">can select most useful ideas how to build the system</li>
<li id="osa51">works under healthy pressure to meet fitness criteria</li>
<li id="rg3e">pragmatic in implementation</li>
<li id="w4.i">learn from results, continuously adapt to needs and environment <br id="w4.i0" /></li>
</ul>
<p><br id="e0r61" /> <strong id="blcs0"> Resources:</strong><br id="wo7l0" /> <a href="http://softwarecreation.org/2008/comparing-intelligent-software-evolution-to-chaotic-biological-evolution/" title="Comparing Intelligent Software Evolution to Chaotic Biological Evolution" id="ep1r">Comparing Intelligent Software Evolution to Chaotic Biological Evolution</a> <br id="nb5p" /> <a href="http://www.newscientist.com/channel/life/dn13620-evolution-24-myths-and-misconceptions.html" title="Evolution: 24 myths and misconceptions" id="z0t3">Evolution: 24 myths and misconceptions</a>, Newscientist (requires subscription)<br id="p-0m0" /> <a href="http://en.wikipedia.org/wiki/Evolution" title="Evolution" id="f5uo">Evolution</a>, Wikipedia</p>
<!-- Social Buttons Shared Counts Generated by Digg Digg plugin v4.0.9, 
    Author : Yong Mook Kim
    Website : http://www.mkyong.com/blog/digg-digg-wordpress-plugin/ --><img src="http://softwarecreation.org/?ak_action=api_record_view&id=66&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://softwarecreation.org/2008/what-software-development-can-learn-from-biological-evolution/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Secret of Building Effective Software Systems</title>
		<link>http://softwarecreation.org/2008/the-secret-of-building-effective-software-systems/</link>
		<comments>http://softwarecreation.org/2008/the-secret-of-building-effective-software-systems/#comments</comments>
		<pubDate>Mon, 19 May 2008 20:55:50 +0000</pubDate>
		<dc:creator>Andriy Solovey</dc:creator>
				<category><![CDATA[Concepts]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[People]]></category>
		<category><![CDATA[Practices]]></category>
		<category><![CDATA[Process]]></category>
		<category><![CDATA[Productivity]]></category>
		<category><![CDATA[Skills]]></category>
		<category><![CDATA[System]]></category>

		<guid isPermaLink="false">http://softwarecreation.org/2008/the-secret-of-building-effective-software-systems/</guid>
		<description><![CDATA[Share
I can&#8217;t wait to share this simple secret with you right now.  The Secret: Effective Software Systems are the systems that easy to understand and operate with human brains.  Programmers are more productive with effective software systems. Programmers can better learn and grow these system. Programmers have less problems, work faster and make [...]]]></description>
			<content:encoded><![CDATA[<div class='dd_post_share'><div class='dd_buttons'><div class='dd_button'><iframe src='http://api.tweetmeme.com/button.js?url=http://softwarecreation.org/2008/the-secret-of-building-effective-software-systems/&source=AndriySolovey&service=&service_api=&style=compact' height='20' width='90' frameborder='0' scrolling='no'></iframe></div><div class='dd_button'><a name='fb_share' type='button_count' share_url='http://softwarecreation.org/2008/the-secret-of-building-effective-software-systems/' href='http://www.facebook.com/sharer.php'>Share</a><script src='http://static.ak.fbcdn.net/connect.php/js/FB.Share' type='text/javascript'></script></div><div class='dd_button'><script src='http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://softwarecreation.org/2008/the-secret-of-building-effective-software-systems/'></script></div><div class='dd_button'><a title='Post on Google Buzz' class='google-buzz-button' href='http://www.google.com/buzz/post' data-button-style='small-count' data-url='http://softwarecreation.org/2008/the-secret-of-building-effective-software-systems/'></a><script type='text/javascript' src='http://www.google.com/buzz/api/button.js'></script></div><div class='dd_button'><iframe src='http://widgets.dzone.com/links/widgets/zoneit.html?url=http://softwarecreation.org/2008/the-secret-of-building-effective-software-systems/&amp;title=The+Secret+of+Building+Effective+Software+Systems&amp;t=2' height='18' width='120' frameborder='0' scrolling='no'></iframe></div></div></div><div style='clear:both'></div><p><img src="http://softwarecreation.org/images/2008/software-unknown.jpg" /></p>
<p>I can&#8217;t wait to share this simple secret with you right now.<br id="bcz60" /> <br id="icww1" /> <span id="yb4h0"><em id="rzm80">The Secret</em></span>: <span id="tmg00"><strong id="lh4q0">Effective Software Systems are the systems that easy to understand and operate with human brains.</strong></span><br id="jwyk0" /> <br id="lfgv0" /> Programmers are more productive with effective software systems. Programmers can better learn and grow these system. Programmers have less problems, work faster and make better decision with them.<br id="lfgv1" /> <br id="jwyk1" /> Now, you can avoid spending time reading this post if you already know this secret and you know how to avoid building the software system that:<br id="jwyk2" /></p>
<ul id="jwyk3">
<li id="jwyk4">almost impossible to understand in reasonable time<br id="cskb0" /></li>
<li id="jwyk4">has confusing and convoluted swamp of logic and structure</li>
<li id="jwyk4">scary to change as nobody has any clue what will be broken, but sure that it will be broken<br id="ys3i0" /></li>
</ul>
<p><br id="df:u0" /> If you are still interested, lets find out what makes software systems effective.<br id="i1br0" /> <br id="fj_60" /> Software Development is a pure mental endeavor (except typing on keyboard) that includes 3 main activities:<br id="q2o50" /></p>
<ul id="ky5w0">
<li id="ky5w1"><span id="qo7g0" style="font-weight: bold">Understand </span>- learn and know system concepts and implementation</li>
<li id="ky5w2"><span id="qo7g1" style="font-weight: bold">Evolve </span>- build, modify and support growth of the system ideas in the code<br id="n51v0" /></li>
<li id="ky5w3"><span id="qo7g2" style="font-weight: bold">Share </span>- communicate and exchange ideas about the system</li>
</ul>
<p><br id="y-gl2" /> Programmers should care about 7 areas to make the system better suited for our brains:<br id="ky5w4" /></p>
<ol id="attr0">
<li id="attr1"><span id="ccgy0"><strong id="pyx80">Knowledge Creation and Retention</strong></span> &#8211; parsing, memorization and comprehension of the system ideas<br id="v1n_0" /></li>
<li id="attr1"><span id="zvyt0"><strong id="pyx81">System Organization</strong></span> &#8211; elements, relations and structure in the system<br id="e:xy0" /></li>
<li id="attr1"><span id="urez0"><strong id="pyx82">Sustaining Emerging Order</strong></span> &#8211; support evolution of the system and gain control over chaos<br id="fwyu0" /></li>
<li id="attr1"><span id="hg-z0"><strong id="pyx83">Minimize Noise</strong></span><span id="r4tk0" style="font-weight: bold"> and Purify</span> &#8211; avoid adding unnecessary stuff to the system<br id="hg-z1" /></li>
<li id="attr1"><span id="mc1a0"><strong id="pyx84">System Discovery and Learning</strong></span> &#8211; making sense of the system<br id="mc1a1" /></li>
<li id="attr1"><span id="mc1a2"><strong id="pyx85">Mental Models</strong></span> &#8211; our internal explanations for how things are working in the real system<br id="j:8d0" /></li>
<li id="attr1"><span id="mc1a3"><strong id="pyx86">Shared Knowledge</strong></span> &#8211; ideas exchange, reconciliation of opinions and creation of mutually enhanced knowledge.</li>
</ol>
<p><span id="more-62"></span></p>
<h3 id="jbhv1">1. Knowledge Creation and Retention<br id="cth80" /></h3>
<p><cite id="ypkf0">Information is not knowledge.</cite> &#8211; Albert Einstein</p>
<p><img src="http://softwarecreation.org/images/2008/knowledge.jpg" /><br id="hapl0" /> <br id="hapl1" /> Programmers should keep as less as possible things in the mind when work with the system. Less information, simpler and more logical ideas behind the code cause less brain damage and more understanding.<br id="cth81" /> Main principles:<br id="cth82" /></p>
<ul id="nrz20">
<li id="nrz21"><span id="ur9t0"><strong id="pyx87">Chunking</strong></span> &#8211; combining many units of information into a limited number of units and chunks, so that information is easier to process and remember. Logical groups (subsystems -&gt; modules -&gt; classes) should contain only few elements. These groups should emerge with growth of the system functionality and complexity. They should replace large clusters of difficult to remember similar and unstructured elements.<br id="m-210" /></li>
</ul>
<ul id="q5os">
<li id="c1yo"><span id="ur9t1"><strong id="pyx88">Abstraction </strong></span>- generalize, find common meaning and remove redundancy in the similar concepts across the system. You can substantially reduce number of ideas required for understanding the system.</li>
<li id="vlkd"><span id="ur9t2"><strong id="pyx89">Simplicity </strong></span>- simpler ideas make understanding (and programmers life) much easier.</li>
<li id="vlkd"><span id="ur9t3"><strong id="pyx810">Isolation </strong></span>- reduce relations and dependencies between elements. These relations add significant complexity to the system and therefore effort to understand and remember them. The volume of knowledge about relations could easily exceed the knowledge about individual elements.</li>
</ul>
<p><br id="j90r0" /> Examples of useful tools for supporting knowledge formation:<br id="j90r1" /></p>
<ul id="f:nj1">
<li id="f:nj2"><span id="g2oc0"><strong id="pyx811">Unit tests</strong></span> &#8211; capture knowledge about the system correct behavior. They evolve with the system and become a parallel verification system. Good unit tests reduce our effort and limit necessary for understanding scope as they focus on the system behavior in isolated components and functions.<br id="f:nj3" /></li>
<li id="f:nj4"><span id="rikw0"><strong id="pyx812">Visuals </strong></span>- take advantage of diagrams, <a href="http://en.wikipedia.org/wiki/Mind_map" title="mind maps" id="j::n">mind maps</a> and pictures to simplify, distill and integrate important knowledge and ideas about the system<br id="d8s50" /></li>
<li id="f:nj5"><span id="e2nd0"><strong id="pyx813">Storytelling </strong></span>- create imagery, emotions and understanding of the system behavior through stories (our <a href="http://softwarecreation.org/2008/the-programmers-brains-at-work-understanding-the-software-system/" title="episodic memory" id="os4o">episodic memory</a> is very powerful). For example, create narratives how users accomplish tasks with your system. Or share dramatic stories how programmers doomed the system with ignoring important practices. <br id="ku0v0" /></li>
</ul>
<h3 id="jbhv5">2. System Organization</h3>
<p><cite id="ypkf1">Be regular and orderly in your <span style="font-weight: bold" id="gqbw0">system organization</span>, so that you may be violent and original in your <span style="font-weight: bold" id="gqbw1">software solutions</span>.</cite>  (paraphrasing Flaubert)</p>
<p><img src="http://softwarecreation.org/images/2008/organization.jpg" /><br id="t0q40" /> <br id="t0q41" /> Human programmers shouldn&#8217;t have hard time to memorize and comprehend a software system. Computers don&#8217;t care much about the organization as long as the logic is correct, but we, human programmers, do. Clear, logical and consistent organization make us much more productive.<br id="ian90" /> Main principles:<br id="ian91" /></p>
<ul id="lxye">
<li id="nfbk"><span id="ib_l0"><strong id="pyx814">Modularity </strong></span>- managing system complexity by dividing large subsystems into multiple, smaller self-contained systems</li>
<li id="n8ng"><span id="ib_l1"><strong id="pyx815">Layering </strong></span>- process of organizing information into related groupings in order to manage complexity and reinforce relationships in the information</li>
<li id="u48h"><span id="ib_l2"><strong id="pyx816">Hierarchy </strong></span>- hierarchical organization is the simplest structure for visualizing and understanding complexity<br id="j90r2" /></li>
</ul>
<h3 id="jbhv6">3. Sustaining Emerging Order</h3>
<p><cite id="ypkf2">Evolution is not a force but a process. Not a cause but a law.</cite> &#8211; John Morley</p>
<p><img src="http://softwarecreation.org/images/2008/evolution.jpg" /><br id="a3or0" /> <br id="a3or1" /> The main challenge for effective system organization is the fact that a system is constantly changing during active development. Good organization today doesn&#8217;t mean good organization tomorrow with many new added features. New customer needs, contribution of fellow developers and growing complexity push a software system to chaos.<br id="jxp-" /> Therefore, we have to keep organization optimal for today needs and still ready for tomorrow changes with<br id="cth83" /></p>
<ul id="br8f0" style="margin-top: 0in" type="disc">
<li id="br8f1" class="MsoNormal"><span id="gy6r0"><strong id="pyx818">Refactoring      </strong></span>– constant effort to improve the system internal      structure and making it effective for recent changes to prevent system degradation and rule of chaos</li>
<li id="br8f2" class="MsoNormal"><span id="uh2c0"><strong id="pyx819">Simple      principles and rules</strong></span> (that everybody follows) help to keep consistency and      integrity of the system in time of intensive growth and modifications.</li>
<li id="br8f4" class="MsoNormal"><span id="i4rm0"><strong id="pyx820">Small independent,      single-purpose components</strong></span> – enable rich behavior with minimum number of      elements, which could participate in various and often unforeseen scenarios. Bigger      components are less reusable, more specialized and lead to more code,      complexity and duplication.</li>
<li id="br8f4" class="MsoNormal"><a href="http://softwarecreation.org/2007/evolutionary-software-architecture-or-why-developers-are-not-janitors/" style="font-weight: bold" title="Building adaptive system" id="lon8">Building adaptive system</a> using agile approach</li>
</ul>
<h3 id="jbhv7">4. Minimize Noise and Purify<br id="omaq0" /></h3>
<p><cite id="p0rn0">Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away.</cite> -Antoine de Saint-Exupery</p>
<p><img src="http://softwarecreation.org/images/2008/noise.jpg" /><br id="tw.y0" /> <br id="wnlj0" /> Complexity is one of the biggest problem for the programmers brains. While good organization and representation of the system ideas help to fight it, the ultimate challenge is to avoid adding unnecessary stuff to the system.<br id="n7:a0" /> <br id="p0rn1" /> Principals for Complexity Reduction:<br id="p0rn2" /></p>
<ul id="bf-b0">
<li id="bf-b1"><span id="p0rn3"><strong id="pyx821">Increase Signal-to-Noise Ratio</strong></span> &#8211; ratio of relevant to irrelevant information in the system. Minimize noise by removing unnecessary elements and minimize the expression of necessary elements.</li>
</ul>
<ul id="bf-b2">
<li id="bf-b3"><span id="bf-b4"><strong id="pyx822">Follow 80/20 Rule (</strong><a href="http://en.wikipedia.org/wiki/Pareto_principle" title="Pareto's Principle" id="obe5"><strong id="pyx823">Pareto&#8217;s Principle</strong></a><strong id="pyx824"> )</strong></span> &#8211; a high percentage of effects in any large system are caused by a low percentage of variables. In other words, 80% of requested functionality will be used rarely or not used at all, while substantially increasing system complexity.<br id="vb9m0" /></li>
<li id="bf-b5"><span id="q03r0"><strong id="pyx825">Consider Good Enough Alternatives</strong></span> &#8211; don&#8217;t dash against the rock implementing exactly what customer asks. Slight modifications and alternatives could often cover need with less effort and complexity.<br id="awte2" /></li>
</ul>
<h3 id="jbhv8">5. System Discovery and Learning<br id="k7nz0" /></h3>
<p><cite id="ypkf3">The real voyage of discovery consists not in seeking new lands, but in seeing with new eyes.</cite> &#8211; Marcel Proust</p>
<p><img src="http://softwarecreation.org/images/2008/discovery.jpg" /><br id="j7y40" /> <br id="o-2g0" /> Learning and navigating the complex software system is a difficult task. Usually developers read code, documentation and debug the system. These methods take time and often are not efficient.<br id="ub::0" /> <br id="q:g80" /> A better way to discover the system and make it discoverable with:<br id="rvyw0" /></p>
<ul id="ufr.0">
<li id="ufr.1"><span id="ufr.2"><strong id="pyx826"> Entry Point</strong></span><span id="ydut0"><strong id="pyx827">s</strong></span> &#8211; points of attentional entry into the system. There are points in the system that doesn&#8217;t require much knowledge about the rest of the system. They could be starting points to understand other elements. For a example, UI screens or the system input / output. Other parts could start making sense and uncover their purpose in relation to these entry points. Discover these points and help newcomers to find them.</li>
<li id="ufr.3"><span id="dc7f0"><strong id="pyx828"> Progressive Disclosure</strong></span> &#8211; a strategy for managing information complexity in which only necessary information is visible at any given time. Good design and coding style allow understanding of intent and logic of the studied system area without deeply diving into boundless waters of implementation details.</li>
</ul>
<p>Code example:<br id="msj:0" /> <code id="ikca0"> Criteria criteria = Criteria.AddPriceRange(10, 100).AddDateRange(Period.LastMonth);<br id="l8j.0" /> IList orders = Database.Orders.LoadBy(criteria);<br id="n9760" /> decimal totalTaxes = orders.Sum(order =&gt; order.Tax)</code>    <br id="tglh0" /></p>
<ul id="ufr.0">
<li id="ufr.4"><span id="mg-x0"><strong id="pyx829"> Recognition over Recall</strong></span> &#8211; memory for recognizing things is better than memory for recalling things. (e.g. multiple choice questions with possible answers vs. fill-in-the-blank questions). Minimize the need to recall information from memory whenever possible. Use tools to make available options clearly visible. For example, <a href="http://msdn.microsoft.com/en-us/library/hcw1s69b%28vs.71%29.aspx" title="Visual Studio Intellisense" id="ryvo">Visual Studio Intellisense</a> and <a href="http://www.jetbrains.com/resharper/" title="Resharper" id="f2wi">Resharper</a> remove need in memorizing members, purpose and syntax of .Net library classes and methods. Build tools or extend a development environment to construct code without memorizing all details.<br id="fw6v0" /></li>
<li id="ufr.5"><span id="lpkt0"><strong id="pyx830"> Inverted pyramid</strong></span> &#8211; method of presentation in which information is presented in descending order of importance. Discover first what is most important and make it easily accessible  following by less and less important information.</li>
<li id="ufr.6"><span id="lpkt1"><strong id="pyx831"> Performance load</strong></span> &#8211; the greater the effort to accomplish a task, the less likely the task will be accomplished successfully. Most important tasks should be easy to accomplish and most valuable information should be easiest to access (including direct access to the people who has the best knowledge).<br id="z61v0" /></li>
<li id="ufr.7"><span id="lpkt2"><strong id="pyx832"> Picture superiority effect</strong></span> &#8211; pictures are remembered better than words. Use pictures and words together to reinforce the learning.</li>
<li id="ufr.8"><span id="ydut1"><strong id="pyx833"> Associations with familiar</strong></span> &#8211; link new information to already familiar concepts. Build on this knowledge by comparing and contrasting to reach deep understanding.<br id="ydut2" /></li>
<li id="ufr.8"><span id="ydut3"><strong id="pyx834">Examples</strong></span> &#8211; learning examples is always one of the best method to understand how to use the system (including best practices, how-to, and tutorials).<br id="ydut4" /></li>
</ul>
<h3 id="jbhv9">6. Mental Models</h3>
<p><cite id="ch7i0">A mental model is an explanation in someone&#8217;s thought process for how something works in the real world.</cite> &#8211; <a href="http://en.wikipedia.org/wiki/Mental_model" title="Wikipedia" id="k4sl">Wikipedia</a></p>
<p><img src="http://softwarecreation.org/images/2008/mental-models.jpg" /><br id="yd.o0" /> <br id="ch7i1" /> People understand systems and environments and interact with them by comparing the outcomes of their mental models with the system and real-world domain concepts. Good mental models bring better understanding and optimal decision making.<br id="fc_n2" /> <br id="mqqf0" /> <span id="x5tm0"><strong id="pyx835"> Schema</strong></span><span id="tt9c0"><strong id="pyx836">ta</strong></span> &#8211; networks of connected ideas or relationships that help to organize experience and information into a meaningful system. Conversation between individuals is most effective if both share common schemata. <br id="eu9j0" /> Examples:<br id="eu9j1" /></p>
<ul id="eu9j2">
<li id="eu9j3"><a href="http://en.wikipedia.org/wiki/Design_pattern_%28computer_science%29" title="design and architecture patterns" id="fm5t">Design and architecture patterns</a> &#8211; general reusable solutions to a commonly occurring problems in software design.</li>
<li id="eu9j4"><a href="http://xp123.com/xplor/xp0004/index.shtml" title="system metaphors" id="qtkr">System metaphors</a> &#8211; a simple story of how the system works. A system metaphor provides common vision and shared vocabulary.<br id="iweu0" /></li>
<li id="eu9j4">Conventions &#8211; standard and well known approaches in architecture, design, code and user interface. They make intuitive and common sense and save mental energy for present and future developers. Custom and novel approaches should be used only if they have serious advantage.<br id="fc_n4" /></li>
</ul>
<h3 id="j:8d3">7. Shared Knowledge</h3>
<p><cite id="ypkf4">I know that you believe you understand what you think I said, but I&#8217;m not sure you realize that what you heard is not what I meant.</cite> &#8211; Robert McCloskey</p>
<p><img src="http://softwarecreation.org/images/2008/shared.jpg" /><br id="bjfn0" /> <br id="t_8r0" /> The system is rarely envisioned, built and used by the same person. A successful system is a result of people interactions &#8211; intensive ideas exchange, reconciliation of opinions and creation of mutually enhanced knowledge. It is not easy for people to properly <a href="http://softwarecreation.org/2007/software-development-is-the-flow-of-ideas-the-rest-is-secondary/" title="translate, communicate and understand" id="ta6o">translate, communicate and understand</a> each other ideas. Complex knowledge, different background and experience increase the gap that people should jump to completely understand each other.<br id="c6sz0" /> Main principles:<br id="szrf0" /></p>
<ul id="s6zq0">
<li id="s6zq1"><span id="j8y80"><a href="http://www.domaindrivendesign.org/discussion/messageboardarchive/UbiquitousLanguage.html" title="Ubiquitous language" id="c3_x"><strong id="pyx837">Ubiquitous language</strong></a></span> &#8211; the shared language that people with different perspectives use to exchange ideas about the system. The same meaning of the words is very important for understanding, but <a href="http://softwarecreation.org/2007/can-computers-beat-human-programmers-part-2-becoming-intelligent/" title="very difficult to achieve" id="hurk">very difficult to achieve</a>.<br id="keiw0" /></li>
<li id="s6zq2"><span id="j8y81"><strong id="pyx838"> Clear goals and intention</strong></span> &#8211; help to align people thinking and actions, and avoid wasteful effort caused by misunderstanding or confusion.<br id="tl400" /></li>
<li id="s6zq4"><span id="j8y82"><strong id="pyx839">Express business domain concepts in the code</strong></span> &#8211; represent business concepts in the code. Developers will better understand domain, synchronize implementation with customer ideas and align the system with relevant business concepts. As a result, the system can effectively grow with the refinement and expansion of business needs.<br id="wz6o0" /></li>
<li id="s6zq5"><span id="j8y83"><strong id="pyx840">Code readability</strong></span> &#8211; good naming and readable code enables better understanding by fellow programmers, reduce chances of errors and lead to correct future modifications.<br id="rsgb0" /></li>
<li id="s6zq6"><span id="j8y84"><strong id="pyx841">Shared mental models</strong></span> &#8211; frequent face-to-face discussions, pair programming and direct conversations with customers bring shared understanding, effective exchange of knowledge and most optimal solutions.<br id="mb.v0" /></li>
</ul>
<p><img src="http://softwarecreation.org/images/2008/software-knowledge.jpg" /></p>
<p>Evolution didn&#8217;t consider adaptation of human brains for software development. But our brains is the most important tool for programming. You cannot change brains (and human nature), so make software development compatible with them. Build effective software systems.<br id="zy4m1" /> <br id="pp8j" /> <span id="s6zq9"><strong id="pyx842">Resources:</strong></span><br />
<a href="http://softwarecreation.org/2008/the-programmers-brains-at-work-understanding-the-software-system/">The Programmer&#8217;s Brains At Work: Understanding The Software System</a><br />
<a href="http://www.amazon.com/gp/product/1592530079/104-3570359-3820730?ie=UTF8&amp;tag=softwcreatmys-20&amp;linkCode=xm2&amp;camp=1789&amp;creativeASIN=1592530079" title="Universal Principles of Design" id="zgk1">Universal Principles of Design</a>, William Lidwell , Kritina Holden, Jill Butler</p>
<!-- Social Buttons Shared Counts Generated by Digg Digg plugin v4.0.9, 
    Author : Yong Mook Kim
    Website : http://www.mkyong.com/blog/digg-digg-wordpress-plugin/ --><img src="http://softwarecreation.org/?ak_action=api_record_view&id=62&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://softwarecreation.org/2008/the-secret-of-building-effective-software-systems/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Is Refactoring a Necessary Waste?</title>
		<link>http://softwarecreation.org/2008/is-refactoring-a-necessary-waste/</link>
		<comments>http://softwarecreation.org/2008/is-refactoring-a-necessary-waste/#comments</comments>
		<pubDate>Fri, 04 Jan 2008 05:22:52 +0000</pubDate>
		<dc:creator>Andriy Solovey</dc:creator>
				<category><![CDATA[Design]]></category>
		<category><![CDATA[Practices]]></category>

		<guid isPermaLink="false">http://softwarecreation.org/2008/is-refactoring-a-necessary-waste/</guid>
		<description><![CDATA[ShareCan we say that clearing house from rubble and debris after home repair is a necessary waste for construction workers? Can we say that making design of the car that could be easily supported and repaired by mechanics is a necessary waste for engineers? Can we say that making ideas clear, easy to follow and [...]]]></description>
			<content:encoded><![CDATA[<div class='dd_post_share'><div class='dd_buttons'><div class='dd_button'><iframe src='http://api.tweetmeme.com/button.js?url=http://softwarecreation.org/2008/is-refactoring-a-necessary-waste/&source=AndriySolovey&service=&service_api=&style=compact' height='20' width='90' frameborder='0' scrolling='no'></iframe></div><div class='dd_button'><a name='fb_share' type='button_count' share_url='http://softwarecreation.org/2008/is-refactoring-a-necessary-waste/' href='http://www.facebook.com/sharer.php'>Share</a><script src='http://static.ak.fbcdn.net/connect.php/js/FB.Share' type='text/javascript'></script></div><div class='dd_button'><script src='http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://softwarecreation.org/2008/is-refactoring-a-necessary-waste/'></script></div><div class='dd_button'><a title='Post on Google Buzz' class='google-buzz-button' href='http://www.google.com/buzz/post' data-button-style='small-count' data-url='http://softwarecreation.org/2008/is-refactoring-a-necessary-waste/'></a><script type='text/javascript' src='http://www.google.com/buzz/api/button.js'></script></div><div class='dd_button'><iframe src='http://widgets.dzone.com/links/widgets/zoneit.html?url=http://softwarecreation.org/2008/is-refactoring-a-necessary-waste/&amp;title=Is+Refactoring+a+Necessary+Waste%3F&amp;t=2' height='18' width='120' frameborder='0' scrolling='no'></iframe></div></div></div><div style='clear:both'></div><p>Can we say that clearing house from rubble and debris after home repair is a necessary waste for construction workers? Can we say that making design of the car that could be easily supported and repaired by mechanics is a necessary waste for engineers? Can we say that making ideas clear, easy to follow and understand is a necessary waste for the influential writer?</p>
<p>Amr Elssamadisy <a href="http://www.infoq.com/news/2007/12/refactoring-is-waste">posted</a> an interesting opinion on InfoQ about refactoring:</p>
<blockquote><p>&#8230; there are two types of waste in Lean: pure waste, and necessary waste. Pure waste is one that has no value to either the team building the software or the customer using the software.  Necessary waste, on the other hand, is the best way we currently know how to do a job even if it does not have customer value.  Refactoring is clearly an instance of the latter.</p></blockquote>
<p>Amr tries to make an important point &#8211; minimize refactoring that doesn&#8217;t contribute directly to customer requirements under development. It is a reasonable point, but I don&#8217;t like word the &#8216;waste&#8217; and belittling of one of the most important practice of the modern developer. This post sparked a very interesting discussion around value of refactoring with many insightful comments (including Kent Beck and Tom Poppendieck).</p>
<p>We, software professionals, sometimes forget that source code is the most important representation of our ideas about how software should work and what it actually does. In the essence, software development is communication, processing and coding of people ideas.  We substantially reduce value of our software if we leave messy, convoluted and difficult to understand software ideas, though correctly implemented. This code will waste time and effort of people who evolves and supports our software (including ourselves). And therefore, it will reduce value of the software for the customers who expects that it will be well supported, easy to change and become better over time. Refactoring is the practice that forces us to improve code and represent software ideas better.</p>
<p>Certainly, as with any complex human activity, we should learn when, how and why we should do refactoring. We should learn how to balance refactoring and development of the new features &#8211; software consolidation and expansion phases (read <a href="http://www.laputan.org/lifecycle/Lifecycle.html">an excellent article</a> from Brian Foote and William F. Opdyke). Refactoring should be not only targeted to reduce <a href="http://martinfowler.com/bliki/TechnicalDebt.html">technical debt</a>, but also to reduce comprehension debt &#8211; understanding, refinement and enhancement of implemented ideas. Finally, refactoring is the essential part of our professional mastery, which distinguish ace programmers from amateurs or indifferent hirelings.</p>
<!-- Social Buttons Shared Counts Generated by Digg Digg plugin v4.0.9, 
    Author : Yong Mook Kim
    Website : http://www.mkyong.com/blog/digg-digg-wordpress-plugin/ --><img src="http://softwarecreation.org/?ak_action=api_record_view&id=53&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://softwarecreation.org/2008/is-refactoring-a-necessary-waste/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Evolutionary Software Architecture or Why Developers Are Not Janitors</title>
		<link>http://softwarecreation.org/2007/evolutionary-software-architecture-or-why-developers-are-not-janitors/</link>
		<comments>http://softwarecreation.org/2007/evolutionary-software-architecture-or-why-developers-are-not-janitors/#comments</comments>
		<pubDate>Tue, 04 Sep 2007 03:01:08 +0000</pubDate>
		<dc:creator>Andriy Solovey</dc:creator>
				<category><![CDATA[Concepts]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[Process]]></category>
		<category><![CDATA[System]]></category>

		<guid isPermaLink="false">http://softwarecreation.org/2007/evolutionary-software-architecture-or-why-developers-are-not-janitors-or-prima-donnas/</guid>
		<description><![CDATA[ShareOpinions about developers varied from janitors to &#8220;prima donnas&#8221; in comments to my previous post Do We Need Software Architects? 10 Reasons Why Not .
Beside discussion about the role of the software architects, the underlying philosophical problem is whether software development is primarily top down (centralized and planned) or bottom up (emergent and adaptive) process. [...]]]></description>
			<content:encoded><![CDATA[<div class='dd_post_share'><div class='dd_buttons'><div class='dd_button'><iframe src='http://api.tweetmeme.com/button.js?url=http://softwarecreation.org/2007/evolutionary-software-architecture-or-why-developers-are-not-janitors/&source=AndriySolovey&service=&service_api=&style=compact' height='20' width='90' frameborder='0' scrolling='no'></iframe></div><div class='dd_button'><a name='fb_share' type='button_count' share_url='http://softwarecreation.org/2007/evolutionary-software-architecture-or-why-developers-are-not-janitors/' href='http://www.facebook.com/sharer.php'>Share</a><script src='http://static.ak.fbcdn.net/connect.php/js/FB.Share' type='text/javascript'></script></div><div class='dd_button'><script src='http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://softwarecreation.org/2007/evolutionary-software-architecture-or-why-developers-are-not-janitors/'></script></div><div class='dd_button'><a title='Post on Google Buzz' class='google-buzz-button' href='http://www.google.com/buzz/post' data-button-style='small-count' data-url='http://softwarecreation.org/2007/evolutionary-software-architecture-or-why-developers-are-not-janitors/'></a><script type='text/javascript' src='http://www.google.com/buzz/api/button.js'></script></div><div class='dd_button'><iframe src='http://widgets.dzone.com/links/widgets/zoneit.html?url=http://softwarecreation.org/2007/evolutionary-software-architecture-or-why-developers-are-not-janitors/&amp;title=+Evolutionary+Software+Architecture+or+Why+Developers+Are+Not+Janitors&amp;t=2' height='18' width='120' frameborder='0' scrolling='no'></iframe></div></div></div><div style='clear:both'></div><p>Opinions about developers varied from janitors to &#8220;prima donnas&#8221; in comments to my previous post <a href="http://softwarecreation.org/2007/do-we-need-software-architects-10-reasons-why-not/" id="qv.1" title="Do We Need Software Architects? 10 Reasons Why Not">Do We Need Software Architects? 10 Reasons Why Not</a> .<br />
Beside discussion about the role of the software architects, the underlying philosophical problem is whether software development is primarily <span style="font-weight: bold">top down</span> (centralized and planned) or <span style="font-weight: bold">bottom up</span> (emergent and adaptive) process. If software development is top down, the architects are essential and crucial people on the project, who concentrate knowledge, establish technical leadership and guide development teams. If software development is bottom up, the developers become primary force for evolving the system, make key technical decisions and care about the architecture; architects (if they still needed) play coordination and mediation roles.</p>
<p>As Goethe said &#8211; between two opposite opinions you’ll find not the truth, but the problem. I incline to consider software development as a bottom up process, which occasionally (often in time of changing direction or crisis) needs centralized effort and top down approach.</p>
<p>Evolutionary, adaptive and emergent development of the software system leads to the most optimal solution. However, any software project usually has specific business goal, constraints and cannot evolve forever as natural systems do. Therefore, the main architecture concern is how to balance these two approaches.</p>
<h3>   Dynamic of the Complex Systems</h3>
<p><img src="http://softwarecreation.org/images/2007/complex-adaptive-system.jpg" title="Complex Adaptive System" alt="Complex Adaptive System" /><br />
<a href="http://en.wikipedia.org/wiki/Complex_adaptive_system" class="photocredit" title="Complex Adaptive System">Complex Adaptive System</a></p>
<p>Many complex systems show organization &#8211; galaxies, biological, market, society, etc. These systems can be explained and studied by referencing their parts, properties and laws (gravitational, supply / demand, etc.). Another approach is to look for the system as a whole, studying dynamic of the elements interaction and system properties &#8211; the science of self-organization.</p>
<p>Can we say that the development of the software system has features of self-organization? Mostly yes, as we have</p>
<ul>
<li>     <span style="font-weight: bold">Fluctuations </span>- optimal solution is not     obvious and needs search; many useful vs. noise factors affect this search</li>
<li>     <span style="font-weight: bold">Local interactions </span>- the software solution     emerge from local interactions between involved people, business needs,     technical platform and IT environment</li>
<li>     <span style="font-weight: bold">Dissipation </span>- a software project     consumes energy to keep going, mostly in the form of money :)</li>
<li>     <span style="font-weight: bold">Instability </span>- software development     deals with constantly changing situations</li>
<li>     <span style="font-weight: bold"> Multiple equilibria</span> &#8211; there are many     possible satisfying solutions</li>
<li>     <span style="font-weight: bold">Complexity </span>- any non-trivial software     project has complexity</li>
<li>     <span style="font-weight: bold">Hierarchies </span>- there are many     perspectives and levels &#8211; organizational, technological and solution domain</li>
</ul>
<p>The only fundamental property, which sometimes is missing for true self-organization &#8211; <strong>autonomy</strong> or absence of external control. Traditional corporation will always exercise some form of the control over software projects. And this is important to resolve &#8211; self-organized systems (evolving bottom up) achieve better solutions than rigid controlled systems. But why self-organized systems can produce better solutions? And what is the best way to control them?</p>
<p><span id="more-33"></span></p>
<h3>   Why self-organized systems are better?</h3>
<ol>
<li>     <span style="font-weight: bold">Distributed control</span> &#8211; &#8220;control&#8221; of the     system organization is typically distributed over the whole of the system.     All parts contribute evenly to the resulting arrangement. The free market is     a good example. There are many independent market agents &#8211; companies and     individuals. Problems with individual company or even market segment doesn&#8217;t     effect economy much as there are always players who will use this     opportunity and take over the vacant niche. The brain is another example.     Its organization is distributed over a network of interacting neurons.     Although different brain regions are specialized for different tasks, no     neuron or group of neurons has overall control. This is shown by the fact     that minor brain lesions because of accidents, surgery or tumors normally do     not disturb overall functioning, whatever the region that is destroyed.
<p style="font-style: italic">Therefore, in effective software projects       any skilled and experienced developer with tacit and specialized knowledge       should have control over architecture decisions in his area as oppose to       giving this control to few architects (or what even worse managers). Global       order should emerge from these local development decisions.</p>
</li>
<li>     <span style="font-weight: bold">Robustness</span> &#8211; self-organized systems     are relatively insensitive to perturbations or errors, and can restore     themselves, unlike most human designed systems. One reason for this     fault-tolerance is the redundant, distributed organization. Another reason     for this intrinsic robustness is that self-organization thrives on     randomness, fluctuations or “noise”, which could bring unexpected and better     solutions. And third reason is stabilizing effect of feedback loops.</li>
<li>     <span style="font-weight: bold">Feedback </span>- the dynamics of a     self-organizing system is typically non-linear, because of circular or     feedback relations between the components.     <a href="http://en.wikipedia.org/wiki/Positive_feedback" id="nn5w" title="Positive feedback">Positive     feedback</a> leads to an explosive growth, which ends when all components     have been absorbed into the new configuration, leaving the system in a     stable,     <a href="http://en.wikipedia.org/wiki/Negative_feedback" id="c9m2" title="negative feedback">negative     feedback</a> state.
<p style="font-style: italic">Effective feedback loops could be       established only with open, adaptive and distributed approach contrary to       closed, rigid and centralized traditional approach to software       development.</p>
</li>
<li>     <span style="font-weight: bold">Emergence </span>- property or feature not     previously observed as a functional characteristic of the system. Self     organization turns a collection of interacting elements into an individual,     coherent whole. Elements produce their own emergent properties and form the     next level of structure in the system, which in turn form the building     blocks for the next higher level of organization, with different emergent     properties, and so on.
<p style="font-style: italic"> Therefore, it is almost impossible to come up with these properties and decisions on the preliminary software design stage. The key for building great software systems is to learn how to tame and use emergence effectively instead of fighting against it.</p>
</li>
<li>     <span style="font-weight: bold">Bifurcations </span>- which of the possible     configurations the system will settle in depends on a chance. A system may settle in a range of stable     configurations. Since small fluctuations are amplified by positive feedback,     this means that even small and impossible to observe fluctuation can lead to     the to completely different project outcome.
<p style="font-style: italic">       Therefore, even if we know business needs, environment and system       specifications at the beginning of the process, the outcome is still       unpredictable. It is waste of effort trying to predict and plan it &#8211; it is better to prepare for changes and adaptation.</p>
</li>
<li>     <span style="font-weight: bold">Adaptation </span>- a configuration of a     system may be called “fit” if it is able to maintain or grow given the     specific configuration of its environment. An &#8220;unfit&#8221; configuration is one     that will disintegrate the system under the given boundary conditions.     Different configurations can be compared as to their degree of fitness, or     probability to survive under the given conditions imposed by the     environment. Thus, adaptation can be defined as achieving a fit between the     system and environment. Systems may be called adaptive if they can adjust to     such changes while keeping their organization as much as possible intact.
<p style="font-style: italic">Considering above points, adaptation is very important for survival and success of the software project.</p>
</li>
<li>     <span style="font-weight: bold">Self Regulation </span>- adaptation can be     considered as a problem of regulation or control: minimizing deviations from     a goal configuration by counteracting perturbations before they become large     enough to endanger the system.
<p style="font-style: italic">Therefore, the software development process should be able to produce variety of actions to cope with each of the possible perturbations and select the best action for the given problem. How it is possible without developers, creators of the software system? They should be empowered, trained and encouraged to do this.</p>
</li>
</ol>
<h3>   How to control a self-organized system?</h3>
<ol>
<li>     <span style="font-weight: bold">Establish attractors</span> (state of     equilibrium, a preferred and stable position for the system). It is better     to establish vision, goals for expected system, good motivation and  <a href="http://softwarecreation.org/2007/fair-compensation-for-programmers-is-it-possible/" title="compensation" id="davx">compensation</a> for the team     instead of telling what to do to and how to achieve this state.</li>
<li>     <span style="font-weight: bold">Establish principles</span> (or fitness     criteria) for choosing the best action for the given circumstances.
<ul>
<li>       The most straightforward method is to let the environment itself determine       what is fit by trial and errors. This can be dangerous for the company since       it may lead to the failure of the software project.</li>
<li>       Another approach is to create internal models of the environment. This       allows to try out a potential action “virtually”, in the model, and       use the model to decide on its fitness. Theoretically, this is the most effective approach and many architect are       trying to follow it, but it is very difficult in reality as this approach should take in consideration huge number of variables and create credible simulation.</li>
<li>       Use simple rules, empirical patterns and best practices &#8211; considering the       current state of the software development it is the best       approach.</li>
</ul>
</li>
<li>     <span style="font-weight: bold">Create effective     </span><a href="http://softwarecreation.org/2007/what-is-the-best-leader-for-the-software-team/" id="crsh" style="font-weight: bold" title="self-organized">self-organized</a><span style="font-weight: bold">     teams.</span></li>
</ol>
<p>Developers are not janitors and prima donnas, because they are the most important people to maintain healthy self organization in the development of the software system, avoid system degradation and lead to the project success. Architects should help developers to establish better attractors, fitness criteria and internal models (or patterns) for selection of the optimal solutions, but they are not the best people to make decisions about these solutions. Certainly it is valid statement,  if we agree that evolution, adaptivity and self-organization are important (bottom up approach). Please notice, in this post I even didn&#8217;t touch <a href="http://softwarecreation.org/2007/human-forces-and-software-creators/" title="people" id="xpxe">people</a>, <a href="http://softwarecreation.org/2007/software-development-is-the-flow-of-ideas-the-rest-is-secondary/" title="idea flow" id="z3i7">idea flow</a> and <a href="http://softwarecreation.org/2007/testosterone-irrational-choices-and-programmers/" title="psychology" id="djvu">psychology</a> factors &#8211; I considered software development only from perspective of the theory of complex systems and self-organization.</p>
<p><span style="font-weight: bold">Useful Resources:</span><br />
<a href="http://www.calresco.org/sos/sosfaq.htm" id="v9b_" title="Self-Organizing Systems FAQ">Self-Organizing Systems FAQ</a><br />
<a href="http://pespmc1.vub.ac.be/Papers/EOLSS-Self-Organiz.pdf" id="iq-e" title="The Science of Self-Organization and Adaptivity">The Science of Self-Organization and Adaptivity</a>, Francis Heylighen<br />
<strong style="font-weight: normal"> <a href="http://www.amazon.com/gp/product/0553343637/104-2883280-1296732?tag=softwcreatmys-20" title="Order Out of Chaos">Order Out of Chaos</a></strong>, Ilya Prigogine</p>
<!-- Social Buttons Shared Counts Generated by Digg Digg plugin v4.0.9, 
    Author : Yong Mook Kim
    Website : http://www.mkyong.com/blog/digg-digg-wordpress-plugin/ --><img src="http://softwarecreation.org/?ak_action=api_record_view&id=33&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://softwarecreation.org/2007/evolutionary-software-architecture-or-why-developers-are-not-janitors/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Do We Need Software Architects? 10 Reasons Why Not</title>
		<link>http://softwarecreation.org/2007/do-we-need-software-architects-10-reasons-why-not/</link>
		<comments>http://softwarecreation.org/2007/do-we-need-software-architects-10-reasons-why-not/#comments</comments>
		<pubDate>Thu, 30 Aug 2007 04:45:22 +0000</pubDate>
		<dc:creator>Andriy Solovey</dc:creator>
				<category><![CDATA[Design]]></category>
		<category><![CDATA[Process]]></category>
		<category><![CDATA[System]]></category>
		<category><![CDATA[Teams]]></category>

		<guid isPermaLink="false">http://softwarecreation.org/2007/do-we-need-software-architects-10-reasons-why-not/</guid>
		<description><![CDATA[Share
Recently I was reviewing requirements for Microsoft Architect Certification and had found description for architect roles. After reading I had a question: do we need this kind of architects in a software team? Can they really help with building successful software?
The summary of architect responsibilities (as per Microsoft):

     Enterprise architects: set [...]]]></description>
			<content:encoded><![CDATA[<div class='dd_post_share'><div class='dd_buttons'><div class='dd_button'><iframe src='http://api.tweetmeme.com/button.js?url=http://softwarecreation.org/2007/do-we-need-software-architects-10-reasons-why-not/&source=AndriySolovey&service=&service_api=&style=compact' height='20' width='90' frameborder='0' scrolling='no'></iframe></div><div class='dd_button'><a name='fb_share' type='button_count' share_url='http://softwarecreation.org/2007/do-we-need-software-architects-10-reasons-why-not/' href='http://www.facebook.com/sharer.php'>Share</a><script src='http://static.ak.fbcdn.net/connect.php/js/FB.Share' type='text/javascript'></script></div><div class='dd_button'><script src='http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://softwarecreation.org/2007/do-we-need-software-architects-10-reasons-why-not/'></script></div><div class='dd_button'><a title='Post on Google Buzz' class='google-buzz-button' href='http://www.google.com/buzz/post' data-button-style='small-count' data-url='http://softwarecreation.org/2007/do-we-need-software-architects-10-reasons-why-not/'></a><script type='text/javascript' src='http://www.google.com/buzz/api/button.js'></script></div><div class='dd_button'><iframe src='http://widgets.dzone.com/links/widgets/zoneit.html?url=http://softwarecreation.org/2007/do-we-need-software-architects-10-reasons-why-not/&amp;title=+Do+We+Need+Software+Architects%3F+10+Reasons+Why+Not&amp;t=2' height='18' width='120' frameborder='0' scrolling='no'></iframe></div></div></div><div style='clear:both'></div><p><img src="http://softwarecreation.org/images/2007/superman.jpg" /></p>
<p>Recently I was reviewing requirements for <a href="http://www.microsoft.com/learning/mcp/architect/default.mspx" title="Microsoft Architect Certification">Microsoft Architect Certification</a> and had found description for <a href="http://www.microsoft.com/learning/mcp/architect/specialties/default.mspx" title="architect roles">architect roles</a>. After reading I had a question: do we need this kind of architects in a software team? Can they really help with building successful software?</p>
<p>The summary of architect responsibilities (as per Microsoft):</p>
<ul>
<li>     <span style="font-weight: bold">Enterprise architects:</span> set the overall vision and framework for the IT environment from a strategic business perspective.</li>
<li>     <span style="font-weight: bold">Solutions architects</span>: design the solution to take advantage of the existing assets, integrate them into the existing environment, follow the enterprise architecture, and solve the business problems of the business owner or unit.</li>
<li>     <span style="font-weight: bold">Infrastructure architects</span>: responsible for creating an architecture that meets the business and service level agreement requirements of the business owners and supports the applications and solutions that are required to operate their day-to-day businesses.</li>
</ul>
<p>The bottom line is that company hires expensive and canny software architects before start of the project. They talk with the business, come up with solutions and make bright key decisions about architecture. <span style="font-weight: bold">But they don&#8217;t program</span>. During the course of the project they ensure that developers don&#8217;t spoil this great architecture.<br />
<span style="font-weight: bold"></span></p>
<p>Now business owners can hire not so bright programmers, who should just follow directives and implement this great architecture. There is even correspondence with <a href="http://softwarecreation.org/2007/programmers-are-lazy-capricious-pseudo-intellectuals-really/" title="theories">theories</a> of some management consultants that programmers are just house painters.</p>
<p>Completely irrelevant questions: Can you trust advise of your friend about Paris, if he saw the city only on TV? Can you trust battle plans if battle didn&#8217;t begin and your commander knows little about enemy? How many chess moves ahead can you predict with high certainty before start of the game?</p>
<p>I don&#8217;t reject a need in architecture, but I don&#8217;t agree <span style="font-weight: bold">who</span>, <span style="font-weight: bold">when </span>and <span style="font-weight: bold">how </span>should make architecture decisions in a software project.</p>
<p><span id="more-32"></span></p>
<h3>Top 10 reasons why you don&#8217;t need Software Architect</h3>
<p>The Architect (dedicated non-programming technical decision maker and problem solver for business):</p>
<ol>
<li>     Has outdated programming knowledge and experience, loss of touch with modern development approaches and practices.</li>
<li>     Don&#8217;t program and don&#8217;t know much about evolving system internals, but makes key technical decisions. Often has completely irrelevant and unreal picture what is happening with the system.</li>
<li>     Tends to complex, premature and generic solutions when the system is still in infancy and nothing is clear. Applies latest modern buzzword technologies as SOA, MDA, SaaS, Software Factories, etc. which look so beautiful in technical magazines, conferences and CV, but cause unnecessary headache for developers.</li>
<li>     Plays role of the middleman introducing complexity in coordination and project responsibilities. Represents software team in interactions with business customers reducing communication value for the rest of the team and <a href="http://softwarecreation.org/2007/software-development-is-the-flow-of-ideas-the-rest-is-secondary/" title="impacting idea flow">impacting idea flow</a>.</li>
<li>     Reduces quality of decisions, which become limited to one perspective; decision making starts lacking diversity, independence and decentralization, which are essential attributes of <a href="http://softwarecreation.org/2007/review-the-wisdom-of-crowds-making-the-best-decisions/" id="mxv." title="collective intelligence">collective intelligence</a>.</li>
<li>     Creates tension with developers who experience mismatch between grand design and reality. Often continues pushing design decisions until the system becomes overly complex, difficult to change and becomes completely unusable.</li>
<li>     Secures job and justifies high salary &#8211; becomes authoritative center for solving business problems without much input from the team.</li>
<li>     Causes loss of sense of ownership, motivation and accountability in developers by detaching them from the key architecture decisions.</li>
<li>     Concentrates project knowledge and the big picture in one head, limiting (and sometimes preventing) complete understanding for others.</li>
<li>     Contributes to creation of specialized IT verticals that <a href="http://softwarecreation.org/2007/it-business-gap-widens-is-this-a-problem/" id="jx_6" title="hurt relations">hurt relations</a> with the business.</li>
</ol>
<p>I&#8217;m sure that some architects bring strong technical leadership, excellent solutions and overall project success. However, the architect role itself, as described by Microsoft and employed by other companies, doesn&#8217;t encourage productive development and effective solutions.</p>
<h3> What is effective architecture? Who is effective architect?</h3>
<p><a href="http://www.laputan.org/metamorphosis/metamorphosis.html" id="hdid" title="Emerging">Emerging</a> and <a href="http://martinfowler.com/articles/designDead.html" id="d5sw" title="evolutionary">evolutionary</a> architecture is a core for a successful agile (and not only) software system, emerging from the implementation of business needs, learning from working code, problems and interactions with people, other systems and operational environment.</p>
<p>Effective architecture:</p>
<ol>
<li>     Provides stable foundation and integrity for the growing software system, enabling desired system qualities for the business solutions.</li>
<li>     Ensures seamless and consistent integration, well defined interfaces and interaction between subsystems, external systems and operational environment.</li>
<li>     Supports emerging abstractions, key system elements and frameworks for conceptual integrity, efficiency and reuse.</li>
</ol>
<p>Effective architect:</p>
<ol>
<li>     Guards a system against failure, sensing worrying changes in the project dynamic, system code and business requests.</li>
<li>     Keeps the <a href="http://en.wikipedia.org/wiki/Vitruvius" id="dg5h" title="trinity of system qualities">trinity of system qualities</a> (known from time of Roman empire) in a balance and prevent degradation and entropy:
<ul>
<li>       <span style="font-weight: bold">Firmitas </span>(Strength) &#8211; the system is reliable, secure, has good performance and easy to support</li>
<li>       <span style="font-weight: bold">Utilitas </span>(Utility) &#8211; the system is usable, meets business business needs and add business value every day instead of drifting into technology trenches</li>
<li>       <span style="font-weight: bold">Venustas </span>(Beauty) &#8211; code and system structure are clean, easy to understand, minimal</li>
</ul>
</li>
<li>     Encourages constant improving of the code design, enhancing system abstractions and structure, removing duplication, defining boundaries and interfaces of the subsystems.</li>
<li>     Keeps solutions as simple as possible, maintains intellectual control over system and avoids over-engineering.</li>
<li>     Most important &#8211; grows and coaches other developers to become architects</li>
</ol>
<p>If your company can afford dedicated non-programming technical person, hire an expert for complex technical areas, a <a href="http://softwarecreation.org/2007/what-is-the-best-leader-for-the-software-team/" id="pydp" title="coach">coach</a> to share best practices and experience or a technical supporter to coordinate with different external groups and help to resolve problems and make them all part of the team.</p>
<p><span style="font-weight: bold">But don&#8217;t take technical decisions and concern about architecture from the development team.</span></p>
<p>The ultimate solution &#8211; every developer covers these architect responsibilities. Hire few experienced, motivated and capable developers and start project with them. Developers will constantly evolve the system based on real needs and shape effective architecture. You can trust that system will be healthy, meet business needs and bring success. Often only few important architecture decisions should be made before start of the project &#8211; trust them to the developers, who will implement the system.</p>
<p>So, here is the answer regarding who, when and how should make architecture decisions:</p>
<p><span style="font-weight: bold">Who</span> &#8211; every developer timely makes architecture decisions and constantly improves evolving architecture<br />
<span style="font-weight: bold">When</span> &#8211; mostly after start of implementation, when system becomes more complex and need design improvements to maintain system qualities, intellectual control and conceptual integrity.<br />
<span style="font-weight: bold">How</span> &#8211; preventing degradation and entropy by making design changes and refactoring; learning from the project dynamic, working code and business requests and adjusting a way how the development team works.</p>
<p>Do you still think that software projects need The Architect?</p>
<p><strong>Useful resources:</strong></p>
<p><a href="http://www.microsoft.com/learning/mcp/architect/default.mspx" title="Microsoft Architect Certification">Microsoft Architect Certification</a></p>
<p><a href="http://martinfowler.com/articles/designDead.html" title="Is Design Dead?">Is Design Dead?</a>, Martin Fowler</p>
<p><a href="http://www.laputan.org/mud/" title="Big Ball of Mud">Big Ball of Mud</a>, Brian Foote and Joseph Yoder</p>
<!-- Social Buttons Shared Counts Generated by Digg Digg plugin v4.0.9, 
    Author : Yong Mook Kim
    Website : http://www.mkyong.com/blog/digg-digg-wordpress-plugin/ --><img src="http://softwarecreation.org/?ak_action=api_record_view&id=32&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://softwarecreation.org/2007/do-we-need-software-architects-10-reasons-why-not/feed/</wfw:commentRss>
		<slash:comments>25</slash:comments>
		</item>
	</channel>
</rss>
