Just A Summary : Tag practiceofprogramming, everything about practiceofprogramming http://www.bofh.org.uk/articles/tag/practiceofprogramming.rss en-us 40 Piers Cawley Practices Punditry Just a thought <p>There&#8217;s a refactoring principle that states that, when you start doing the same thing for the third time, you should refactor to remove the duplication.</p> <p>I&#8217;m starting to wonder if there&#8217;s a Smalltalk principle which states that, when you start doing the same thing the second time, you should search the image for the obviously named method (or use the method finder to find some candidate by feeding it some inputs and an expected answer), because the odds are good that it&#8217;s only the second time for you &#8211; it might be the millionth time for the image you&#8217;re working in.</p> Thu, 25 Sep 2008 23:46:00 -0500 urn:uuid:3acc824f-f1f6-4328-bf97-ab310523115a pdcawley@bofh.org.uk (Piers Cawley) http://www.bofh.org.uk/articles/2008/09/25/just-a-thought#comments The Practice of Programming practiceofprogramming smalltalk refactoring http://www.bofh.org.uk/articles/2008/09/25/just-a-thought Get sophisticated <p>Ruby&#8217;s primitives (Strings, Hashes, Arrays, Numbers &#8211; anything that has a literal syntax) are fine things. But that doesn&#8217;t mean you should use them everywhere. You&#8217;re often much better off wrapping them up in your own Value Objects.</p> <p>Something I was working on at Railscamp this weekend threw up a great example of why it makes sense to replace primitives with more specific objects as soon as possible. <a href="http://tommorris.org/">Tom Morris</a> asked me to take a look at <a href="http://github.com/tommorris/rena">Rena</a>, an <span class="caps">RDF</span>/Semantic Web thingy.</p> <p>The <span class="caps">RDF</span> spec describes two types of literals: a plain literal, which is a string with an optional language attribute and a typed literal, which is a string and an encoding (so the string might represent an integer, float, or anything else that your schema feels like expressing).</p> <p>These literals can be output in one of (at least) two formats. We&#8217;ll start by looking at <code>Literal#to_trix</code> and see where that takes us:</p> <pre name="code" class="ruby"><code> def to_trix if @lang != nil &#38;&#38; @lang != "" out = "&lt;plainLiteral xml:lang=\"" + @lang + "\"&gt;" else out = "&lt;plainLiteral&gt;" end out += @contents out += "&lt;/plainLiteral&gt;" return out end </code></pre> <p>If we look over at <code>TypedLiteral#to_trix</code> we see a much more straightforward implementation:</p> <pre name="code" class="ruby"><code> def to_trix "&lt;typedLiteral datatype=\"#{@encoding}\"&gt;#{@contents}&lt;/typedLiteral&gt;" end </code></pre> <p>How do we eliminate that ugly conditional at the beginning of <code>Literal#to_trix</code>, and analogous conditionals in <code>Literal#to_n3</code> and <code>TypedLiteral#to_n3</code>?</p> <p>My first thought was that I wanted to be able to write something like:</p> <pre name="code" class="ruby"><code> def to_trix "&lt;plainLiteral#{@lang.to_trix}&gt;#{@contents}&lt;/plainLiteral&gt;" end </code></pre> <p>But I didn&#8217;t want every string in the world suddenly acquiring a <code>to_trix</code> method. So, the solution was to intoduce a <code>Literal::Language</code> class and coerce our language into it, so <code>Literal#initialize</code> became:</p> <pre name="code" class="ruby"><code> def initialize(contents, lang = nil) @contents = contents @lang = Language.coerce(lang) end </code></pre> <p>And Language would look something like:</p> <pre name="code" class="ruby"><code> def self.coerce(lang) if lang.is_a?(self) return lang end new(lang.to_s.downcase) end def initialize(lang) @value = lang end def to_trix if @value == '' '' else " xml:lang=\"#{@value}\"" end end </code></pre> <p>That ugly conditional&#8217;s still there though, so we introduced the Null Object pattern, and things started to look a good deal cleaner:</p> <pre name="code" class="ruby"><code> class Language class Null include Singleton def to_trix '' end end def self.coerce(lang) case lang when self return lang when nil, '' return Null.instance else return new(lang.to_s.downcase) end end ... def to_trix " xml:lang=\"#{@value}\"" end end </code></pre> <p>At this point, we&#8217;re still just pushing code around. If anything, we&#8217;ve got more lines of code now than when we started, but we&#8217;re starting to move behaviour nearer to the data it relates to, and our objects are starting to look like objects rather than data structures. So, we press on and make a <code>TypedLiteral::Encoding</code> class and, at this point things start to look interesting. TypedLiteral is starting to look almost exactly the same as Literal, but with an Encoding rather than a language.</p> <p>That strange leading space in <code>Language#to_trix</code> is starting bug me. Let&#8217;s rewrite like so:</p> <pre name="code" class="ruby"><code> class Literal class Language def format_as_trix(literal) "&lt;plainLiteral xml:lang=\"#{@value}\"&gt;#{literal}&lt;/plainLiteral&gt;" end class Null def format_as_trix(literal) "&lt;plainLiteral&gt;#{literal}&lt;/plainLiteral&gt;" end end end def to_trix @lang.format_as_trix(@contents) end end </code></pre> <p>If we make analogous change to <code>TypedLiteral</code> and <code>TypedLiteral::Encoding</code> it&#8217;s obvious that TypedLiteral and Literal were essentially the same class. Renaming <code>@lang</code> and <code>@encoding</code> to <code>@language_or_encoding</code> makes this blindingly obvious, so we&#8217;ll remove all of TypedLiteral&#8217;s methods except initialize. All that remains is to introduce <code>Literal.untyped</code> and <code>Literal.typed</code> factory methods to Literal, and make <code>Literal.new</code> into a private method and we can remove TypedLiteral in its entireity. So we change the specs to reflect the new <span class="caps">API</span> (wrong way round I know). Now we have a chunk of shorter, clearer code that will hopefully be easier to extend to cope with outputting literals in other formats.</p> <h3>Retrospective</h3> <p>I realise that patterns aren&#8217;t the goal of development, but by the end of the process we have a Strategy (Language/Encoding), a couple of Factory Methods (<code>Literal.typed</code>, <code>Literal.untyped</code>) and a couple of factoryish methods (<code>Language.coerce</code>, <code>Encoding.coerce</code>).</p> <p>The most important aspect of the change was the introduction of the two new value object classes. Once they were introduced, they became the obvious places in which to put the varying behaviour and eliminate the repeatition of conditional code from the <code>to_*</code> methods. If there were to be a third output style, I would look at introducing classes like <code>N3Stream</code>, <code>TrixStream</code> and <code>WhateverStream</code> and have a scheme like:</p> <pre name="code" class="ruby"><code> def to_n3 print_on( N3Stream.new ) end def print_on(stream) language_or_encoding.print_on(stream, value) end </code></pre> <p>but that&#8217;s almost certainly over complicating things right now.</p> <p>The other thing I like about this kind of refactoring is that it drives the code towards methods and classes which obey the single responsibility principle and, at the end of the process, not only do we have fewer lines of code in total, but the individual methods involved are <em>all</em> substantially shorter and closer to the left hand margin.</p> <p>I really should start doing this kind of thing more in my Rails practice &#8211; I keep being put off by the fact that the <code>composed_of</code> helper is so annoyingly not quite right and, rather than submitting a patch or making a plugin I go &#8220;Ah well&#8230; I can live with a string for a bit longer&#8230;&#8221; and I <em>know</em>. From hard won experience at that, that it&#8217;s going to come and bite me. It&#8217;s already bitten Rails recently when Ruby got a new <code>String#to_chars</code> which doesn&#8217;t work like the ActiveSupport version.</p> <h3>Notes</h3> <p>If you want to see the gory details of how the change got made, Tom has merged this weekends changes into the github repository. It didn&#8217;t happen in quite the order I&#8217;ve described it in this post, but neither is this post a complete fabrication.</p> <h3>Changes</h3> <p>Corrected a stupid typo in the first block of code. Ugly condition is actually <code>if @lang != nil &#38;&#38; @lang != ''</code></p> Wed, 20 Aug 2008 11:25:00 -0500 urn:uuid:109c717f-5ad5-469e-b3b9-f19b40e8648e pdcawley@bofh.org.uk (Piers Cawley) http://www.bofh.org.uk/articles/2008/08/20/get-sophisticated#comments Ruby ruby practiceofprogramming patterns railscamp08 http://www.bofh.org.uk/articles/2008/08/20/get-sophisticated Usability testing (throws) rocks <p>Usability testing is wonderful. But wow, its humiliating.</p> <p>I&#8217;ve spent the last few weeks working on the <a href="http://www.amazingtunes.com">Amazingtunes</a> in page player. Amazingtunes is a music site, so we need to play music. However, we don&#8217;t like the way that most music sites work; either the music stops as you go from one page to another, or the player is a huge Flash app running in its own window. There has to be a better way. There needs to be a popup window if you want to eliminate stop/start behaviour, but there&#8217;s surely no reason not to keep the controls on the main page.</p> <p>So, we set about writing somthing that did just that. We settled on using Jeroen Wijering&#8217;s excellent <a href="http://www.jeroenwijering.com/?item=JW_FLV_Player">flvPlayer</a>, which handles the media formats we need and has good Javascript control and communications. This sits in the child window and we use Javascript cross-window communication to have a player controller in the main window that looks something like:</p> <div class="thumbnail"><a href="http://skitch.com/pdcawley/xy5m/piers-cawley-on-amazingtunes.com"><img src="http://img.skitch.com/20080703-58ianuwrptmeysscfkse3bm9i.preview.jpg" alt="Piers Cawley on amazingtunes.com" /></a><br /><span style="font-family: Lucida Grande, Trebuchet, sans-serif, Helvetica, Arial; font-size: 10px; color: #808080">Uploaded with <a href="http://plasq.com/">plasq</a>&#8217;s <a href="http://skitch.com">Skitch</a>!</span></div> <p>This is all done in <span class="caps">HTML</span> and and Javascript, the progress bar does the Safari trick of running behind the tune data links, the buttons do their <span class="caps">AJAX</span> magic and the whole thing is rather slick, though I say so myself.</p> <p>At least, we thought it was slick until we pointed the <a href="http://www.usertesting.com/">usertesting.com</a> legions at it. Without exception, they ignore the in page player, foreground the popup and use the teeny weeny controls on the flash player. Originally, the popup window didn&#8217;t even display any transport controls, it just had a picture of some speakers and some text asking the user not to close it because it was playing the tunes. We added transport controls as a stopgap while we made the in page player work properly.</p> <p>I sound like I&#8217;m whinging don&#8217;t I? It&#8217;s certainly a blow to the ego to see something we spent so much time and attention on being ignored by our sample users. On at least one occasion, while watching the screencasts I found myself boggling at the things the users did, and if I didn&#8217;t shout &#8220;Just play some bloody music!&#8221; at the screen, then I came worryingly close.</p> <p>It would be easy to retreat into a state of denial: &#8220;They&#8217;re not our target users! They&#8217;re stupid! They&#8217;re American! If they would only magically intuit the way we think they should use the site!&#8221;. And maybe it would be comforting to do so, for a while. The right thing to do is to suck it up &#8211; take away from those videos the sure and certain knowledge that bits of the site don&#8217;t work and do something about it.</p> <p>We may dislike the &#8216;popup window for transport controls&#8217; model of controlling music playback, but users are cool with it. And it&#8217;s not as if the work we did on making the in page player work is going to be wasted &#8211; widget is straightforwardly event driven so it&#8217;ll work just as well in the popup window, and the communication protocol will be much simpler. Having the player in its own window means we&#8217;ll be able to extend its interface in ways that would be hard when the player had to share window space with the rest of the page. In the end, it&#8217;s all good.</p> <p>But&#8230; damn that in page player was sweet. I learned Javascript as I wrote it (mostly by pretending it was Perl with odd syntas) and I&#8217;m bloody proud of it. I&#8217;ll happily replace it with the next iteration (which I&#8217;m already working on), but it&#8217;ll be with a pang of remorse all the same.</p> Thu, 03 Jul 2008 04:55:00 -0500 urn:uuid:c3e1ff9d-3a90-4f3d-8cbc-706f8fb61b85 pdcawley@bofh.org.uk (Piers Cawley) http://www.bofh.org.uk/articles/2008/07/03/usability-testing-throws-rocks#comments amazingtunes practiceofprogramming usabilitytesting javascript http://www.bofh.org.uk/articles/2008/07/03/usability-testing-throws-rocks Listen to the Voice! <p>You know that voice at the back of your head that says things like &#8220;That&#8217;s not really a data structure, that&#8217;s an object that is!&#8221;?</p> <p>You should listen to it.</p> <p>I&#8217;ve been battling away with having a million and one things monkeying with a result set that consists of an array of arrays, when really it should have been a <code>ResultSet</code> which has a collection of <code>ResultSet::Row</code>s. Once I bit that bullet, I got to do things like add <code>ActiveRecord::Errors</code> to each row and generally start to bring a bunch of big guns to bear on a problem.</p> <p>So, having listened to the voice at last I&#8217;m going through and removing code with gay abandon. Sometimes I think removing code is one of the great joys of being a programmer &#8211; it&#8217;s the code&#8217;s way of telling you you got something right.</p> <p>So, today&#8217;s slogan is &#8220;Reify early and reify often&#8221;.</p> Tue, 13 Feb 2007 07:31:00 -0600 urn:uuid:6cc39c59-8718-43d2-a33b-6e2cb0c6c3b7 pdcawley@bofh.org.uk (Piers Cawley) http://www.bofh.org.uk/articles/2007/02/13/listen-to-the-voice#comments The Practice of Programming slogans practiceofprogramming voicesinmyhead http://www.bofh.org.uk/articles/2007/02/13/listen-to-the-voice Blessed are the toolmakers <p>My dad drives a vintage Fraser Nash. I say drives, but that&#8217;s only half the battle, a large part of his Nash time is spent fettling it. It&#8217;s an old car; bits wear out, break or drop off. And because it&#8217;s an old car, you can&#8217;t just nip round to Halfords and pic up a replacement; nor can you head down to the breaker&#8217;s yard and cannibalize something else. So he has a lathe and a milling machine and a bewildering collection of tools. When he needs a part, he will disappear into the machine shop and, after sufficient swearing and/or bleeding, he will emerge with a newly made part. For dad, it&#8217;s all part of the fun of running a vintage car. If he weren&#8217;t able to do the work, the Nash would have had to remain a pleasant pipedream.</p> <p>I don&#8217;t know my way around a machine shop, except in the vaguest and most theoretical way. The tools I&#8217;ve grown up knowing to use are programming languages, editors, fine manuals and the mental tools a grounding in mathematics brings.</p> <p>So, when I&#8217;m putting a new photography business together, and I realise that a couple of the supporting software tools that I had vaguely assumed &#8216;should exist&#8217; don&#8217;t <em>actually</em> exist, I know that it doesn&#8217;t matter. I may not know Cocoa programming yet, but I know programming, so I&#8217;m confident that, like dad in his machine shop, I&#8217;ll be able to knock something up that does the job.</p> <p>On reflection, I realised that this is probably a good thing. If I can set up and run the business with a combination of off the shelf software, then it&#8217;s trivial for potential competitors to reverse engineer the business and do the same (let&#8217;s assume here that the business is a success) and I&#8217;m left competing on margin in a service industry. No fun at all.</p> <p>Being able to make my own tools gives me a competitive edge.</p> <h3>Why aren&#8217;t there more tool makers?</h3> <p>Because I&#8217;m a programer, I know that if my working environment isn&#8217;t habitable, it&#8217;s possible to fix it. I carry that approach to working with other capable software &#8211; keep typing &#8216;teh&#8217; when I mean &#8216;the&#8217;? Add a macro, autocorrect rule, snippet or whatever you want to call it to the tool I&#8217;m using and wonder if it might be a good idea to implement some kind of central repository for such things so I don&#8217;t have to repeat myself with every new tool.</p> <p>The tools to do this sort of thing are there; they&#8217;ve never been more available, and in many cases they&#8217;re not hard to use, but surprisingly few people seem to be using them. Why is that? Why do people put up with annoying software when (often) the fix is only a couple of settings away? Why are programmers so rare?</p> <p>I wish I knew. Or maybe I don&#8217;t &#8211; as long as people don&#8217;t realise how easy it is to fix/make things, I&#8217;ve got an edge.</p> <h3>Taking control of your tools</h3> <p>If you let your tools shape you, then you&#8217;re going to be awfully uncomfortable. Make a commitment to at least capture your annoyances with the tools you use most frequently. Make a note of the problems and think about what you <em>wish</em> the software would do and blog about it. Here&#8217;s a couple of stories based on some of the things I need to be able to do for my business:</p> <blockquote> <h4>Auto Slideshows</h4> <p>As an onsite picture editor, I need to run a &#8216;smart&#8217; slideshow on a secondary display while I working on images on the primary display. The slideshow should be based on an Aperture album and should automatically pick up any changes in the underlying album.</p> </blockquote> <blockquote> <h4>Auto crediting</h4> <p>As an onsite picture editor, I need my slideshow to display a credit on any images in the slideshow that weren&#8217;t taken by me. If the Credit metadata doesn&#8217;t match &#8216;Piers Cawley&#8217; the string &#8220;by <whoever>&#8221; should be added as a &#8216;watermark&#8217; to the displayed image.</p> </blockquote> <p>If you&#8217;re a programmer yourself, you&#8217;ve just given yourself a nice list of projects to be working on when you have the time. If you&#8217;re not, then you&#8217;ve just written a useful set of requirements. Tag your post &#8216;lazyweb&#8217; and if you&#8217;re lucky someone might know how to do exactly what you want without having to write a line of code, or someone else might agree that it&#8217;s something that needs fixing and actually <em>fix</em> it. If neither of those two happen, well, at least you&#8217;ve vented your frustration, and that&#8217;s not a bad thing either.</p> Tue, 05 Dec 2006 11:07:00 -0600 urn:uuid:70d18dba-df5b-4bb3-98a0-6553f96eb7dc pdcawley@bofh.org.uk (Piers Cawley) http://www.bofh.org.uk/articles/2006/12/05/blessed-are-the-toolmakers#comments Musings The Practice of Programming Photography lazyweb practiceofprogramming toolmaking http://www.bofh.org.uk/articles/2006/12/05/blessed-are-the-toolmakers Another Two Cultures <p>So, I&#8217;m temping now, just another admin worker bee for the council. I can&#8217;t say that I&#8217;ve found my vocation, but it&#8217;s certainly an eye opener.</p> <p>All my adult life, I&#8217;ve seen a computer as an amazingly flexible servant. If it doesn&#8217;t yet do what I need then it&#8217;s possible to program it so that it does. That&#8217;s what computers are <em>for</em> after all.</p> <p>This seems to be rather a long way from the experience of the people I&#8217;m working with. For them the relationship is inverted. The servant becomes the master and they have to conform to its way of doing things. Flexibility disappears.</p> <p>On my first day I spent some time keying in data from feedback forms into a badly designed Access database. I was walked through the process which involved inputting data into the table view. This isn&#8217;t necessarily a bad way of doing things, but some columns were supposed to be set to one of five satisfaction levels, and those levels weren&#8217;t simply numbers, they were text: &#8220;Excellent&#8221;, &#8220;Good&#8221;, &#8220;Satisfactory&#8221;, &#8220;Poor&#8221; and &#8220;Don&#8217;t Know/Not Applicable&#8221;. Not fun to type in repeatedly.</p> <p>So I spent 10 minutes setting up a form complete with combo boxes and other appropriate devices to ensure that the data entered was valid, with the added bonus that data entry through the form was <em>way</em> faster. I estimate that it would have taken me at least half an hour to input the data through the table view, and I wouldn&#8217;t have a great deal of confidence about its validity. With the form, I had the data input within 10 minutes of finishing the form. Bear in mind that this is the first time I&#8217;ve ever used Access; it just seemed obvious that anything that called itself an end user database would be able to do what I needed.</p> <p>Before I started the job there were already 200 entries, all apparently input by hand. Nobody had taken the apparently simple step of adding a form to make life easier. (Someone had, but it was a terrible form with an insane tabbing order, and nobody seemed to know about it).</p> <p>It&#8217;s terribly easy for programmers to dismiss non-programmers as stupid, but they&#8217;re really not. There&#8217;s a schism between users and programmers that&#8217;s as fundamental as the divide between C.P. Snow&#8217;s <cite asin="0521457300">Two Cultures</cite></p> <p>I&#8217;ve written, indirectly, about this <a href="/articles/2003/08/01/the-fine-art-of-complexity-management">before</a>, but this is the first time I&#8217;ve seen the difference so plainly. Mainstream software like Microsoft Office becomes more and more programmable with every iteration and those features hardly ever get used by end users. And end users are the people who really could benefit from this stuff. They&#8217;re the people who know what they need the software to do. The divide tends to mean that programmers implement what&#8217;s easy for them rather than what&#8217;s Right. So users, unfamiliar with the power of programmability, end up feeling that a bad &#8216;solution&#8217; has been foisted on them.</p> <p>Picking another example, there&#8217;s a bookings system here. It&#8217;s terrible. Things that should easy to do in software end up being done by hand&#8212;one obvious example is when you use a canned query to find all of a client&#8217;s bookings, the list that gets returned isn&#8217;t in date order. If you book a room to someone the system doesn&#8217;t check that the room&#8217;s available, you have to check by hand first (but that&#8217;s a pain, because, as before, the list of bookings for a room aren&#8217;t in date order)... By any measure, the software these people are working with is terrible. It&#8217;s not as if it&#8217;d be hard to fix, simply tweaking a couple of queries would make things noticeably better.</p> <p>As far as I can tell, the people who use this system never met any of the people who wrote the code. Or maybe they never had a chance to play with what&#8217;s possible, so they don&#8217;t know that software doesn&#8217;t have to be this bad.</p> <h3>The Usual Sermon</h3> <p>As those of you who&#8217;ve been reading this blog for a while can probably guess, this is the bit where I point out that Agile methodologies win big in this situation. Development that gets a rough model into the hands of the users and then debugs its way to full functionality through a dialogue between users and developers will end up with a more habitable product.</p> <p>The real power of the conversational approach is the conversation itself. If I can get immediate clarification from the user; if my development practice means that I can say &#8220;I think I&#8217;ve got an idea that&#8217;ll make this easy for you, give me half and hour and have a demo for you&#8221;; if I can then deliver running code that shows what I mean, then that can only be a win.</p> <p>It might take a little more time (the Agile people will tell you it&#8217;s actually faster because you don&#8217;t waste time on unnecessary code and endless meetings and requirements gathering&#8212;I tend to believe them) but I&#8217;m prepared to bet that the resulting code will be a great deal more robust and useful. Not just that, but the users will have learned an important lesson about the flexibility of code, which just has to be a good thing. Even if users never learn to program themselves, the knowledge of exactly how flexible these tools are is empowering all by itself.</p> <p>I&#8217;m not sure I&#8217;d go so far as to recommend that every programmer out there goes and spends some time working in an office doing the daily admin grind, but if you do find yourself in that position, keep your eyes, ears and mind open. There&#8217;s a great deal of good stuff to learn&#8212;who knows, you might just come up with the next great product.</p> Fri, 02 Sep 2005 16:47:00 -0500 urn:uuid:f0e8995cab9f63e1e72c6089f8853b04 pdcawley@bofh.org.uk (Piers Cawley) http://www.bofh.org.uk/articles/2005/09/02/another-two-cultures#comments Musings The Practice of Programming practiceofprogramming agilemethods twocultures http://www.bofh.org.uk/articles/2005/09/02/another-two-cultures The Quality Without A Name <p>The Quality Without A Name is a phrase coined by Christopher Alexander in <cite asin="0195024028">The Timeless Way of Building</cite> to describe the feeling of satisfaction and contentment engendered by good building. He later went on to call it &#8216;life&#8217;, but a friend of mine described it as &#8216;The Tao of Building&#8217;, which seems rather appropriate too. <cite>The Timeless Way of Building</cite> is a fantastic, if somewhat overwritten book, introducing Alexander&#8217;s themes and ideas about how modern architects and builders can recapture the qualities inherent in great (usually old) buildings.</p> <p>Alexander later went on to crystallize his ideas about how to lay out cities, towns, neighbourhoods, houses, rooms, windows, etc in his massively influential book, <cite asin="0195019199">A Pattern Language</cite>, in which Alexander and his co-authors attempted to set down a &#8216;language&#8217; that would enable anyone to design and build somewhere that possessed the Quality Without a Name for themselves. Sadly, as they admit later, they failed in this attempt; efforts to use this pattern language by laymen resulted in interesting, but flawed buildings. Despite the failure (in Alexander&#8217;s terms) it&#8217;s a great book; the prose can be a little annoying at times, but the analysis is deep, and mind-changing. Here&#8217;s an extract from one of the patterns:</p> <blockquote> <p><b>208. Gradual Stiffening</b></p> </blockquote> <blockquote> <p><strong>The Fundamental philosophy behind the use of pattern languages in buildings is that buildings should be uniquely adapted to individual needs and sites; and that the plans of buildings should be rather loose and fluid, in order to accommodate these subtleties.</strong></p> </blockquote> <blockquote> <p>[An essay describing the problem more fully, and the reasoning behind the solution presented]</p> </blockquote> <blockquote> <p>Therefore:</p> </blockquote> <blockquote> <p><strong>Recognize that you are not assembling a building from components like an erector set, but that you are instead weaving a structure which starts out globally complete, but flimsy; then gradually making it stiffer buit still rather flimsy; and only finally making it completely stiff and strong. We believe that in our own time, the most natural version of this process is to put up a shell of sheet materials, and then to make it fully strong by filling it with compressive fill.</strong></p> </blockquote> <p>Look, Agile Building!</p> <p>Alexander and his co-writers have found a remarkably powerful way of managing complexity by isolating parts of the process of building in individual patterns, but neatly tying them into the greater whole by their use of introductory and closing paragraphs to explain the context in which a pattern is used. When I read it, I find I&#8217;m constantly flipping back and forth to look at these contextual patterns that support (or use) the pattern that I&#8217;m concentrating on. The book itself has the Quality Without a Name.</p> <p>It was only after I&#8217;d read <cite>The Timeless Way</cite> and <cite>A Pattern Language</cite> that I came across the idea of Design Patterns in programming (In fact, I was working as a contractor and had a copy of <cite>The Timeless Way</cite> on my desk when a coworker spotted it and made a remark along the lines of &#8220;Ah, going back to the source eh?&#8221;, which he then had to explain as I didn&#8217;t know what he was talking about.) when a friend lent me the Gang of Four&#8217;s <cite asin="0201633612">Design Patterns</cite>.</p> <p>I don&#8217;t really like <cite>Design Patterns</cite>. Too many of the patterns seem to be concerned with working around problems with the static nature of C++ and Java&#8212;not exactly useful if you&#8217;re used to a more dynamic OO language. Another, deeper failing, is the disjointed nature of the patterns presented; there&#8217;s no attempt to tie the patterns together in a coherent language and the whole thing feels like a mishmash of ideas waiting to be turned into a finished book.</p> <p>There is one software patterns book I&#8217;ve read that gets it though, that has The Quality Without A Name in the same way that <cite>A Pattern Language</cite> does. That book is <cite asin="013476904X">Smalltalk Best Practice Patterns</cite> by <a href="http://www.c2.com/cgi/wiki?KentBeck">Kent Beck</a>. If you don&#8217;t know Smalltalk, don&#8217;t be put off by that title; a very sizable fraction of the book can be applied directly to any suitably dynamic OO language (Perl, Python, Perl 6, Javascript&#8230;) and the syntax of Smalltalk is virtually nonexistent and easy enough to pick up.</p> <p>The book works well because Beck, quite deliberately, limits its scope to the tactics of coding. Instead of going for the big things, we&#8217;re dealing with the nuts and bolts: how to choose good names, how to write methods in ways that encourage reuse and flexibility, how to keep things loosely coupled. Beck explains this stuff with concrete examples and simple rules, that work phenomenally well together. It&#8217;s hard to put my finger on <em>why</em> it works so well, but my gut feeling is that it&#8217;s because Beck has not forgotten the importance of context.</p> <p>Very few of the patterns are strictly standalone, they refer to each other up and down the &#8216;levels&#8217; of the various patterns and the individual patterns are small enough, and well enough supported by the other patterns in the language that they remain tightly focussed on the issue they address.</p> <p><cite>Smalltalk Best Practice Patterns</cite> is a complete pattern language, something that I&#8217;ve not seen achieved in any other software patterns book (though Martin Fowler&#8217;s <cite asin="0201485672">Refactoring: Improving the Design of Existing Code</cite> gets pretty close.) It&#8217;s easy to read; full of practical wisdom from someone who knows their stuff and can explain it well.</p> <p>I recommend this book wholeheartedly to anyone who wants to become a better programmer, and especially to anyone who does object oriented programming in a dynamic language of any kind. If you find me in a bar amongst programmers, and we&#8217;re talking about how to get better at our craft, then I&#8217;ll almost certainly be banging on about how good this book is.</p> <p>I believe the Java types are fans too, but if I were a java programmer then I&#8217;d find the kind of flexibility inherent in Smalltalk as expressed in this book would just make me want to abandon Java in favour of something more expressive.</p> Tue, 29 Jul 2003 06:06:00 -0500 urn:uuid:a857db3e470e75cbe6da6e39d32982cf pdcawley@bofh.org.uk (Piers Cawley) http://www.bofh.org.uk/articles/2003/07/29/the-quality-without-a-name#comments The Practice of Programming Review review practiceofprogramming designpatterns XP extremeprogramming agilemethods http://www.bofh.org.uk/trackbacks?article_id=the-quality-without-a-name&day=29&month=07&year=2003 http://www.bofh.org.uk/articles/2003/07/29/the-quality-without-a-name