<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-3933266989882835478</id><updated>2018-09-17T08:49:00.094+01:00</updated><title type='text'>David Peterson</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://blog.davidpeterson.co.uk/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3933266989882835478/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://blog.davidpeterson.co.uk/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/3933266989882835478/posts/default?start-index=26&amp;max-results=25&amp;redirect=false'/><author><name>David Peterson</name><uri>http://www.blogger.com/profile/03475136061061572446</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>37</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-3933266989882835478.post-3017257218352705922</id><published>2014-01-03T11:59:00.000+00:00</published><updated>2014-01-03T11:59:40.318+00:00</updated><title type='text'>Stretch zone</title><content type='html'>&lt;p&gt;This model is by &lt;a href=&quot;http://www.karlrohnke.com/&quot;&gt;Karl Rohnke&lt;/a&gt;, an outdoor adventure instructor. I like the way it reduces the black and whiteness of the concept of comfort zones.&lt;/p&gt;&lt;div&gt;&lt;img src=&quot;http://www.davidpeterson.co.uk/image/thinking/stretch-zone.svg&quot; alt=&quot;comfort-stretch-panic model&quot; border=&quot;0&quot; style=&quot;border: 0&quot; /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.davidpeterson.co.uk/feeds/3017257218352705922/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3933266989882835478&amp;postID=3017257218352705922' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3933266989882835478/posts/default/3017257218352705922'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3933266989882835478/posts/default/3017257218352705922'/><link rel='alternate' type='text/html' href='http://blog.davidpeterson.co.uk/2014/01/stretch-zone.html' title='Stretch zone'/><author><name>David Peterson</name><uri>http://www.blogger.com/profile/03475136061061572446</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3933266989882835478.post-8702846121309873104</id><published>2013-10-10T11:41:00.000+01:00</published><updated>2013-10-10T11:42:46.176+01:00</updated><title type='text'>Make them work for it</title><content type='html'>&lt;p&gt;I think this campaign from Transport for London is fantastic.&lt;/p&gt;&lt;img border=&quot;0&quot; style=&quot;border: 0px&quot; src=&quot;http://www.davidpeterson.co.uk/image/misc/watch-for-bikes.svg&quot; alt=&quot;&#39;Drivers, look out for cyclists&#39; poster&quot; /&gt;&lt;p&gt;I love that everything is parallel, the bike is behind the vehicle and the road edge extends to the full width of the poster. It looks like there&#39;s no danger, so you have to use your imagination to make sense of the caption.&lt;/p&gt;&lt;p&gt;I also suspect that the campaign is not really aimed at drivers.&lt;/p&gt;&lt;br /&gt;&lt;hr /&gt;&lt;p&gt;By the way, if you can&#39;t see the picture, try a different browser! I&#39;ve been moving away from bitmap images to SVG (vector graphics), to support high-resolution devices. I&#39;ve updated most of my previous posts with SVG versions of the pictures. My assumption is that most people who read my blog will have a modern browser.&lt;/p&gt;&lt;hr /&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.davidpeterson.co.uk/feeds/8702846121309873104/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3933266989882835478&amp;postID=8702846121309873104' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3933266989882835478/posts/default/8702846121309873104'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3933266989882835478/posts/default/8702846121309873104'/><link rel='alternate' type='text/html' href='http://blog.davidpeterson.co.uk/2013/10/make-them-work-for-it.html' title='Make them work for it'/><author><name>David Peterson</name><uri>http://www.blogger.com/profile/03475136061061572446</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3933266989882835478.post-7819075433409840959</id><published>2013-04-15T11:56:00.001+01:00</published><updated>2013-10-10T11:40:49.698+01:00</updated><title type='text'>Expressing your thinking in code comments</title><content type='html'>&lt;p style=&quot;font-size: 12pt; margin-top: 24px;&quot;&gt;&lt;b&gt;Comments are sometimes warning signals&lt;/b&gt;&lt;/p&gt;&lt;p&gt;When you feel the need to add a comment to a piece of code it is sometimes a signal that the code is getting too complicated. It&#39;s generally better to fix the underlying design problem than write a comment to explain the mess. As soon as code starts to become complex it is very easy to &lt;a href=&quot;http://blog.davidpeterson.co.uk/2011/04/why-do-agile-projects-fail-so-often.html&quot;&gt;descend into a negative spiral&lt;/a&gt;.&lt;/p&gt;&lt;p style=&quot;font-size: 12pt; margin-top: 24px;&quot;&gt;&lt;b&gt;However, some explanatory comments can be very helpful&lt;/b&gt;&lt;/p&gt;&lt;p&gt;I have found a lot of value writing comments to explain the rationale for a design and possible future directions that I might forget or that others will find useful. I&#39;ve got a brain like a sieve and I used to find that I frequently ended up rewriting code I&#39;d previously written because I couldn&#39;t remember the direction the design was going in or how it fits together with other pieces. A real waste of time. The comments have almost completely stopped that, but they can cause a new problem: I sometimes find it hard to resist the temptation to start implementing the future-direction ideas I&#39;m explaining in the comment. &lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.davidpeterson.co.uk/feeds/7819075433409840959/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3933266989882835478&amp;postID=7819075433409840959' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3933266989882835478/posts/default/7819075433409840959'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3933266989882835478/posts/default/7819075433409840959'/><link rel='alternate' type='text/html' href='http://blog.davidpeterson.co.uk/2013/04/expressing-your-thinking-in-code.html' title='Expressing your thinking in code comments'/><author><name>David Peterson</name><uri>http://www.blogger.com/profile/03475136061061572446</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3933266989882835478.post-1553757329768790632</id><published>2012-07-04T21:33:00.001+01:00</published><updated>2012-07-05T15:59:59.899+01:00</updated><title type='text'>Separating Look/Feel from View/Presenter</title><content type='html'>&lt;a style=&quot;float: right;&quot; href=&quot;http://www.davidpeterson.co.uk/lab/on-off/demo.html&quot;&gt;&lt;img style=&quot;border: 0&quot; src=&quot;http://www.davidpeterson.co.uk/image/oo/on-off.svg&quot;&gt;&lt;/a&gt;&lt;p&gt; Here&#39;s a &lt;a href=&quot;http://www.davidpeterson.co.uk/lab/on-off/demo.html&quot;&gt;demo&lt;/a&gt; of a working iPad-style on-off switch that I wrote in SVG and Javascript (GWT). &lt;/p&gt;  &lt;p&gt; SVG seems to work pretty consistently across platforms &amp;#8211; including the iPad, iPhone and all modern desktop browsers, astonishingly even IE 9. The only unfortunate exception is Android where, apparently, SVG support was actively removed to reduce the browser footprint (by a measly 1MB). You can work around it by installing Android Firefox which supports SVG though not multi-touch. &lt;/p&gt;  &lt;p&gt; As I developed the on-off switch control, I separated out two distinct interfaces that I called: &lt;b&gt;View&lt;/b&gt; and &lt;b&gt;Look&lt;/b&gt;. To give them a proper namespace, without too much clutter, I nested the interfaces inside an outer interface for the &lt;b&gt;OnOffSwitch&lt;/b&gt; something like this: &lt;/p&gt;  &lt;pre style=&quot;font-size: 13px; font-family: Courier New, Courier, Monospace; background-color: #f7f7f7; padding: 16px;&quot;&gt;&lt;b style=&quot;color: #7F0055&quot;&gt;public interface&lt;/b&gt; OnOffSwitch {&lt;br /&gt;&lt;br /&gt;    &lt;b style=&quot;color: #7F0055&quot;&gt;interface&lt;/b&gt; View {&lt;br /&gt;&lt;br /&gt;        &lt;b style=&quot;color: #7F0055&quot;&gt;void&lt;/b&gt; setOn(&lt;b style=&quot;color: #7F0055&quot;&gt;boolean&lt;/b&gt; on);&lt;br /&gt;&lt;br /&gt;        &lt;b style=&quot;color: #7F0055&quot;&gt;boolean&lt;/b&gt; isOn();&lt;br /&gt;&lt;br /&gt;        HandlerRegistration addValueChangeHandler(&lt;br/&gt;            ValueChangeHandler&amp;lt;Boolean&amp;gt; handler);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    &lt;b style=&quot;color: #7F0055&quot;&gt;interface&lt;/b&gt; Look {&lt;br /&gt;&lt;br /&gt;        &lt;b style=&quot;color: #7F0055&quot;&gt;void&lt;/b&gt; knobDown();&lt;br /&gt;&lt;br /&gt;        &lt;b style=&quot;color: #7F0055&quot;&gt;void&lt;/b&gt; knobUp();&lt;br /&gt;&lt;span style=&quot;color: #3F5FBF&quot;&gt;&lt;br /&gt;        /**&lt;br /&gt;         * &lt;span style=&quot;color: #7F9FBF&quot;&gt;@param&lt;/span&gt; position&lt;br /&gt;         *        A value between zero and one (0 = OFF, 1 = ON)&lt;br /&gt;         */&lt;/span&gt;&lt;br /&gt;        &lt;b style=&quot;color: #7F0055&quot;&gt;void&lt;/b&gt; setKnobPosition(&lt;b style=&quot;color: #7F0055&quot;&gt;double&lt;/b&gt; position);&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;  &lt;p&gt; The &lt;b&gt;Look&lt;/b&gt; is called by a &lt;b&gt;Feel&lt;/b&gt; object that translates mouse-clicks and touches. The &lt;b&gt;View&lt;/b&gt; is called by the application code. My &lt;b&gt;SVGOnOffSwitch&lt;/b&gt; widget implements both &lt;b&gt;Look&lt;/b&gt; and &lt;b&gt;View&lt;/b&gt; interfaces and hooks itself up to a default &lt;b&gt;Feel&lt;/b&gt; object. Testing the &lt;b&gt;Feel&lt;/b&gt; object was easy to do by passing it a mock &lt;b&gt;Look&lt;/b&gt;.&lt;/p&gt; &lt;p&gt; It&#39;s always hard coming up with good names for interfaces and objects. I thought I&#39;d post this because I was pleased with the way the code ended up.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.davidpeterson.co.uk/feeds/1553757329768790632/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3933266989882835478&amp;postID=1553757329768790632' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3933266989882835478/posts/default/1553757329768790632'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3933266989882835478/posts/default/1553757329768790632'/><link rel='alternate' type='text/html' href='http://blog.davidpeterson.co.uk/2012/07/look-and-feel.html' title='Separating Look/Feel from View/Presenter'/><author><name>David Peterson</name><uri>http://www.blogger.com/profile/03475136061061572446</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3933266989882835478.post-1829710083950341246</id><published>2012-06-19T19:00:00.002+01:00</published><updated>2012-06-24T10:20:23.323+01:00</updated><title type='text'>A &quot;new&quot; alternative to Spring</title><content type='html'>&lt;p&gt;Objects are composed of objects. The pen in your hand is composed of a nib, a cartridge, and a plastic sheath. The cartridge contains ink, some kind of valve and so forth. The word &quot;pen&quot; is an abstraction that allows us to communicate at a higher-level and ignore all that detail. &lt;/p&gt; &lt;p&gt; However, when you use a dependency injection (DI) framework, like &lt;a href=&quot;http://www.springsource.org/&quot;&gt;Spring&lt;/a&gt;, to wire objects together, everything appears to be at the same level of abstraction. &lt;/p&gt; &lt;p style=&quot;font-size: 12pt; margin-top: 24px&quot;&gt;&lt;b&gt;Abstraction is the key to dealing with complexity&lt;/b&gt;&lt;/p&gt; &lt;p&gt; Without being able to distinguish higher-level abstractions it&#39;s easy to become mired in low-level implementation detail. The complexity makes it harder to reason about the application and hard to maintain a clean separation of concerns. &lt;/p&gt; &lt;p&gt;&lt;img style=&quot;border: 0&quot; src=&quot;http://www.davidpeterson.co.uk/memos/images/spring-soup-1.svg&quot; /&gt;&lt;/p&gt; &lt;p style=&quot;font-size: 12pt; margin-top: 24px&quot;&gt;&lt;b&gt;Find clusters that can be abstracted&lt;/b&gt;&lt;/p&gt; &lt;p&gt; To work at higher levels of abstraction, we need to encapsulate a graph of lower-level objects inside a simpler fa&amp;#xe7;ade. The &lt;a href=&quot;http://www.growing-object-oriented-software.com/&quot;&gt;GOOS&lt;/a&gt; authors call this &quot;the rule of composite simpler than the sum of its parts&quot; (p.53). &lt;/p&gt; &lt;p&gt;&lt;img style=&quot;border: 0&quot; src=&quot;http://www.davidpeterson.co.uk/memos/images/spring-soup-2.svg&quot; /&gt;&lt;/p&gt; &lt;p style=&quot;font-size: 12pt; margin-top: 24px&quot;&gt;&lt;b&gt;Inner objects are &lt;u&gt;not&lt;/u&gt; peers&lt;/b&gt;&lt;/p&gt; &lt;p&gt; The encapsulated objects are &lt;em&gt;inside&lt;/em&gt; the higher-level object. They are not external collaborators of the object. The inner objects are an implementation detail. &lt;/p&gt; &lt;p&gt; To construct our objects we have two basic choices: either (1) we pass inner objects in through the constructor/setters (&amp;#224; la Spring) or (2) we create the inner objects inside the outer object.&lt;/p&gt; &lt;p style=&quot;font-size: 12pt; margin-top: 24px&quot;&gt;&lt;b&gt;Injecting inner-objects breaks encapsulation&lt;/b&gt;&lt;/p&gt; &lt;p&gt; If we pass objects in, we make it hard to distinguish internals from peers and we break encapsulation because we are forced to know how the object is implemented when we construct it. &lt;/p&gt; &lt;p style=&quot;font-size: 12pt; margin-top: 24px&quot;&gt;&lt;b&gt;Use &quot;new&quot; instead&lt;/b&gt;&lt;/p&gt; &lt;p&gt; The simple alternative is to use the &lt;code style=&quot;font-size: 13px&quot;&gt;new&lt;/code&gt; operator to create the internal objects and wire them together in the outer object&#39;s constructor. If we do this consistently through our application, we don&#39;t actually need a DI framework. Objects themselves are quite capable of performing the role that a DI container would perform. &lt;/p&gt; &lt;p style=&quot;font-size: 12pt; margin-top: 24px&quot;&gt;&lt;b&gt;If necessary, mix the two approaches&lt;/b&gt;&lt;/p&gt; &lt;p&gt;There are occasions when having separated configuration can be useful - e.g. for supporting plugins. There is nothing stopping us from adopting a hybrid of the two approaches. We can use a DI container for those specific objects that need it.&lt;/p&gt; &lt;p&gt; And vice versa: if we&#39;re already using Spring, there&#39;s nothing to stop us pulling out clusters of objects from the Spring configuration and assembling them in code, one cluster at a time. It doesn&#39;t have to be an all-or-nothing transition. It can be done gently.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.davidpeterson.co.uk/feeds/1829710083950341246/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3933266989882835478&amp;postID=1829710083950341246' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3933266989882835478/posts/default/1829710083950341246'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3933266989882835478/posts/default/1829710083950341246'/><link rel='alternate' type='text/html' href='http://blog.davidpeterson.co.uk/2012/06/problem-with-di-frameworks.html' title='A &quot;new&quot; alternative to Spring'/><author><name>David Peterson</name><uri>http://www.blogger.com/profile/03475136061061572446</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3933266989882835478.post-1869466792494636161</id><published>2011-06-11T17:56:00.008+01:00</published><updated>2012-03-29T18:25:09.097+01:00</updated><title type='text'>Eli Goldratt RIP</title><content type='html'>&lt;p&gt;I just received very sad news that &lt;a href=&quot;http://en.wikipedia.org/wiki/Eliyahu_M._Goldratt&quot;&gt;Eli Goldratt&lt;/a&gt; died today. He had aggressive lung cancer, presumably brought on from a lifetime of pipe-smoking. I feel extremely lucky to have met him. He has influenced my life tremendously. I only wish I&#39;d met him earlier. :-(&lt;/p&gt;&lt;div style=&quot;padding-top: 8px&quot;&gt;&lt;img style=&quot;border: 0px&quot; src=&quot;http://www.davidpeterson.co.uk/image/people/eli-goldratt.svg&quot; width=&quot;566px&quot; height=&quot;480px&quot; alt=&quot;Picture of Dr. Eliyahu M. Goldratt&quot; /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.davidpeterson.co.uk/feeds/1869466792494636161/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3933266989882835478&amp;postID=1869466792494636161' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3933266989882835478/posts/default/1869466792494636161'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3933266989882835478/posts/default/1869466792494636161'/><link rel='alternate' type='text/html' href='http://blog.davidpeterson.co.uk/2011/06/eli-goldratt-rip.html' title='Eli Goldratt RIP'/><author><name>David Peterson</name><uri>http://www.blogger.com/profile/03475136061061572446</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3933266989882835478.post-2897070456214479615</id><published>2011-04-29T15:25:00.055+01:00</published><updated>2012-03-29T20:08:23.297+01:00</updated><title type='text'>Why do teams fail to sustain code quality?</title><content type='html'>&lt;p&gt;Code quality always seems to get worse and worse. Even when a team is actively fighting against it, complexity inevitably wins in the end. What&#39;s going on? Why is this pull towards complexity such a powerful force? &lt;/p&gt; &lt;p&gt;In my view, a lot of the problem stems from the wrong actions being taken, with the best of intentions in mind.&lt;/p&gt;&lt;p style=&quot;font-size: 12pt; margin-top: 24px&quot;&gt;&lt;b&gt;Code quality quickly spirals down&lt;/b&gt;&lt;/p&gt; &lt;p&gt;Developers don&#39;t want to introduce bugs, so they naturally take actions to avoid doing so. Making changes to working code is risky, so developers make heavy use of conditional logic (&quot;in my particular case do this, otherwise, do the same as before&quot;) and duplication to minimise the changes to existing code. &lt;/p&gt;&lt;p&gt;There&#39;s a good intention behind it. Unfortunately, it makes the code increasingly difficult to work with&amp;#8212;to understand the ramifications of a change&amp;#8212; and subsequently increases the pressure to tread carefully and avoid making those bigger and bolder changes to the design that are really needed to keep the code clean. &lt;/p&gt;  &lt;div style=&quot;text-align: center; padding: 24px;&quot;&gt; &lt;img width=&quot;530px&quot; height=&quot;484px&quot; style=&quot;border: 0px;&quot; src=&quot;http://www.davidpeterson.co.uk/image/business/code-complexity-spiral.svg&quot; /&gt; &lt;/div&gt; &lt;p style=&quot;font-size: 12pt; margin-top: 24px&quot;&gt;&lt;b&gt;Automated regression tests aren&#39;t enough to stop it&lt;/b&gt;&lt;/p&gt; &lt;p&gt; Agile teams tend to make heavy use of automated regression tests. This not only allows the team to release code frequently, but allows them to refactor it and keep the design in good shape. The tests should catch any bugs introduced when the design is reworked.&lt;/p&gt;   &lt;div style=&quot;text-align: center; padding: 24px;&quot;&gt; &lt;img width=&quot;439px&quot; height=&quot;242px&quot; style=&quot;border: 0px;&quot; src=&quot;http://www.davidpeterson.co.uk/image/business/code-complexity-step-1.svg&quot; /&gt; &lt;/div&gt; &lt;p&gt; That&#39;s the theory, but, in practice, the developers don&#39;t keep the design clean. Why? Because their old &quot;don&#39;t make unnecessary changes&quot; habit is so deeply-ingrained. And so, the vicious circle continues. &lt;/p&gt;   &lt;div style=&quot;text-align: center; padding: 24px;&quot;&gt; &lt;img width=&quot;245px&quot; height=&quot;223px&quot; style=&quot;border: 0px;&quot; src=&quot;http://www.davidpeterson.co.uk/image/business/code-complexity-problem-2.svg&quot; /&gt; &lt;/div&gt; &lt;p style=&quot;font-size: 12pt; margin-top: 24px&quot;&gt;&lt;b&gt;You have to change the habits too&lt;/b&gt;&lt;/p&gt; &lt;p&gt; How do you change habits? Education, constant reminders, code reviews, management oversight, tie a knot in your handkerchief... whatever it takes because if you don&#39;t change the habits your code quality will deteriorate and your team&#39;s agility will disappear with it. &lt;/p&gt;  &lt;div style=&quot;text-align: center; padding: 24px;&quot;&gt; &lt;img width=&quot;485px&quot; height=&quot;235px&quot; style=&quot;border: 0px;&quot; src=&quot;http://www.davidpeterson.co.uk/image/business/code-complexity-step-2.svg&quot; /&gt; &lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.davidpeterson.co.uk/feeds/2897070456214479615/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3933266989882835478&amp;postID=2897070456214479615' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3933266989882835478/posts/default/2897070456214479615'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3933266989882835478/posts/default/2897070456214479615'/><link rel='alternate' type='text/html' href='http://blog.davidpeterson.co.uk/2011/04/why-do-agile-projects-fail-so-often.html' title='Why do teams fail to sustain code quality?'/><author><name>David Peterson</name><uri>http://www.blogger.com/profile/03475136061061572446</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3933266989882835478.post-1037612264560563726</id><published>2011-04-29T10:26:00.003+01:00</published><updated>2012-07-05T09:02:33.683+01:00</updated><title type='text'>&quot;Circuit Diagram&quot; for Options</title><content type='html'>&lt;p&gt;After drawing the diagrams for my &lt;a href=&quot;http://blog.davidpeterson.co.uk/2011/04/always-have-plan-b.html&quot;&gt;last post&lt;/a&gt;, I&#39;m playing with ideas for a notation for describing options. What I&#39;ve come up with so far isn&#39;t very good &amp;#8212; I&#39;m not even very clear on what the dimensions are... I think it&#39;s roughly time along the x-axis and choices along the y-axis, though I think I may be mixing other concepts in as well &amp;#8212; but, anyway, I thought I&#39;d put it out in the hope that someone else might help me improve it.&lt;/p&gt;&lt;p&gt;Here&#39;s a real-life example from my last project (read it from left to right):&lt;/p&gt;&lt;div&gt;&lt;img src=&quot;http://www.davidpeterson.co.uk/image/business/options-circuit-diagram.svg&quot; style=&quot;border: 0px; padding: 24px 0px 24px 0px;&quot;/&gt;&lt;/div&gt;&lt;p&gt;We actually followed these steps. The team in Hong Kong worked on improving the speed of the database reports, while, in London, I built an alternative report generator that wasn&#39;t as flexible, but was very fast. By release time the Hong Kong team had ironed out all the problems with the queries and optimised the databases indexes so their reports were adequately fast. In the end, we went with a mixture of the two.&lt;/p&gt;&lt;p&gt;I also got in trouble by trying to be too clever. I put code in to the test environment to do live cross-checking of the reports generated by the two methods. It did reveal some discrepancies. But I got in trouble because they were trying to do speed tests at the time. Communication, communication, communication...&lt;/p&gt;&lt;p&gt;Let me know if you have any ideas about a notation for describing options (I&#39;m talking about real-life options, not financial options).&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.davidpeterson.co.uk/feeds/1037612264560563726/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3933266989882835478&amp;postID=1037612264560563726' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3933266989882835478/posts/default/1037612264560563726'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3933266989882835478/posts/default/1037612264560563726'/><link rel='alternate' type='text/html' href='http://blog.davidpeterson.co.uk/2011/04/circuit-diagram-for-options.html' title='&quot;Circuit Diagram&quot; for Options'/><author><name>David Peterson</name><uri>http://www.blogger.com/profile/03475136061061572446</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3933266989882835478.post-2334359276901095367</id><published>2011-04-28T15:10:00.003+01:00</published><updated>2012-07-05T09:03:21.132+01:00</updated><title type='text'>Always have a plan &#39;B&#39;</title><content type='html'>&lt;p&gt; You cannot predict exactly what&#39;s going to happen in the future. Having options allows you to respond quickly as different situations arise. &lt;/p&gt;  &lt;div style=&quot;margin: 16px; text-align: center;&quot;&gt;&lt;img style=&quot;border: 0px&quot; src=&quot;http://www.davidpeterson.co.uk/image/business/real-option-types.svg&quot; /&gt;&lt;/div&gt;   &lt;p style=&quot;font-size: 12pt; margin-top: 24px&quot;&gt;&lt;b&gt;Option to Abandon&lt;/b&gt;&lt;/p&gt;  &lt;p&gt; Lifeboats on an ocean liner are an example of the option to abandon. The same with backups of your software. With luck you&#39;ll never need them, but it&#39;s worth creating the option just in case. &lt;/p&gt; &lt;p style=&quot;font-size: 12pt; margin-top: 24px&quot;&gt;&lt;b&gt;Option to Backtrack&lt;/b&gt;&lt;/p&gt;  &lt;p&gt; The option to backtrack is similar to the option to abandon, except that you don&#39;t abandon the direction completely, you go back to a previous &quot;safe&quot; point ready to try again. &lt;/p&gt;  &lt;p&gt; If you release a new version of some software and then find it&#39;s unstable, you want to be able to go back to the previous version. Any kind of &quot;rollback&quot; or &quot;undo&quot; capability is providing the option to backtrack. &lt;/p&gt;  &lt;p&gt; Being able to backtrack is important for learning. To experiment with a piece of software, try out a new refactoring, or test the boundaries of a technique you want to feel safe that you can go back to where you were. &lt;/p&gt;   &lt;p style=&quot;font-size: 12pt; margin-top: 24px&quot;&gt;&lt;b&gt;Option to Choose&lt;/b&gt;&lt;/p&gt;  &lt;p&gt; This option is about alternatives. To travel between cities you might take a train, but if the train drivers are on strike you&#39;ll need to find another way. By thinking about your choice of options in advance, you won&#39;t need to panic. &lt;/p&gt;  &lt;p&gt; An example in software is where the business logic is decoupled from the data storage technology, so that users can choose between several different databases. This can create value by widening the potential market. &lt;/p&gt;   &lt;p style=&quot;font-size: 12pt; margin-top: 24px&quot;&gt;&lt;b&gt;Option to Defer&lt;/b&gt;&lt;/p&gt;  &lt;p&gt; This option is about timing. Do we have to decide now or can we decide later? The option to defer is about pushing back decision points, to allow more information to come in, or being able to put something on hold, with the possibility of returning to it later on &amp;#8212; for example, postponing a space shuttle launch due to icy conditions. &lt;/p&gt;    &lt;p&gt; Traditional software development methods force the development team to commit to features a long time before they are developed or deployed. Agile methods let you defer commitment (see &lt;a href=&quot;http://www.infoq.com/articles/real-options-enhance-agility&quot;&gt;this article&lt;/a&gt; by Chris Matts and Olav Maassen for a more in-depth explanation of how options-thinking relates to agile). &lt;/p&gt;   &lt;p style=&quot;font-size: 12pt; margin-top: 24px&quot;&gt;&lt;b&gt;Option to Expand (or Contract)&lt;/b&gt;&lt;/p&gt;  &lt;p&gt; This option is about resources. If a customer wants to place a huge order with you, can you accommodate it? Can you recruit quickly? Can you move resources from a less successful project to another more successful one? &lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.davidpeterson.co.uk/feeds/2334359276901095367/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3933266989882835478&amp;postID=2334359276901095367' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3933266989882835478/posts/default/2334359276901095367'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3933266989882835478/posts/default/2334359276901095367'/><link rel='alternate' type='text/html' href='http://blog.davidpeterson.co.uk/2011/04/always-have-plan-b.html' title='Always have a plan &#39;B&#39;'/><author><name>David Peterson</name><uri>http://www.blogger.com/profile/03475136061061572446</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3933266989882835478.post-1045650321003539087</id><published>2011-03-29T21:29:00.011+01:00</published><updated>2011-03-29T21:59:45.479+01:00</updated><title type='text'>Start with clear acceptance tests</title><content type='html'>&lt;p&gt; One of the advantages of acceptance test driven development (ATDD) is that it helps a team to agree on the objectives before diving into coding. The clearer the acceptance tests, the fewer misunderstandings there are likely to be. Every misunderstanding wastes time and adds cruft to the software. &lt;/p&gt;  &lt;p&gt; Releasing frequently gives an opportunity for feedback and correction. Small corrections early on can prevent the need for large corrections later. &lt;/p&gt; &lt;div style=&quot;margin-top: 24px; padding: 24px; background-color: #eceae0;&quot;&gt;  &lt;p&gt; &lt;b&gt;1.&lt;/b&gt; Well-articulated acceptance tests and frequent releases: &lt;/p&gt;  &lt;div&gt; &lt;center&gt;&lt;img style=&quot;text-align: center; border: 0px; margin: 4px 0px 12px 4px;&quot; alt=&quot;Relatively straight line&quot; src=&quot;http://www.davidpeterson.co.uk/image/agile/strategy/well-articulated-objective.png&quot; /&gt; &lt;/center&gt; &lt;/div&gt;   &lt;p&gt; &lt;b&gt;2.&lt;/b&gt; Poorly articulated acceptance tests: &lt;/p&gt;  &lt;div&gt; &lt;center&gt;&lt;img style=&quot;text-align: center; border: 0px; margin: 4px 0px 12px 4px;&quot; alt=&quot;Line with some zig-zagging&quot; src=&quot;http://www.davidpeterson.co.uk/image/agile/strategy/poorly-articulated-objective.png&quot; /&gt; &lt;/center&gt; &lt;/div&gt;  &lt;p&gt; &lt;b&gt;3.&lt;/b&gt; Longer times between releases exaggerate the deviations: &lt;/p&gt;  &lt;div&gt; &lt;center&gt;&lt;img style=&quot;text-align: center; border: 0px; margin: 4px 0px 12px 4px;&quot; alt=&quot;Line with fewer segments and severe zig-zagging&quot; src=&quot;http://www.davidpeterson.co.uk/image/agile/strategy/longer-feedback-times.png&quot; /&gt; &lt;/center&gt; &lt;/div&gt;   &lt;p&gt; &lt;b&gt;4.&lt;/b&gt; Without any vision or objectives: &lt;/p&gt;  &lt;div&gt; &lt;center&gt;&lt;img style=&quot;text-align: center; border: 0px; margin: 4px 0px 12px 4px;&quot; alt=&quot;Random loopy patterns&quot; src=&quot;http://www.davidpeterson.co.uk/image/agile/strategy/random.png&quot; /&gt; &lt;/center&gt; &lt;/div&gt; &lt;p&gt; This often happens in start-ups where a product idea is hazy and the team is basically chasing every hare that runs past. Eventually they might happen to catch one, but it&#39;s a pretty inefficient way to work. &lt;/p&gt; &lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.davidpeterson.co.uk/feeds/1045650321003539087/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3933266989882835478&amp;postID=1045650321003539087' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3933266989882835478/posts/default/1045650321003539087'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3933266989882835478/posts/default/1045650321003539087'/><link rel='alternate' type='text/html' href='http://blog.davidpeterson.co.uk/2011/03/start-with-clear-acceptance-tests.html' title='Start with clear acceptance tests'/><author><name>David Peterson</name><uri>http://www.blogger.com/profile/03475136061061572446</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3933266989882835478.post-115592596760453976</id><published>2011-03-25T18:17:00.003+00:00</published><updated>2012-07-05T09:14:37.569+01:00</updated><title type='text'>Evaluating start-up business ideas</title><content type='html'>&lt;p&gt;I often have ideas for start-up businesses and get quite excited about them until it slowly dawns on me there are major flaws. In a bid to spot the flaws sooner, I&#39;ve come up with some evaluation criteria. I thought I&#39;d post them, in case anyone finds them interesting or has any of their own thoughts on the subject they&#39;d like to share.&lt;/p&gt;&lt;div&gt;&lt;img src=&quot;http://www.davidpeterson.co.uk/image/business/judging-business-overview.svg&quot; alt=&quot;Judging a business&quot; style=&quot;border: 0px&quot; /&gt;&lt;/div&gt;&lt;p style=&quot;margin-top: 24px; font-size: 12pt; font-weight: bold&quot;&gt;Large scope for growth&lt;/p&gt;&lt;div&gt;&lt;img src=&quot;http://www.davidpeterson.co.uk/image/business/judging-business-scope-for-growth.svg&quot; alt=&quot;Judging a business&quot; style=&quot;border: 0px&quot; /&gt;&lt;/div&gt;&lt;p style=&quot;margin-top: 24px; font-size: 12pt; font-weight: bold&quot;&gt;Risks can be kept low&lt;/p&gt;&lt;div&gt;&lt;img src=&quot;http://www.davidpeterson.co.uk/image/business/judging-business-risk.svg&quot; alt=&quot;Judging a business&quot; style=&quot;border: 0px&quot; /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.davidpeterson.co.uk/feeds/115592596760453976/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3933266989882835478&amp;postID=115592596760453976' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3933266989882835478/posts/default/115592596760453976'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3933266989882835478/posts/default/115592596760453976'/><link rel='alternate' type='text/html' href='http://blog.davidpeterson.co.uk/2011/03/evaluating-start-up-business-ideas.html' title='Evaluating start-up business ideas'/><author><name>David Peterson</name><uri>http://www.blogger.com/profile/03475136061061572446</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3933266989882835478.post-4765628186375558285</id><published>2011-01-21T14:09:00.008+00:00</published><updated>2012-07-05T08:40:09.363+01:00</updated><title type='text'>What&#39;s wrong with the Agile Manifesto?</title><content type='html'>&lt;p&gt; I&#39;ve never liked the &lt;a href=&quot;http://agilemanifesto.org/&quot;&gt;Agile Manifesto&lt;/a&gt;. I&#39;m not blaming the authors because I know it must have been a nightmare trying to come to a consensus, and the manifesto has served a useful purpose bringing like-minded people together under a single brand. It is slightly ironic that the wording hasn&#39;t changed in 10 years, but there you go. I&#39;m not brave enough to propose an alternative yet. In this article, I&#39;m just going to explain where I think the logic is faulty. &lt;/p&gt;  &lt;p&gt; Here is the wording of the manifesto: &lt;/p&gt;  &lt;p style=&quot;margin: 16px; padding: 20px; border: 3px solid #d7bb9e; font-style: normal; background-color: #ffeedd;&quot;&gt; &lt;b&gt;Manifesto for Agile Software Development&lt;/b&gt; &lt;br /&gt; &lt;br /&gt;We are uncovering better ways of developing software by doing it and helping others do it. Through this work we have come to value: &lt;br /&gt; &lt;br /&gt;&lt;b&gt;Individuals and interactions&lt;/b&gt; over processes and tools &lt;br /&gt;&lt;b&gt;Working software&lt;/b&gt; over comprehensive documentation &lt;br /&gt;&lt;b&gt;Customer collaboration&lt;/b&gt; over contract negotiation &lt;br /&gt;&lt;b&gt;Responding to change&lt;/b&gt; over following a plan &lt;br /&gt; &lt;br /&gt;That is, while there is value in the items on the right, we value the items on the left more. &lt;/p&gt;  &lt;p style=&quot;margin-top: 24px; font-size: 12pt; font-weight: bold&quot;&gt;It doesn&#39;t distinguish agile from &quot;slapdash&quot;&lt;/p&gt;  &lt;p&gt;The aim of the manifesto seems to be to try and distinguish agile from waterfall. Unfortunately, agile&#39;s worst enemy isn&#39;t waterfall but the &quot;we don&#39;t write documentation, so we&#39;re agile&quot; brigade. And the manifesto doesn&#39;t defend agile very well against this threat. Perhaps there&#39;s something in the &lt;a href=&quot;http://agilemanifesto.org/principles.html&quot;&gt;twelve principles&lt;/a&gt; but who on earth reads them? Certainly not the slapdash developers claiming to be agile. &lt;/p&gt;  &lt;p style=&quot;margin-top: 24px; font-size: 12pt; font-weight: bold&quot;&gt;It mixes up goals and solutions&lt;/p&gt;  &lt;p&gt; &quot;We value working software over comprehensive documentation&quot;. OK, but surely whatever software development method you select, working software is the ultimate goal, isn&#39;t it? Some people believe that by writing comprehensive documentation you are more likely to produce working software. That&#39;s part of their solution. But you can&#39;t go round comparing goals with solutions. It&#39;s nonsensical. Perhaps what the manifesto authors wanted to convey was that &quot;the code is the documentation&quot;, or something along those lines, but couldn&#39;t agree to write it, so plumped for the goal as their solution. That&#39;s cheating! &lt;/p&gt;  &lt;p style=&quot;margin-top: 24px; font-size: 12pt; font-weight: bold&quot;&gt;The dilemmas are easy to solve&lt;/p&gt;  &lt;p&gt; The manifesto poses dilemmas and then tries to position agile at a certain point in each trade-off continuum. But why are we compromising? If both sides have value (as the manifesto plainly says), why don&#39;t we find solutions that resolve the conflicts? Let&#39;s take each one in turn: &lt;/p&gt;  &lt;div&gt; &lt;img style=&quot;border: 0px; margin-top: 10px; margin-bottom: 24px&quot; src=&quot;http://www.davidpeterson.co.uk/image/agile/agile-manifesto-processes-dilemma.svg&quot; /&gt; &lt;/div&gt; &lt;p&gt;I don&#39;t know whether the value of documentation is to do with maintainability, improving clarity or good governance. The point I&#39;m trying to make is that there does not have to be any compromise between those needs and agile methods.&lt;/p&gt; &lt;div&gt; &lt;img style=&quot;border: 0px; margin-top: 10px; margin-bottom: 24px&quot; src=&quot;http://www.davidpeterson.co.uk/image/agile/agile-manifesto-documentation-dilemma.svg&quot; /&gt; &lt;/div&gt;  &lt;div&gt; &lt;img style=&quot;border: 0px; margin-top: 10px; margin-bottom: 24px&quot; src=&quot;http://www.davidpeterson.co.uk/image/agile/agile-manifesto-contract-dilemma.svg&quot; /&gt; &lt;/div&gt;  &lt;div&gt; &lt;img style=&quot;border: 0px; margin-top: 10px; margin-bottom: 24px&quot; src=&quot;http://www.davidpeterson.co.uk/image/agile/agile-manifesto-planning-dilemma.svg&quot; /&gt; &lt;/div&gt;  &lt;p style=&quot;margin-top: 24px; font-size: 12pt; font-weight: bold&quot;&gt;So what &lt;em&gt;is&lt;/em&gt; agile then?&lt;/p&gt;  &lt;p&gt; I&#39;m not sure. Please can you give me feedback on this post and your ideas. Leave a comment, or blog about it, or tweet&amp;#160;me&amp;#160;(&lt;a href=&quot;http://twitter.com/davidp99&quot;&gt;@davidp99&lt;/a&gt;). Thanks. &lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.davidpeterson.co.uk/feeds/4765628186375558285/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3933266989882835478&amp;postID=4765628186375558285' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3933266989882835478/posts/default/4765628186375558285'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3933266989882835478/posts/default/4765628186375558285'/><link rel='alternate' type='text/html' href='http://blog.davidpeterson.co.uk/2011/01/whats-wrong-with-agile-manifesto.html' title='What&#39;s wrong with the Agile Manifesto?'/><author><name>David Peterson</name><uri>http://www.blogger.com/profile/03475136061061572446</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3933266989882835478.post-7946254873647903757</id><published>2011-01-11T14:18:00.022+00:00</published><updated>2012-07-05T08:51:37.045+01:00</updated><title type='text'>FlowChain - Ideal company structure?</title><content type='html'>&lt;blockquote style=&quot;font-family: Times New Roman, Times, Serif; font-style: italic; font-size: 12pt&quot;&gt;&quot;If you could start from a clean slate, how would you structure a large company?&quot;&lt;/blockquote&gt;&lt;p&gt;A little Twitter conversation with Simon Baker (@energizr) about &lt;a href=&quot;http://www.energizedwork.com/weblog/2009/10/product-stream&quot;&gt;product streams&lt;/a&gt;, reminded me of a talk at last July&#39;s &lt;a href=&quot;http://www.agilecoachesgathering.org&quot;&gt;Agile Coaches Gathering&lt;/a&gt;, where &lt;a href=&quot;http://www.fallingblossoms.com/&quot;&gt;Bob Marshall&lt;/a&gt; (@flowchainsensei) answered the question above by describing his &quot;FlowChain&quot; concept.&lt;/p&gt;&lt;p&gt;This is my interpretation of what he said (from memory) so it may not be quite right and he&#39;s probably refined it since then.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Running the whole company in an &quot;agile&quot; way&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Essentially FlowChain scales agile practices up to the company level. There is a single (large) development team that works from a prioritised backlog of MMFs (Minimal Marketable Features). I&#39;m not sure who manages the backlog. I&#39;ve called it a &quot;product strategist&quot;, but that&#39;s my name for it not Bob&#39;s.&lt;/p&gt;&lt;p&gt;The team works on multiple value streams. Each value stream has its own operations staff.&lt;/p&gt;&lt;div&gt;&lt;img style=&quot;border: 0px; margin-top: 16px; margin-bottom: 16px&quot; src=&quot;http://www.davidpeterson.co.uk/image/agile/flowchain.svg&quot; /&gt;&lt;/div&gt;&lt;p&gt;Zooming in:&lt;/p&gt;&lt;div&gt;&lt;img style=&quot;border: 0px; margin-top: 16px; margin-bottom: 16px&quot; src=&quot;http://www.davidpeterson.co.uk/image/agile/flowchain-magnified.svg&quot; /&gt;&lt;/div&gt;&lt;p&gt;&lt;b&gt;Extreme flexibility&lt;/b&gt;&lt;/p&gt;&lt;p&gt;What I like about FlowChain is the flexibility it provides. If a value stream is doing well, resources can quickly be redeployed to capitalise on its success. Alternatively, new products (value streams) can be developed. In most organisations, moving developers from one project to another is a major upheaval, and that puts pressure on the project to be a success. When you can move developers quickly to something else, it relieves the pressure and allows the company to tackle more risky (but potentially more lucrative) opportunities.&lt;/p&gt;&lt;p&gt;Note that in a large company, the pool of resources for developing products could be very large, and there may therefore be many MMFs in progress at the same time. Bob didn&#39;t explain how to resolve resource conflicts, sequencing etc. We may have to wait for his book...&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.davidpeterson.co.uk/feeds/7946254873647903757/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3933266989882835478&amp;postID=7946254873647903757' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3933266989882835478/posts/default/7946254873647903757'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3933266989882835478/posts/default/7946254873647903757'/><link rel='alternate' type='text/html' href='http://blog.davidpeterson.co.uk/2011/01/flow-chain-ideal-company-structure.html' title='FlowChain - Ideal company structure?'/><author><name>David Peterson</name><uri>http://www.blogger.com/profile/03475136061061572446</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3933266989882835478.post-895909953636867483</id><published>2011-01-11T10:16:00.005+00:00</published><updated>2012-07-05T10:45:01.162+01:00</updated><title type='text'>Prototypes, Spikes and Tracer Bullets</title><content type='html'>&lt;p&gt;Here&#39;s an attempt to classify various development techniques and the sequence in which they tend to be used.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img style=&quot;border: 0px&quot; src=&quot;http://www.davidpeterson.co.uk/image/agile/2x2-tracer-bullet.svg&quot; /&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.davidpeterson.co.uk/feeds/895909953636867483/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3933266989882835478&amp;postID=895909953636867483' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3933266989882835478/posts/default/895909953636867483'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3933266989882835478/posts/default/895909953636867483'/><link rel='alternate' type='text/html' href='http://blog.davidpeterson.co.uk/2011/01/prototypes-spikes-and-tracer-bullets.html' title='Prototypes, Spikes and Tracer Bullets'/><author><name>David Peterson</name><uri>http://www.blogger.com/profile/03475136061061572446</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3933266989882835478.post-4343786129904824112</id><published>2011-01-10T10:10:00.005+00:00</published><updated>2011-01-21T14:55:48.076+00:00</updated><title type='text'>Don&#39;t kid yourself</title><content type='html'>&lt;blockquote style=&quot;font-size: 12pt; font-style: italic; font-family: Times New Roman, Times Serif;&quot;&gt;&quot;Our team&#39;s agile, but we haven&#39;t released yet because some of the teams we depend on aren&#39;t agile.&quot;&lt;/blockquote&gt;&lt;p&gt;Fine, then you&#39;re &lt;em&gt;not&lt;/em&gt; agile!&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.davidpeterson.co.uk/feeds/4343786129904824112/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3933266989882835478&amp;postID=4343786129904824112' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3933266989882835478/posts/default/4343786129904824112'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3933266989882835478/posts/default/4343786129904824112'/><link rel='alternate' type='text/html' href='http://blog.davidpeterson.co.uk/2011/01/dont-kid-yourself.html' title='Don&#39;t kid yourself'/><author><name>David Peterson</name><uri>http://www.blogger.com/profile/03475136061061572446</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3933266989882835478.post-8687774876656352667</id><published>2011-01-09T10:15:00.011+00:00</published><updated>2011-01-09T12:10:37.897+00:00</updated><title type='text'>BDD: Concrete Examples Aren&#39;t Enough</title><content type='html'>&lt;p&gt; The Given/When/Then style of Behaviour Driven Development (BDD), favoured by Cucumber and JBehave, puts a lot of context in the examples that &lt;a href=&quot;http://blog.davidpeterson.co.uk/2010/09/refactoring-givenwhenthen.html&quot;&gt;I claimed was unnecessary clutter&lt;/a&gt;, but I had quite a few comments that puzzled me until it dawned on me there&#39;s another difference in my approach compared with the Given/When/Then style. &lt;/p&gt;  &lt;p&gt; I always state the required behaviour in a sentence or two before giving the examples. Each behaviour is described by a specification like this: &lt;/p&gt;  &lt;div&gt; &lt;img style=&quot;border: 0px; margin: 6px 0px 6px 40px;&quot; src=&quot;http://www.davidpeterson.co.uk/image/agile/anatomy-spec.png&quot; /&gt; &lt;/div&gt;  &lt;p&gt; Maybe it looks like a lot of work to write, but it isn&#39;t really. The structure is standard and each part is just a sentence or two. &lt;/p&gt;  &lt;p&gt; Whereas in the Given/When/Then approach the business rule describing the behaviour generally isn&#39;t made explicit. The reader is expected to guess the rule from the examples, so naturally they have to have more context. &lt;/p&gt;  &lt;div&gt; &lt;img style=&quot;border: 0px; margin: 6px 0px 6px 40px;&quot; src=&quot;http://www.davidpeterson.co.uk/image/agile/given-when-then.png&quot; /&gt; &lt;/div&gt;   &lt;p&gt; Occasionally it&#39;s difficult for the domain expert to immediately state the abstract rule and easier to start with concrete examples, but once the expert has explained a few examples then we can usually begin to take an educated guess at the rules behind them&amp;#8212;&quot;Ah OK, so the rule is X?&quot;&amp;#8212;and then have a useful discussion. &lt;/p&gt;  &lt;p&gt; But if we don&#39;t make the rule explicit we only have the concrete examples, so they have to be made much more verbose&amp;#8212;and potentially implementation-specific&amp;#8212;so that readers can correctly interpret them. &lt;/p&gt; &lt;p&gt;It is true that Given/When/Then style examples are much better at avoiding implementation lock-in than test scripting (&quot;click this, click that...&quot;), but I would argue that context-free examples with explicitly stated rules are even better, both in terms of avoiding lock-in and in terms of readability (how long it takes the reader to understand the behaviour expected).&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.davidpeterson.co.uk/feeds/8687774876656352667/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3933266989882835478&amp;postID=8687774876656352667' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3933266989882835478/posts/default/8687774876656352667'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3933266989882835478/posts/default/8687774876656352667'/><link rel='alternate' type='text/html' href='http://blog.davidpeterson.co.uk/2011/01/bdd-concrete-examples-arent-enough.html' title='BDD: Concrete Examples Aren&#39;t Enough'/><author><name>David Peterson</name><uri>http://www.blogger.com/profile/03475136061061572446</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3933266989882835478.post-1075210676823645971</id><published>2011-01-07T22:43:00.017+00:00</published><updated>2011-01-13T13:05:56.617+00:00</updated><title type='text'>Object-Oriented Example</title><content type='html'>&lt;p&gt; For ages I treated objects as glorified data structures to be operated on by procedural code. It took me a long time to get out of the procedural mindset and into an object-oriented mindset.&lt;/p&gt; &lt;p&gt; Well-written object-oriented code helps you deal with complexity by hiding internal details so that you can operate at ever higher levels of abstraction. Object-oriented code increases flexibility &amp;#8211; objects can be plugged together in different ways like Lego&amp;trade; pieces &amp;#8211; and it keeps duplication and churn to a minimum by keeping data and operations in the same place instead of spreading them throughout the code-base. &lt;/p&gt; &lt;p&gt; The recent discussion on the &lt;a href=&quot;http://groups.google.com/group/growing-object-oriented-software&quot;&gt;GOOS mailing list&lt;/a&gt; has made me realise that others are also struggling with the transition. Nat Pryce has posted a &lt;a href=&quot;http://www.natpryce.com/articles/000783.html&quot;&gt;couple of blog entries&lt;/a&gt; today, and I&#39;d like to pick up the same theme with an example in the hope it might help. &lt;/p&gt;  &lt;p&gt; Let&#39;s start with a simple PopGroup class that implements the role of SongPerformer (in Java this would be an interface): &lt;/p&gt;  &lt;div style=&quot;margin: 24px 24px 24px 64px;&quot;&gt; &lt;img style=&quot;border: 0px;&quot; src=&quot;http://www.davidpeterson.co.uk/image/oo/pop-group.png&quot; /&gt; &lt;/div&gt;  &lt;p&gt; To construct a valid PopGroup you need a Singer, a Drummer and a Keyboardist. These are the PopGroup&#39;s &lt;em&gt;dependencies&lt;/em&gt;. &lt;/p&gt;  &lt;div style=&quot;margin: 24px;&quot;&gt; &lt;img style=&quot;border: 0px;&quot; src=&quot;http://www.davidpeterson.co.uk/image/oo/pop-group-needs-dependencies.png&quot; /&gt; &lt;/div&gt;  &lt;p&gt; The responsibility for coordinating the various activities to perform songs is the responsibility of the PopGroup object, but the actual acts of singing, drumming and keyboard playing are separated out. This is the &lt;em&gt;single responsibility principle&lt;/em&gt; combined with &lt;em&gt;dependency injection&lt;/em&gt;. &lt;/p&gt;  &lt;p&gt; This approach makes the design highly flexible because we can plug together all kinds of variations. As long as the dependencies we inject implement the right interfaces we can make the pop group perform a song. &lt;/p&gt;  &lt;p&gt; For example: &lt;/p&gt;  &lt;div style=&quot;margin: 24px;&quot;&gt; &lt;img style=&quot;border: 0px;&quot; src=&quot;http://www.davidpeterson.co.uk/image/oo/pop-group-with-dependencies.png&quot; /&gt; &lt;/div&gt;  &lt;p&gt; If we don&#39;t have a DrumMachine, we can substitute a PhysicalDrummer and the PopGroup will still function the same. &lt;/p&gt;  &lt;div style=&quot;margin: 24px;&quot;&gt; &lt;img style=&quot;border: 0px;&quot; src=&quot;http://www.davidpeterson.co.uk/image/oo/physical-drummer.png&quot; /&gt; &lt;/div&gt;  &lt;p&gt; Our PhysicalDrummer object depends on interfaces not implementations. If we&#39;re desperate we could grab a passer by, a dustbin and a broom handle and create a drummer: &lt;/p&gt;  &lt;div style=&quot;margin: 24px;&quot;&gt; &lt;img style=&quot;border: 0px;&quot; src=&quot;http://www.davidpeterson.co.uk/image/oo/broom-handle-drumstick.png&quot; /&gt; &lt;/div&gt;  &lt;p&gt; Unfortunately the BroomHandle class does not implement the Drumstick interface. We could make it implement Drumstick, but the BroomHandle is in a different domain. It&#39;s in the domain of sweeping, rather than musical performances. We don&#39;t really want to couple its class to an interface from the musical performances domain, so we create an adapter to map between the two. This is known as a &lt;em&gt;ports and adapters architecture&lt;/em&gt;. &lt;/p&gt;  &lt;p&gt; To make things easier to understand we can wrap the objects into a class that has a name that better expresses the intent. &lt;/p&gt;  &lt;div style=&quot;margin: 24px;&quot;&gt; &lt;img style=&quot;border: 0px;&quot; src=&quot;http://www.davidpeterson.co.uk/image/oo/emergency-drummer-exposed.png&quot; /&gt; &lt;/div&gt;  &lt;p&gt; Now we&#39;ve hidden all the complexity and we&#39;re operating at a higher-level of abstraction. &lt;/p&gt;  &lt;div style=&quot;margin: 24px;&quot;&gt; &lt;img style=&quot;border: 0px;&quot; src=&quot;http://www.davidpeterson.co.uk/image/oo/emergency-drummer.png&quot; /&gt; &lt;/div&gt;&lt;p&gt;In reality, a ports and adapters architecture is not so much mapping between entirely unconnected domains as mapping lower-level domains to higher-level domains, so that the technical detail is hidden within simpler more abstract concepts.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.davidpeterson.co.uk/feeds/1075210676823645971/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3933266989882835478&amp;postID=1075210676823645971' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3933266989882835478/posts/default/1075210676823645971'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3933266989882835478/posts/default/1075210676823645971'/><link rel='alternate' type='text/html' href='http://blog.davidpeterson.co.uk/2011/01/object-oriented-example.html' title='Object-Oriented Example'/><author><name>David Peterson</name><uri>http://www.blogger.com/profile/03475136061061572446</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3933266989882835478.post-2710485878704421010</id><published>2011-01-07T10:28:00.009+00:00</published><updated>2011-01-07T13:59:46.551+00:00</updated><title type='text'>Concordion Extensions</title><content type='html'>&lt;p&gt; &lt;a href=&quot;http://tutansblog.blogspot.com/&quot;&gt;Nigel Charman&lt;/a&gt; has started a &lt;a href=&quot;http://code.google.com/p/concordion-extensions/&quot;&gt;concordion-extensions&lt;/a&gt; sub-project that adds some useful extra features to &lt;a href=&quot;http://www.concordion.org&quot;&gt;Concordion&lt;/a&gt;, such as the ability to &lt;a href=&quot;http://www.concordion.org/extensions/ScreenshotExtension.html&quot;&gt;add screenshots to the Concordion output&lt;/a&gt; so you can more clearly see what state the application is in when something fails. &lt;/p&gt;  &lt;p&gt; &lt;a href=&quot;http://www.concordion.org/extensions/LoggingTooltipExtension.html&quot;&gt;Another valuable extension&lt;/a&gt; inserts a little icon into the output and when you hover over it, it shows logging output that occurred during the test. This is a neat solution to a dilemma that I&#39;ve sometimes encountered: &lt;em&gt;&quot;If I don&#39;t write down the steps, how can I be sure the test has been implemented right?&quot;&lt;/em&gt; &lt;/p&gt;  &lt;p&gt; We want to write high-level tests that express the business requirements without reference to a particular implementation, so we can change the implementation later. To do this, we hide the test&#39;s implementation steps in its accompanying Java fixture. But some people aren&#39;t comfortable navigating and reading Java code. If you&#39;re a non-developer tester trying to make sure the system is well-tested, it can be scary to &quot;trust&quot; the developers to implement your tests correctly. &lt;/p&gt;  &lt;p&gt; The temptation is therefore to explicitly write into the test specification the steps required to execute the test. The trouble is by encoding the &quot;how&quot; you end up locking the test into a specific implementation. The lock-in problem is exacerbated by duplication across tests. When you&#39;re detailing all the steps, you find that many tests require a similar set of steps. &lt;/p&gt; &lt;p&gt;Our &lt;a href=&quot;http://en.wikipedia.org/wiki/Evaporating_Cloud&quot;&gt;conflict cloud&lt;/a&gt; looks something like this: &lt;/p&gt; &lt;div&gt; &lt;img style=&quot;border: 0px; margin: 24px;&quot; src=&quot;http://www.davidpeterson.co.uk/image/agile/testing-conflict.png&quot; alt=&quot;Testing Conflict&quot;/&gt; &lt;/div&gt;  &lt;p&gt; Some testing frameworks, such as &lt;a href=&quot;http://code.google.com/p/robotframework/&quot;&gt;Robot&lt;/a&gt; and &lt;a href=&quot;http://fitnesse.org/&quot;&gt;FitNesse&lt;/a&gt;, allow you to pull out common set-up but this is a compromise. Effectively what you&#39;re doing is &lt;em&gt;programming&lt;/em&gt;, but not in a proper programming language. The intentions of your tests become lost amongst increasingly complex interweaved test scripts. &lt;/p&gt;  &lt;p&gt; Nigel&#39;s solution allows you to write the tests in a way that retains a clear separation between intent and implementation, yet allows non-developers to be reassured that the test has been implemented correctly. &lt;/p&gt;  &lt;div&gt; &lt;img style=&quot;border: 0px; margin: 24px;&quot; src=&quot;http://www.davidpeterson.co.uk/image/agile/testing-conflict-resolved.png&quot; alt=&quot;Testing Conflict Resolved&quot;/&gt; &lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.davidpeterson.co.uk/feeds/2710485878704421010/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3933266989882835478&amp;postID=2710485878704421010' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3933266989882835478/posts/default/2710485878704421010'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3933266989882835478/posts/default/2710485878704421010'/><link rel='alternate' type='text/html' href='http://blog.davidpeterson.co.uk/2011/01/concordion-extensions.html' title='Concordion Extensions'/><author><name>David Peterson</name><uri>http://www.blogger.com/profile/03475136061061572446</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3933266989882835478.post-5120486602038441177</id><published>2010-12-03T14:55:00.011+00:00</published><updated>2011-01-14T13:45:25.225+00:00</updated><title type='text'>BCS SPA 2011 Conference</title><content type='html'>&lt;div style=&quot;float: right; padding: 0px 0px 16px 16px;&quot;&gt;&lt;a href=&quot;http://www.spaconference.org/spa2011/&quot;&gt;&lt;img style=&quot;border: 0px&quot; border=&quot;0&quot;  src=&quot;http://www.davidpeterson.co.uk/image/misc/spa-2011-logo.png&quot; alt=&quot;SPA Conference&quot;&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;I&#39;m the newly-elected Chair of the &lt;a href=&quot;http://www.bcs.org&quot;&gt;BCS&lt;/a&gt; &lt;a href=&quot;http://www.bcs-spa.org/index.php&quot;&gt;Software Practice Advancement&lt;/a&gt; group. I&#39;m not sure how it happened, but I&#39;m very excited about it.&lt;/p&gt;&lt;p&gt;Unfortunately, I joined too late to be actively involved in organising the next &lt;a href=&quot;http://www.spaconference.org/spa2011/&quot;&gt;SPA&amp;#160;conference&lt;/a&gt; (London, June 12-15th 2011). That responsibility lies with Ivan Moore and Mike Hill as conference chairs and Willem van den Ende and Rob Bowley as programme chairs. However, I&#39;m definitely going to attend the conference having just snapped up an &lt;a href=&quot;http://www.spaconference.org/spa2011/&quot;&gt;early-bird ticket&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;What I like about the conference is that it&#39;s not oriented around a particular technology or approach, and the attendees tend to be at the expert end of the scale. In my opinion, it&#39;s the best conference having your thoughts challenged. That&#39;s what I want from a conference.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.davidpeterson.co.uk/feeds/5120486602038441177/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3933266989882835478&amp;postID=5120486602038441177' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3933266989882835478/posts/default/5120486602038441177'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3933266989882835478/posts/default/5120486602038441177'/><link rel='alternate' type='text/html' href='http://blog.davidpeterson.co.uk/2010/12/bcs-spa-2011-conference.html' title='BCS SPA 2011 Conference'/><author><name>David Peterson</name><uri>http://www.blogger.com/profile/03475136061061572446</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3933266989882835478.post-212308724153924927</id><published>2010-09-02T16:03:00.029+01:00</published><updated>2011-01-11T21:52:12.053+00:00</updated><title type='text'>Refactoring Given/When/Then</title><content type='html'>&lt;p&gt; I&#39;ve come to the view that Given/When/Then is a poor way to think about scenarios, and is even worse for writing them. It makes me turn even the simplest situations into a ramble. And &lt;a href=&quot;http://antonymarcano.com/blog/2010/08/youre-almost-cuking-it/&quot;&gt;I don&#39;t think it&#39;s just me&lt;/a&gt;. &lt;/p&gt;  &lt;div style=&quot;border: 1px solid black; padding: 8px 20px 8px 20px; margin: 16px; line-spacing: 130%; width: 400px;&quot;&gt; &lt;p&gt; Given a user called Fred &lt;br /&gt;And user Fred is logged in &lt;br /&gt;And user Fred has an empty shopping basket &lt;br /&gt;When Fred adds a $15 screw-driver &lt;br /&gt;And Fred adds a $12 lamp &lt;br /&gt;And Fred adds a $12 lamp &lt;br /&gt;Then the total of Fred&#39;s bill is $39 &lt;/p&gt; &lt;/div&gt;  &lt;p&gt; If I start with Given/When/Then, I end up having to go through a laborious process of simplifying, getting rid of unnecessary details. In our example, above, Fred may be needed behind the scenes but doesn&#39;t add anything useful to the description. &lt;/p&gt;   &lt;div style=&quot;border: 1px solid black; padding: 8px 20px 8px 20px; margin: 16px; line-spacing: 130%; width: 400px;&quot;&gt; &lt;p&gt; Given we are logged in &lt;br /&gt;And we have an empty shopping basket &lt;br /&gt;When we add a $15 screw-driver &lt;br /&gt;And add a $12 lamp &lt;br /&gt;And add a $12 lamp &lt;br /&gt;Then the total bill is $39 &lt;/p&gt; &lt;/div&gt;  &lt;p&gt; Do we need that bit about being logged in? No. Readers will likely assume it and, even if they don&#39;t, who cares anyway? It&#39;s irrelevant to what I&#39;m trying to explain. &lt;/p&gt;  &lt;p&gt; My rule of thumb is: if the context is unexpected (e.g. we&#39;re trying to explain what happens when you &lt;em&gt;aren&#39;t&lt;/em&gt; logged in) then we need to mention it, but if the context can be inferred from the other parts of the scenario, or from common sense, then leave it out. There&#39;s a feeling that adding context will remove ambiguity, but all it actually does is complicate the example. &lt;/p&gt;  &lt;div style=&quot;border: 1px solid black; padding: 8px 20px 8px 20px; margin: 16px; line-spacing: 130%; width: 400px;&quot;&gt; &lt;p&gt; Given we have an empty shopping basket &lt;br /&gt;When we add a $15 screw-driver &lt;br /&gt;And add a $12 lamp &lt;br /&gt;And add a $12 lamp &lt;br /&gt;Then the total bill is $39 &lt;/p&gt; &lt;/div&gt;  &lt;p&gt; Are the words &quot;screw-driver&quot; and &quot;lamp&quot; necessary? I think they are. If we removed those words and just had the prices, the example would be harder to understand. You need something to show that the prices represent items. Using more abstract labels (e.g. &quot;item A&quot;, &quot;item B&quot;) is a possibility, but doesn&#39;t seem to buy us much. &lt;/p&gt;  &lt;p&gt; What about the &quot;empty shopping basket&quot;? Can that be reasonably assumed? Yes, but rather than starting with an empty shopping basket, how about starting with a full one and dropping the &quot;when&quot; part?&lt;/p&gt;  &lt;div style=&quot;border: 1px solid black; padding: 8px 20px 8px 20px; margin: 16px; line-spacing: 130%; width: 400px;&quot;&gt; &lt;p&gt; Given a basket containing a $15 screw-driver &lt;br /&gt;And a $12 lamp &lt;br /&gt;And a $12 lamp &lt;br /&gt;Then the total bill is $39 &lt;/p&gt; &lt;/div&gt;  &lt;p&gt; Finally let&#39;s remove the duplication. &lt;/p&gt;  &lt;div style=&quot;border: 1px solid black; padding: 8px 20px 8px 20px; margin: 16px; line-spacing: 130%; width: 400px;&quot;&gt; &lt;p&gt; Given a basket containing a $15 screw-driver &lt;br /&gt;And 2 x $12 lamp &lt;br /&gt;Then the total bill is $39 &lt;/p&gt; &lt;/div&gt;  &lt;p&gt; OK, this doesn&#39;t suck as much as what I started with. &lt;/p&gt; &lt;p&gt; But why not just write this: &lt;/p&gt;  &lt;div style=&quot;border: 1px solid black; padding: 8px 20px 8px 20px; margin: 16px; line-spacing: 130%; width: 400px;&quot;&gt; &lt;p&gt; 1 x $15 screw-driver &lt;br /&gt;2 x $12 lamp &lt;/p&gt;  &lt;p&gt; Total bill = $39 &lt;/p&gt; &lt;/div&gt;  &lt;p&gt; This is what I might write on the back of an envelope if I were giving an example to somebody. With the right tools (e.g. &lt;a href=&quot;http://www.concordion.org&quot;&gt;Concordion&lt;/a&gt;), I can code it up exactly as I just wrote it. I don&#39;t &lt;em&gt;need&lt;/em&gt; to use Given/When/Then. I used to think it was a good way to structure the example, but I&#39;ve changed my mind.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.davidpeterson.co.uk/feeds/212308724153924927/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3933266989882835478&amp;postID=212308724153924927' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3933266989882835478/posts/default/212308724153924927'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3933266989882835478/posts/default/212308724153924927'/><link rel='alternate' type='text/html' href='http://blog.davidpeterson.co.uk/2010/09/refactoring-givenwhenthen.html' title='Refactoring Given/When/Then'/><author><name>David Peterson</name><uri>http://www.blogger.com/profile/03475136061061572446</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3933266989882835478.post-9133885114089722547</id><published>2010-03-02T14:23:00.000+00:00</published><updated>2010-03-02T14:24:46.290+00:00</updated><title type='text'>Growing Object-Oriented Software, Guided by Tests</title><content type='html'>&lt;div style=&quot;float: right; margin-left: 24px;&quot;&gt; &lt;a href=&quot;http://www.amazon.co.uk/gp/product/0321503627?ie=UTF8&amp;tag=davidpeterson-21&amp;linkCode=as2&amp;camp=1634&amp;creative=19450&amp;creativeASIN=0321503627&quot;&gt;&lt;img border=&quot;0&quot; style=&quot;border:none !important; margin:0px !important;&quot; src=&quot;http://www.davidpeterson.co.uk/image/misc/growing-oo-software.jpg&quot;/&gt;&lt;/a&gt; &lt;/div&gt;   &lt;p&gt; Almost every programming book I&#39;ve read has irritated me. I get irritated easily (I don&#39;t get enough sleep), but Java books are the worst because Java&#39;s the language I use most and know best.   I still read them because there are usually a few good ideas buried inside, but it irritates me that I have to wade through so much tosh. &lt;/p&gt;  &lt;p&gt; So far, &lt;a href=&quot;http://www.amazon.co.uk/gp/product/0321503627?ie=UTF8&amp;tag=davidpeterson-21&amp;linkCode=as2&amp;camp=1634&amp;creative=19450&amp;creativeASIN=0321503627&quot;&gt;Growing Object-Oriented Software, Guided by Tests&lt;/a&gt; is the only exception. There&#39;s no tosh. It&#39;s incredible. I&#39;ve read the book two or three times and each time I felt myself becoming a better programmer. If you haven&#39;t read it yet, I can&#39;t recommend it enough. &lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.davidpeterson.co.uk/feeds/9133885114089722547/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3933266989882835478&amp;postID=9133885114089722547' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3933266989882835478/posts/default/9133885114089722547'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3933266989882835478/posts/default/9133885114089722547'/><link rel='alternate' type='text/html' href='http://blog.davidpeterson.co.uk/2010/03/growing-object-oriented-software-guided.html' title='Growing Object-Oriented Software, Guided by Tests'/><author><name>David Peterson</name><uri>http://www.blogger.com/profile/03475136061061572446</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3933266989882835478.post-8120805881022321781</id><published>2009-10-14T08:19:00.005+01:00</published><updated>2009-10-14T08:31:46.236+01:00</updated><title type='text'>Kanban Blog</title><content type='html'>&lt;p&gt;Having leapt aboard the Kanbandwagon, I&#39;ve started a new blog about Kanban at, funnily enough, &lt;a href=&quot;http://www.kanbanblog.com&quot;&gt;kanbanblog.com&lt;/a&gt;. Here&#39;s a taster of my first post:&lt;/p&gt;  &lt;p&gt; Which of these feature ideas should we select as a priority? &lt;/p&gt;  &lt;table style=&quot;border-collapse: collapse; border: 1px solid black&quot; cellpadding=&quot;4px&quot;&gt; &lt;tr&gt; &lt;th align=&quot;center&quot; style=&quot;border: 1px solid black; background-color: #ccc&quot;&gt;Feature&lt;/th&gt; &lt;th align=&quot;center&quot; style=&quot;border: 1px solid black; background-color: #ccc&quot;&gt;Estimated&lt;br /&gt;Value&lt;/th&gt; &lt;th align=&quot;center&quot; style=&quot;border: 1px solid black; background-color: #ccc&quot;&gt;Estimated&lt;br /&gt;Production Time&lt;/th&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td align=&quot;center&quot; style=&quot;border-right: 1px solid black;&quot;&gt;A&lt;/td&gt; &lt;td align=&quot;right&quot; style=&quot;border-right: 1px solid black;&quot;&gt;$100,000&lt;/td&gt; &lt;td align=&quot;center&quot;&gt;40 hrs&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td align=&quot;center&quot;  style=&quot;border-right: 1px solid black;&quot;&gt;B&lt;/td&gt; &lt;td align=&quot;right&quot; style=&quot;border-right: 1px solid black;&quot;&gt;$80,000&lt;/td&gt; &lt;td align=&quot;center&quot;&gt;40 hrs&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td align=&quot;center&quot; style=&quot;border-right: 1px solid black;&quot;&gt;C&lt;/td&gt; &lt;td align=&quot;right&quot; style=&quot;border-right: 1px solid black;&quot;&gt;$60,000&lt;/td&gt; &lt;td align=&quot;center&quot;&gt;40 hrs&lt;/td&gt; &lt;/tr&gt; &lt;/table&gt; &lt;br /&gt; &lt;p&gt; Feature A? It&#39;s a no-brainer, right? &lt;/p&gt;  &lt;p&gt; &lt;a href=&quot;http://www.kanbanblog.com/article/time-at-bottleneck.html&quot;&gt;Not necessarily&lt;/a&gt;... &lt;/p&gt;&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.davidpeterson.co.uk/feeds/8120805881022321781/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3933266989882835478&amp;postID=8120805881022321781' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3933266989882835478/posts/default/8120805881022321781'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3933266989882835478/posts/default/8120805881022321781'/><link rel='alternate' type='text/html' href='http://blog.davidpeterson.co.uk/2009/10/kanban-blog.html' title='Kanban Blog'/><author><name>David Peterson</name><uri>http://www.blogger.com/profile/03475136061061572446</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3933266989882835478.post-3470993298697054093</id><published>2009-05-25T18:57:00.013+01:00</published><updated>2009-05-26T08:37:06.728+01:00</updated><title type='text'>Concordion 1.3.1</title><content type='html'>&lt;p&gt;Concordion 1.3.1 was released last month with a handful of &lt;a href=&quot;http://www.concordion.org/Download.html&quot;&gt;new and noteworthy features&lt;/a&gt;. There was an announcement on the Yahoo mailing list, but I wanted to wait for the Concordion.NET port to catch up before making an announcement on this blog.&lt;/p&gt;&lt;p&gt;For those who didn&#39;t know, there are now &lt;a href=&quot;http://www.concordion.org/Ports.html&quot;&gt;versions of Concordion&lt;/a&gt; for:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Java&lt;/b&gt; (&lt;a href=&quot;http://www.concordion.org&quot;&gt;Concordion&lt;/a&gt;)&lt;/li&gt;&lt;li&gt;&lt;b&gt;.NET&lt;/b&gt; (&lt;a href=&quot;http://code.google.com/p/concordion-net/&quot;&gt;Concordion.NET&lt;/a&gt;) by Jeffrey Cameron&lt;/li&gt;&lt;li&gt;&lt;b&gt;Python&lt;/b&gt; (&lt;a href=&quot;http://code.google.com/p/pyconcordion/&quot;&gt;PyConcordion&lt;/a&gt;) by JC Plessis&lt;/li&gt;&lt;li&gt;&lt;b&gt;Ruby&lt;/b&gt; (&lt;a href=&quot;http://ruby-concordion.rubyforge.org/&quot;&gt;ruby-concordion&lt;/a&gt;) by Ben Goodspeed, Ariel Valentin and Chris Gardner&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;So, if you&#39;re using Cucumber in Ruby, or FitNesse in .NET check out the alternative. No other acceptance testing framework lets you create such readable acceptance tests as Concordion&#39;s. The key advantage in having readable tests is that when you come back in three months time and wonder what the heck you were doing, you might actually have a clue.&lt;/p&gt;&lt;div style=&quot;background-color: #fffff7; padding: 8px;&quot;&gt;&lt;b&gt;Update:&lt;/b&gt; Jeffrey Cameron has started a &lt;a href=&quot;http://living-in-concordion.blogspot.com/&quot;&gt;blog about Concordion.NET&lt;/a&gt; and how to use it.&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.davidpeterson.co.uk/feeds/3470993298697054093/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3933266989882835478&amp;postID=3470993298697054093' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3933266989882835478/posts/default/3470993298697054093'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3933266989882835478/posts/default/3470993298697054093'/><link rel='alternate' type='text/html' href='http://blog.davidpeterson.co.uk/2009/05/concordion-131.html' title='Concordion 1.3.1'/><author><name>David Peterson</name><uri>http://www.blogger.com/profile/03475136061061572446</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3933266989882835478.post-6999702038716982148</id><published>2009-02-19T11:11:00.006+00:00</published><updated>2009-02-19T17:36:07.297+00:00</updated><title type='text'>Avoid not using positive method names</title><content type='html'>&lt;p&gt;I&#39;m integrating with &lt;a href=&quot;http://static.springsource.org/spring-security/site/index.html&quot;&gt;Spring Security&lt;/a&gt; at the moment. It seems to be a well-designed framework, but I got myself confused this morning trying to implement some methods of the &lt;a href=&quot;http://static.springsource.org/spring-security/site/apidocs/org/springframework/security/userdetails/UserDetails.html&quot;&gt;UserDetails&lt;/a&gt; interface:&lt;/p&gt;&lt;p style=&quot;padding: 8px 16px 8px 16px; background-color: #f7f7f7; line-height: 130%;&quot;&gt;&lt;code style=&quot;font-size: 10pt&quot;&gt;boolean &lt;b&gt;isAccountNonExpired()&lt;/b&gt;&lt;/code&gt;&lt;br/&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;Indicates whether the user&#39;s account has expired.&lt;br/&gt;&lt;code style=&quot;font-size: 10pt&quot;&gt;boolean &lt;b&gt;isAccountNonLocked()&lt;/b&gt;&lt;/code&gt;&lt;br/&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;Indicates whether the user is locked or unlocked.&lt;br/&gt;&lt;code style=&quot;font-size: 10pt&quot;&gt;boolean &lt;b&gt;isCredentialsNonExpired()&lt;/b&gt;&lt;/code&gt;&lt;br/&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;Indicates whether the user&#39;s credentials (password) has expired.&lt;br/&gt;&lt;code style=&quot;font-size: 10pt&quot;&gt;boolean &lt;b&gt;isEnabled()&lt;/b&gt;&lt;/code&gt;&lt;br/&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;Indicates whether the user is enabled or disabled.&lt;/p&gt;&lt;p&gt;I imagine the designers wanted all the answers to be &lt;code style=&quot;font-size: 10pt&quot;&gt;&lt;b&gt;true&lt;/b&gt;&lt;/code&gt; for the normal &quot;happy&quot; situation. But my brain couldn&#39;t cope with all the negatives, so I ended up writing a second set of positively-named methods to call from the negative ones. :-)&lt;/p&gt;&lt;pre style=&quot;font-size: 10pt; padding: 8px 16px 8px 16px; background-color: #f7f7f7;&quot;&gt;&lt;b&gt;public boolean&lt;/b&gt; isAccountNonExpired() {&lt;br /&gt;    &lt;b&gt;return&lt;/b&gt; !isAccountExpired();&lt;br /&gt;}&lt;br /&gt;... etc.&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.davidpeterson.co.uk/feeds/6999702038716982148/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3933266989882835478&amp;postID=6999702038716982148' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3933266989882835478/posts/default/6999702038716982148'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3933266989882835478/posts/default/6999702038716982148'/><link rel='alternate' type='text/html' href='http://blog.davidpeterson.co.uk/2009/02/avoid-not-using-positive-method-names.html' title='Avoid not using positive method names'/><author><name>David Peterson</name><uri>http://www.blogger.com/profile/03475136061061572446</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3933266989882835478.post-5445682949828859455</id><published>2008-10-14T18:06:00.027+01:00</published><updated>2008-10-29T16:26:55.247+00:00</updated><title type='text'>Label verbose items to simplify back-references</title><content type='html'>This is quite an obvious little pattern, but I think it&#39;s still worth documenting.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Some repetition is harmless&lt;/b&gt;&lt;br /&gt;When I&#39;m writing an example of a required behaviour, I find that I often have to refer to something I&#39;ve already mentioned. For example:&lt;br /&gt;&lt;blockquote style=&quot;background-color: #d9ffd9; padding: 12px; background-image: url(&#39;http://www.concordion.org/image/technique/Good.png&#39;); background-repeat: no-repeat; background-position: top right;&quot;&gt;Given the following names: &lt;b&gt;Charles, Naomi, Melissa, Arnold&lt;/b&gt;&lt;br /&gt;Searching for &#39;&lt;b&gt;ar&lt;/b&gt;&#39; should find: &lt;b&gt;Charles, Arnold&lt;/b&gt;&lt;/blockquote&gt;&lt;p&gt;Here, I have mentioned the names Charles and Arnold twice: once when describing the context and once when describing the expected outcome. This isn&#39;t a problem because I purposely kept the names short to make the example easy to follow.&lt;/p&gt;&lt;p&gt;&lt;b&gt;But repetition can become awkward&lt;/b&gt;&lt;br /&gt;If the values are long or complicated then the examples can become hard to read and maintain. For example:&lt;/p&gt;&lt;blockquote style=&quot;background-color: #ffd9d9; padding: 12px; background-image: url(&#39;http://www.concordion.org/image/technique/Bad.png&#39;); background-repeat: no-repeat; background-position: top right;&quot;&gt;Given the following addresses:&lt;blockquote&gt;18 Cedar Row, Enfield, Middx, EN8 9TT&lt;br /&gt;&quot;The Grange&quot;, 177 Hounslow Road, Epping, Essex, HA10 4PL&lt;br /&gt;2b Armsfield Avenue, London, SE1 2BN&lt;br /&gt;80 Commercial Street, Aberdeen, AR19 1TB&lt;/blockquote&gt;Searching for &#39;&lt;b&gt;ar&lt;/b&gt;&#39; should find:&lt;blockquote&gt;18 Cedar Row, Enfield, Middx, EN8 9TT&lt;br /&gt;2b Armsfield Avenue, London, SE1 2BN&lt;br /&gt;80 Commercial Street, Aberdeen, AR19 1TB&lt;/blockquote&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;b&gt;So, use labels for verbose values&lt;/b&gt;&lt;br /&gt;Labelling each item allows you to use the label, instead of the value, whenever you need to refer to it.&lt;/p&gt;&lt;blockquote style=&quot;background-color: #d9ffd9; padding: 12px; background-image: url(&#39;http://www.concordion.org/image/technique/Good.png&#39;); background-repeat: no-repeat; background-position: top right;&quot;&gt;Given the following addresses:&lt;blockquote&gt;&lt;b&gt;(1)&lt;/b&gt; 18 Cedar Row, Enfield, Middx, EN8 9TT&lt;br /&gt;&lt;b&gt;(2)&lt;/b&gt; &quot;The Grange&quot;, 177 Hounslow Road, Epping, Essex, HA10 4PL&lt;br /&gt;&lt;b&gt;(3)&lt;/b&gt; 2b Armsfield Avenue, London, SE1 2BN&lt;br /&gt;&lt;b&gt;(4)&lt;/b&gt; 80 Commercial Street, Aberdeen, AR19 1TB&lt;/blockquote&gt;Searching for &#39;&lt;b&gt;ar&lt;/b&gt;&#39; should match addresses: &lt;b&gt;(1), (3), and (4)&lt;/b&gt;&lt;/blockquote&gt;&lt;p&gt;I call them &lt;i&gt;labels&lt;/i&gt; or &lt;i&gt;pseudo-identifiers&lt;/i&gt; to distinguish them from real identifiers in the system under test. For example, in the implementation we might have a database table called &lt;code style=&quot;font-size: 10pt&quot;&gt;Address&lt;/code&gt; with an identifier column called &lt;code style=&quot;font-size: 10pt&quot;&gt;addressId&lt;/code&gt;. But the identifiers we use in the examples are merely a way of making the example easier to read. They are not a reflection of any particular database model. Any mapping between real identifiers and pseudo-identifiers must always be handled behind the scenes in the fixture code.&lt;/p&gt;&lt;p&gt;The labels don&#39;t have to be numeric. They could be letters (A, B, C) or other more meaningful short strings.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Labels can also help you to hide details&lt;/b&gt;&lt;br /&gt;Another advantage of labels is that they can let you gloss over unnecessary details. For example:&lt;/p&gt;&lt;img src=&quot;http://www.davidpeterson.co.uk/image/misc/acceptance-test-pseudo-identifiers.png&quot; style=&quot;border: 0px&quot; alt=&quot;Example acceptance test showing use of pseudo-identifiers&quot; /&gt;&lt;p&gt;Using labels for bookings (1, 2) and for booking references (A, B) means we don&#39;t need to go into any details of what we&#39;re booking or what the booking references look like. If the format of the booking references is important, we can cover that in another test, but, in this test, we&#39;re not locking ourselves into any particular format. All we&#39;re doing is demonstrating the rule: &quot;Each booking is given a unique booking reference that can be used to look-up the booking.&quot;&lt;/p&gt;&lt;p&gt;The fixture code will have the following methods:&lt;/p&gt;&lt;pre style=&quot;font-size: 10pt; background-color: #f7f7f7;&quot;&gt;&lt;br /&gt;&lt;b style=&quot;color: #7f0055&quot;&gt;public class&lt;/b&gt; IdentifyingBookingsTest &lt;b style=&quot;color: #7f0055&quot;&gt;extends&lt;/b&gt; ConcordionTestCase {&lt;br /&gt;&lt;br /&gt;    &lt;b style=&quot;color: #7f0055&quot;&gt;public void&lt;/b&gt; makeBooking(String bookingNumber, String bookingRefAlias) {&lt;br /&gt;        ...&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;b style=&quot;color: #7f0055&quot;&gt;public&lt;/b&gt; String lookupBooking(String bookingRefAlias) {&lt;br /&gt;        ...&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Having this extra level of indirection may make the fixture code work harder, but that is not a problem. It is much better to put complexity and implementation-related assumptions in the fixture code, where we have powerful refactoring tools at our disposal, than to complicate the specification and make it more fragile.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.davidpeterson.co.uk/feeds/5445682949828859455/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3933266989882835478&amp;postID=5445682949828859455' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3933266989882835478/posts/default/5445682949828859455'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3933266989882835478/posts/default/5445682949828859455'/><link rel='alternate' type='text/html' href='http://blog.davidpeterson.co.uk/2008/10/acceptance-testing-pattern-pseudo.html' title='Label verbose items to simplify back-references'/><author><name>David Peterson</name><uri>http://www.blogger.com/profile/03475136061061572446</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry></feed>