<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://devlicio.us/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Christopher Bennage : Opinion, ALT.NET</title><link>http://devlicio.us/blogs/christopher_bennage/archive/tags/Opinion/ALT.NET/default.aspx</link><description>Tags: Opinion, ALT.NET</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP1 (Build: 31106.3070)</generator><item><title>Visions of Software Development or Can’t We Just All Get Along?</title><link>http://devlicio.us/blogs/christopher_bennage/archive/2010/01/12/visions-of-software-development.aspx</link><pubDate>Tue, 12 Jan 2010 11:38:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:54958</guid><dc:creator>Christopher Bennage</dc:creator><slash:comments>7</slash:comments><description>&lt;p&gt;I’m currently reading Thomas Sowell’s &lt;a href="http://www.amazon.com/gp/product/0465002056?ie=UTF8&amp;amp;tag=bluspiconinc-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=0465002056"&gt;A Conflict of Visions: Ideological Origins of Political Struggles&lt;/a&gt;&lt;img style="margin:0px;" border="0" alt="" src="http://www.assoc-amazon.com/e/ir?t=bluspiconinc-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=0465002056" width="1" height="1" /&gt;. As the title suggests, it deals with certain fundamental differences in the way we see the world and how that affects our political views. Don’t worry, I’m not going to delve into politics in the post. However, I was struck by how applicable the ‘visions’ in the book are to the competing (and conflicting) views about how we should write software.&lt;/p&gt;  &lt;p&gt;Here’s a simplified sketch of the two fundamental visions in the book. (Note that I’m not attempting to make a judgment call here on which vision is correct or better. Though admittedly, I have my bias. Likewise, I’m necessarily keeping it simplified.).&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Complex problems are best addressed by:      &lt;br /&gt;[a] systemic evolution or [b] clear and articulated reason &lt;/li&gt;    &lt;li&gt;When a complex problem is addressed the result will most likely be:      &lt;br /&gt;[a] a set of prudent trade-offs or [b] a solution &lt;/li&gt;    &lt;li&gt;Better results are produced when governance is provided by      &lt;br /&gt;[a] role and ritual or [b] well-educated individuals &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;This is just a few characteristics indentified in the book. We have a tendency to favor either the &lt;strong&gt;A&lt;/strong&gt; answers or the &lt;strong&gt;B&lt;/strong&gt; ones.&lt;/p&gt;  &lt;p&gt;Let me unpack this now in terms of software development. I think that the philosophy of agile/software craftsmanship/etc has generally preferred the A answers. While more traditional software development has generally preferred the B answers.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Many agile practices (such as TDD) build up software through systemic evolution. (Tim Barcz touched upon &lt;a title="Irreducible Complexity and Evolutionary Design in Software" href="http://www.timbarcz.com/blog/IrreducibleComplexityAndEvolutionaryDesign.aspx"&gt;this idea&lt;/a&gt; some time ago). Evolution is at the heart of iterative design. In opposition to this is a heavy initial design phase (or Big Design Up Front). In BDUF, the problem is analyzed and a clear, detailed path is laid out.&lt;/li&gt;    &lt;li&gt;I think the second point follows implicitly from the first point. BDUF is a ‘solution’, whereas iterative development is inherently about trade-offs. By the term ‘solution’ I am implying that on such-and-such a date, the software will be delivered and the problem will be solved. The value is delayed, but it is complete. In an iterative project the goal is to deliver immediate, but only partial value. It acknowledges that some value is always omitted and that the software might never be complete.&lt;/li&gt;    &lt;li&gt;The third point is one of the more divisive ones. I believe that agile practices focus a lot on ritual. TDD is a ritual. (I believe there was a Hanselman interview with Robert Martin that discussed this point). Kaban, Scrum, and other similar practices are ritualistic. These rituals are the soil where the systemic evolution grows. On the opposing side, development teams are led by architects. That is, by well-educated and intelligent individuals who have a greater understanding of what needs to be done.&lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;My Bias&lt;/h3&gt;  &lt;p&gt;It is always important to admit your bias. I tend to favor the &lt;strong&gt;A&lt;/strong&gt; answers above, though not always. I have been in circumstances where that approach broke down.&lt;/p&gt;  &lt;p&gt;Regardless, I highly recommend the book as it has given me a lot of insight into my own views and those of others.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=54958" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/Reflection/default.aspx">Reflection</category><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/Agile/default.aspx">Agile</category><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/ALT.NET/default.aspx">ALT.NET</category><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/Opinion/default.aspx">Opinion</category></item><item><title>Solving Problems with TDD</title><link>http://devlicio.us/blogs/christopher_bennage/archive/2008/11/06/solving-problems-with-tdd.aspx</link><pubDate>Thu, 06 Nov 2008 20:03:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:42921</guid><dc:creator>Christopher Bennage</dc:creator><slash:comments>7</slash:comments><description>&lt;p&gt;I&amp;#39;m giving a talk on TDD at our local UG tonight, and under the influence of some recent posts here on devlicio.us, I just finished reworking my presentation. This post is an outline for the first half of my presentation.&lt;/p&gt; &lt;h3&gt;The Problems&lt;/h3&gt; &lt;p&gt;Code has entropy. That is over time it deteriorates. At least, that&amp;#39;s the metaphor we developers like to use. What is really means is that the code becomes harder to maintain and extend as it is maintained and extended over time. Did you follow that? Our typical approach to maintaining and extending code causes the code to become fragile and rigid and thus harder to maintain and extend in the future.&lt;/p&gt; &lt;p&gt;There are three common difficulties that arise, maybe more, but I&amp;#39;m focusing on three:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Unchangeable Code&lt;/li&gt; &lt;li&gt;Unintelligible Code&lt;/li&gt; &lt;li&gt;Unnecessary Code&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;A portion of code becomes unchangeable when its deeply entwined and entangled with other portions of code that have different responsibilities. You can&amp;#39;t change method X because we really don&amp;#39;t know what that will do to Y and Z.&lt;/p&gt; &lt;p&gt;Code can become unintelligible for lots of reasons: abbreviated names, circuitous logic, enormous methods, confusion of responsibilities, use of php☺, etc.&lt;/p&gt; &lt;p&gt;Finally, unnecessary code is code that is not used by the system. It can be vestigial, or as often happens, it can be the result of feature anticipation. &lt;em&gt;We thought this was going to be needed in the app, so...&lt;/em&gt;&lt;/p&gt; &lt;h3&gt;The Solutions&lt;/h3&gt; &lt;p&gt;There are some generally accepted solutions to these three problems.&lt;/p&gt; &lt;p&gt;In the case of unchangeable code, we can apply such patterns as &lt;a href="http://en.wikipedia.org/wiki/Separation_of_concerns" target="_blank"&gt;Separation of Concerns&lt;/a&gt; (SoC) and the &lt;a href="http://en.wikipedia.org/wiki/Single_responsibility_principle" target="_blank"&gt;Single Responsibility Principle&lt;/a&gt; (SRP). For addressing unintelligible code, we have a number of techniques such as &lt;em&gt;thoughtful&lt;/em&gt; comments, explicit naming, SRP again, etc. Finally, for unnecessary code we have the old axiom of &lt;a href="http://en.wikipedia.org/wiki/YAGNI" target="_blank"&gt;You Ain&amp;#39;t Gonna Need It.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Okay, so we know how to solve the problems. Or least, we know how to mediate them. So what? What does that have to do with TDD?&lt;/p&gt; &lt;p&gt;My proposition is this:&lt;strong&gt; solutions are without value unless they are applied&lt;/strong&gt;.&lt;/p&gt; &lt;p&gt;Additionally, when a problem occurs over time, the solution must be applied over time.&lt;/p&gt; &lt;h3&gt;The Analogy&lt;/h3&gt; &lt;p&gt;I just started going to the gym. It&amp;#39;s been about a decade since I did that, but I&amp;#39;m back. For the past several years however, I have been preaching to certain family members the value of exercise and healthy diet. I knew the benefits: stress reduction, longevity, improved sleeping, and just plain feeling better. However, I wasn&amp;#39;t really doing either.&lt;/p&gt; &lt;p&gt;I had the problem and I believed in the solution and, in fact, I made attempts to employ the solution. Ultimately, I was unsuccessful. That is, until I committed to go to the gym three days week at a set time and with a workout buddy.&lt;/p&gt; &lt;p&gt;My point is this, we are human beings and despite being smart we frequently revert to doing &amp;quot;the easiest thing&amp;quot;. Therefore, we ought to set up some sort of framework of methodology or discipline where the easiest thing is actually what we &lt;em&gt;want&lt;/em&gt; to do.&lt;/p&gt; &lt;p&gt;Additionally, I have to &lt;em&gt;keep on going&lt;/em&gt; to gym. For as long as I want to be fit, I will need to exercise. In the same way, for as long as I want my code to fit I will need to apply good principles.&lt;/p&gt; &lt;h3&gt;TDD as a Discipline&lt;/h3&gt; &lt;p&gt;I will argue that TDD is a discipline that enables the application of the solutions outlined above. Perhaps you apply those solution naturally. Perhaps you can benchmark 200lbs because of your genetic disposition. Bully for you. Go ahead and skip the rest.&lt;/p&gt; &lt;p&gt;Let&amp;#39;s examine a few essentials of TDD and see if they really address the problems we outlined.&lt;/p&gt; &lt;h4&gt;Test First&lt;/h4&gt; &lt;p&gt;I&amp;#39;m an advocate of automated testing in general. However, I do think that writing your tests first yields additional value. Primarily, it helps you &lt;em&gt;discover your ideal API&lt;/em&gt;. In other words, you can design your API up front such that it is more intuitive. More intuitive means easier to understand. &lt;/p&gt; &lt;p&gt;Secondly, testing first helps you identify dependencies early. You quickly discover that class X will need a Y and so you are forced to create seams in the application at the onset. This encourages SoC and SRP.&lt;/p&gt; &lt;h4&gt;Testing Units&lt;/h4&gt; &lt;p&gt;It took me a long time to understand the &amp;quot;unit&amp;quot; part of unit testing. The idea is that you decompose your problem into units, and deal with the problem one unit at a time. You could call this &amp;quot;test just one thing&amp;quot;. Okay, well what is &amp;quot;one thing&amp;quot;? That is hard to tell and comes with experience. Nevertheless, &lt;em&gt;the practice&lt;/em&gt; of trying to decompose a problem and identifying units leads you back to SoC and SRP again.&lt;/p&gt; &lt;h4&gt;Just Enough Code&lt;/h4&gt; &lt;p&gt;Another tenet of TDD is to &lt;em&gt;write only enough code to pass the test&lt;/em&gt;. Our natural instinct is to anticipate. It is part of what we are as developer, and it is not a bad thing. However, like many strengths, it can become a weakness. By constraining ourselves to a single problem at a time we will end up with less code. It also forces us to be conscious about our anticipation and to ask if a given scenario is &lt;em&gt;really&lt;/em&gt; necessary.&lt;/p&gt; &lt;h3&gt;Conclusion&lt;/h3&gt; &lt;p&gt;I know that there is much contention over the actual value of TDD as a practice, and I am not going to force it on anyone (unless I hire you and now you are warned). However, I have found it to be a useful discipline for helping me to overcome common problems and because of that I encourage it&amp;#39;s use.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=42921" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/Design+Patterns/default.aspx">Design Patterns</category><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/Agile/default.aspx">Agile</category><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/Software+Architecture/default.aspx">Software Architecture</category><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/TDD/default.aspx">TDD</category><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/ALT.NET/default.aspx">ALT.NET</category><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/Best+Practices/default.aspx">Best Practices</category><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/Opinion/default.aspx">Opinion</category></item></channel></rss>