<?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: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-14303091</id><updated>2011-09-02T14:51:40.720+01:00</updated><title type='text'>Digital Compulsion</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://digital-compulsion.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14303091/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://digital-compulsion.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Stacy Curl</name><uri>http://www.blogger.com/profile/01599842149600715942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>10</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-14303091.post-1263500008185832184</id><published>2010-06-04T07:31:00.014+01:00</published><updated>2010-06-05T00:31:59.703+01:00</updated><title type='text'>Function closures can encapsulate better than objects</title><content type='html'>I was surprised to discover recently that a function closure can encapsulate code better than an object. Suppose I have the follow classes:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  public interface Car {&lt;br /&gt;    void Drive();&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;  public class CheapCar : Car {&lt;br /&gt;    public CheapCar(int milesPerGallon, string name) {...}&lt;br /&gt;&lt;br /&gt;    public void Drive() {&lt;br /&gt;      Console.WriteLine("Crawling along...");&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;  public class FastCar : Car {&lt;br /&gt;    public FastCar(double acceleration, string name) {...}&lt;br /&gt;&lt;br /&gt;    public void Drive() {&lt;br /&gt;      Console.WriteLine("Speeding along...");&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now suppose I want to build a DSL for constructing them, I want the usage to look like this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  carFactory.FastCar(0.67).WithName("Speedy");&lt;br /&gt;  carFactory.CheapCar(123).WithName("Efficient");&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;My DSL conveyor-belt will need a few stages, each receiving a parameter, each bundling it up with the parameters acquired thus far and handing over to the next stage or actually building a car:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  public class CarFactory {&lt;br /&gt;    public NameCapturer FastCar(double acceleration) {&lt;br /&gt;      return new FastCarNameCapturer(acceleration);&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    public NameCapturer CheapCar(int milesPerGallon) {&lt;br /&gt;      return new CheapCarNameCapturer(milesPerGallon);&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;  public interface NameCapturer {&lt;br /&gt;    Car WithName(string name);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  &lt;br /&gt;  class FastCarNameCapturer : NameCapturer {&lt;br /&gt;    public FastCarNameCapturer(double acceleration) {...}&lt;br /&gt;    &lt;br /&gt;    public Car WithName(string name) {&lt;br /&gt;      return new FastCar(acceleration, name);&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  &lt;br /&gt;  class CheapCarNameCapturer : NameCapturer {&lt;br /&gt;    public CheapCarNameCapturer(int milesPerGallon) {...}&lt;br /&gt;    &lt;br /&gt;    public Car WithName(string name) {&lt;br /&gt;      return new CheapCar(milesPerGallon, name);&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Because there are two routes to specifying a name and thus two types of possible accumulation parameter there needs to be two NameCapturer implementations. &lt;br /&gt;&lt;br /&gt;Let's see what happens when we accumulate parameters inside a function closure instead of directly inside a capturer object:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  public class NameCapturer {&lt;br /&gt;    public NameCapturer(Func&amp;lt;string, Car&amp;gt; pipeline) {...}&lt;br /&gt;&lt;br /&gt;    public Car WithName(string name) {&lt;br /&gt;      return pipeline(name);&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;  public class CarFactory {&lt;br /&gt;    public NameCapturer FastCar(double acceleration) {&lt;br /&gt;      return new NameCapturer(name =&amp;gt; new FastCar(acceleration, name) as Car);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public NameCapturer CheapCar(int mpg) {&lt;br /&gt;      return new NameCapturer(name =&amp;gt; new CheapCar(mpg, name) as Car);&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The capturer object now provides just the language of the DSL whilst the function closure holds &amp; fully encapsulates both the conversation that's been captured thus far and the final result.&lt;br /&gt;&lt;br /&gt;It's very easy to generalise NameCapturer. Whilst we are at it let's add an age to each type of car and capture this with a generic AgeCapturer, a small helper class to smooth away noise from generics will be handy too.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  public class NameCapturer&amp;lt;T&amp;gt; {&lt;br /&gt;    public NameCapturer(Func&amp;lt;string, T&amp;gt; pipeline) {...}&lt;br /&gt;&lt;br /&gt;    public T WithName(string name) {&lt;br /&gt;      return pipeline(name);&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;  public class AgeCapturer&amp;lt;T&amp;gt; {&lt;br /&gt;    public AgeCapturer(Func&amp;lt;int, T&amp;gt; pipeline) {...}&lt;br /&gt;&lt;br /&gt;    public T WithAge(int age) {&lt;br /&gt;      return pipeline(age);&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;  public class DSLHelper {&lt;br /&gt;    protected AgeCapturer&amp;lt;T&amp;gt; AgeCapturer(Func&amp;lt;int, T&amp;gt; pipeline) {&lt;br /&gt;      return new AgeCapturer&amp;lt;T&amp;gt;(pipeline);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    protected NameCapturer&amp;lt;T&amp;gt; NameCapturer(Func&amp;lt;string, T&amp;gt; pipeline) {&lt;br /&gt;      return new NameCapturer&amp;lt;T&amp;gt;(pipeline);&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;All this stuff could conceivably exist in a 'DSL combinator' library. It's now possible to build a simple DSL for creating cars with just the following code:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  public class CarFactory : DSLHelper {&lt;br /&gt;    public NameCapturer&amp;lt;AgeCapturer&amp;lt;Car&amp;gt;&amp;gt; FastCar(double acceleration) {&lt;br /&gt;      return NameCapturer(name =&amp;gt; AgeCapturer(age =&amp;gt; new FastCar(acceleration, name, age) as Car));&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    public NameCapturer&amp;lt;AgeCapturer&amp;lt;Car&amp;gt;&amp;gt; CheapCar(int mpg) {&lt;br /&gt;      return NameCapturer(name =&amp;gt; AgeCapturer(age =&amp;gt; new CheapCar(mpg, name, age) as Car));&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14303091-1263500008185832184?l=digital-compulsion.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://digital-compulsion.blogspot.com/feeds/1263500008185832184/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14303091&amp;postID=1263500008185832184' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14303091/posts/default/1263500008185832184'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14303091/posts/default/1263500008185832184'/><link rel='alternate' type='text/html' href='http://digital-compulsion.blogspot.com/2010/06/function-closures-can-encapsulate.html' title='Function closures can encapsulate better than objects'/><author><name>Stacy Curl</name><uri>http://www.blogger.com/profile/01599842149600715942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14303091.post-3666856173498643557</id><published>2008-10-07T18:49:00.000+01:00</published><updated>2008-10-07T19:12:44.951+01:00</updated><title type='text'>Our Money Madness (an article by the Mises Institute)</title><content type='html'>I've had an interest in economics for quite a while particularly the writings of &lt;a href="http://en.wikipedia.org/wiki/Ludwig_von_Mises"&gt;Ludwig von Mises&lt;/a&gt; and more generally of the &lt;a href="http://en.wikipedia.org/wiki/Austrian_School"&gt;Austrian School&lt;/a&gt;. This school asserts (and I for one am quite convinced) that the present crisis was predicted by their theories of inflation, fiat currencies and the &lt;a href="http://en.wikipedia.org/wiki/Austrian_Business_Cycle_Theory"&gt;boom-bust business cycle&lt;/a&gt;. I'm no expert so I'd like to hand over to an article on the 'Mises Institude' website:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;&lt;a href="http://mises.org/story/1971"&gt;Our Money Madness&lt;/a&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;We flatter ourselves, in this technological age driven by financial innovation and mind-boggling efficiencies, that we know more than any previous generation. But there is lost knowledge, among which is the knowledge of what sound money feels and looks like, what it does, who makes it and why, and how it holds its value.&lt;br /&gt;So let us revisit Robert Louis Stevenson's classic story, &lt;i&gt;Treasure Island&lt;/i&gt;, and the climactic scene where the pirates and their companions have finally found their treasure and prepare to haul it away. The narrator reports as follows &lt;a href="http://mises.org/story/1971" style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;...&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14303091-3666856173498643557?l=digital-compulsion.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://digital-compulsion.blogspot.com/feeds/3666856173498643557/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14303091&amp;postID=3666856173498643557' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14303091/posts/default/3666856173498643557'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14303091/posts/default/3666856173498643557'/><link rel='alternate' type='text/html' href='http://digital-compulsion.blogspot.com/2008/10/our-money-madness-article-by-mises.html' title='Our Money Madness (an article by the Mises Institute)'/><author><name>Stacy Curl</name><uri>http://www.blogger.com/profile/01599842149600715942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14303091.post-1736992962409382944</id><published>2007-08-29T09:17:00.001+01:00</published><updated>2007-08-29T10:07:15.827+01:00</updated><title type='text'>Example of mutable extension to immutable domain model</title><content type='html'>I must not have communicated the mutable extension idea clearly enough, as I've been accused of breaking the immutability and encapsulation of the domain model which would, I agree, make the domain model sloppy.  I deplore mutability in domain models and anemic / 'behaviourally absent' nonsense such as setters / getters.&lt;br /&gt;&lt;br /&gt;I haven't done either of those things (as far as production code is concerned) here's a worked example which demonstrates this.&lt;br /&gt;&lt;br /&gt;Here's the &lt;b&gt;immutable&lt;/b&gt;, &lt;b&gt;encapsulated&lt;/b&gt;, distinctly &lt;b&gt;unsloppy&lt;/b&gt; domain model:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class Person {&lt;br /&gt;  private final String name;&lt;br /&gt;  private final int age;&lt;br /&gt;&lt;br /&gt;  public Person(String name, int age) {&lt;br /&gt;    this.name = name;&lt;br /&gt;    this.age = age;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Here's code that's &lt;b&gt;only&lt;/b&gt; available for testing:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class MutablePerson extends Person {&lt;br /&gt; private static final String DEFAULT_NAME = "Bob";&lt;br /&gt; private static final int DEFAULE_AGE = 32;&lt;br /&gt;&lt;br /&gt; public MutablePerson() {&lt;br /&gt;  super(DEFAULT_NAME, DEFAULT_AGE);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public MutablePerson withName(String name) {&lt;br /&gt;  return new MutablePerson(name, getAge());&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public MutablePerson withAge(int age) {&lt;br /&gt;  return new MutablePerson(getName(), age);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;private String getName() {&lt;br /&gt;  return accessor.get(this, "name", String.class);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;private int getAge() {&lt;br /&gt;  return accessor.get(this, "age", Integer.class);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;private final ReflectiveAccessor accessor = new ReflectiveAccessor();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now it's true that the testing code has broken encapsulation but only as far as the testing code is concerned, not for the production code. The domain model itself is unchanged. It should be noted that there is a one-to-one relationship between the immutable domain model class and the mutable extension and that the break in encapsulation for a given domain model class propagates no further than the corresponding mutable extension; and again this break only exists in the testing code.&lt;br /&gt;&lt;br /&gt;So I would say the testing code has a minor encapsulation breach which allows the testing code to have a more succinct form than possible with the test builder (it essentially removes the need for all the build() methods).&lt;br /&gt;&lt;br /&gt;Unlike the Test Builder it would not be suitable to move the Mutable Extensions to the production code. Immutability &amp;amp; non-anemicness helps keep domain models from becoming 'bags-o-data', having a mutable version of each domain model in the production code would be too much of a temptation.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14303091-1736992962409382944?l=digital-compulsion.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://digital-compulsion.blogspot.com/feeds/1736992962409382944/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14303091&amp;postID=1736992962409382944' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14303091/posts/default/1736992962409382944'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14303091/posts/default/1736992962409382944'/><link rel='alternate' type='text/html' href='http://digital-compulsion.blogspot.com/2007/08/example-of-mutable-extension-to.html' title='Example of mutable extension to immutable domain model'/><author><name>Stacy Curl</name><uri>http://www.blogger.com/profile/01599842149600715942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14303091.post-573580075824042730</id><published>2007-08-28T01:24:00.000+01:00</published><updated>2007-08-28T02:20:57.465+01:00</updated><title type='text'>Mutable extension to immutable domain model: an alternative to the Test Data Builder pattern</title><content type='html'>&lt;a href="http://nat.truemesh.com/archives/000714.html"&gt;Nat Pryce&lt;/a&gt; recently blogged about an alternative to the Object Mother pattern: creating a builder class for each class in the domain. He's able with this idea to get testing code to look like this:&lt;br /&gt;&lt;pre class="Java Source"&gt;Invoice invoiceWithNoPostcode = new InvoiceBuilder()&lt;br /&gt;   .withRecipient(new RecipientBuilder()&lt;br /&gt;       .withAddress(new AddressBuilder()&lt;br /&gt;           .withNoPostcode()&lt;br /&gt;           .build())&lt;br /&gt;       .build())&lt;br /&gt;   .build();&lt;/pre&gt;&lt;br /&gt;I think I can improve on this and achieve code that looks like this:&lt;br /&gt;&lt;br /&gt;&lt;pre class="Java Source"&gt;MutableInvoice invoiceWithNoPostcode = new MutableInvoice()&lt;br /&gt;   .withRecipient(new MutableRecipient()&lt;br /&gt;       .withAddress(new MutableAddress()&lt;br /&gt;           .withNoPostcode()));&lt;/pre&gt;&lt;br /&gt;Instead of creating a builder for each domain class I've created a mutable extension to each domain class, it is the mutable extension I'm using in the test.&lt;br /&gt;&lt;br /&gt;I don't quite like the code above, I think the following looks better:&lt;br /&gt;&lt;pre class="Java Source"&gt;Invoice invoiceWithNoPostcode = new Invoice()&lt;br /&gt;   .withRecipient(new Recipient()&lt;br /&gt;       .withAddress(new Address()&lt;br /&gt;           .withNoPostcode()));&lt;/pre&gt;&lt;br /&gt;I've changed the code to use the same name for the mutable extension (with a different package of course) because I figure the tests can just refer to the mutable versions and it saves me having the 'Mutable' prefix on everything. Naturally I only make the mutable extensions available for testing.&lt;br /&gt;&lt;br /&gt;Here's how the mutable Invoice extension might look:&lt;br /&gt;&lt;br /&gt;&lt;pre class="Java Source"&gt;package model.mutable;&lt;br /&gt;&lt;br /&gt;public Invoice extends model.Invoice {&lt;br /&gt;  public Invoice(Recipient recipient, InvoiceLines invoiceLines) {&lt;br /&gt;      super(recipient, invoiceLines);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public Invoice() {&lt;br /&gt;      // choose the same defaults here as you would in the InvoiceBuilder&lt;br /&gt;      this(null, null);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public Invoice withRecipient(Recipient recipient) {&lt;br /&gt;      return new Invoice(recipient, getInvoiceLines());&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;I've had to add protected accessors to the domain model; this bothers me a little as they make it easier to slip towards an anemic data model. It might be worth using some reflective code in the extension class instead:&lt;br /&gt;&lt;br /&gt;&lt;pre class="Java Source"&gt;public class Invoice extends model.Invoice {&lt;br /&gt; ...&lt;br /&gt;&lt;br /&gt; private InvoiceLines getInvoiceLines() {&lt;br /&gt;     return new ReflectiveAccessor().get(this, "invoiceLines", InvoiceLines.class);&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;public class ReflectiveAccessor {&lt;br /&gt; public &lt;t&gt; T get(Object fieldOwner, String fieldName, Class&lt;t&gt;&lt;t&gt; fieldClass) {&lt;br /&gt;    ...&lt;br /&gt; }&lt;br /&gt;}&lt;span style="font-family: Georgia,serif;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/t&gt;&lt;/t&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14303091-573580075824042730?l=digital-compulsion.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://digital-compulsion.blogspot.com/feeds/573580075824042730/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14303091&amp;postID=573580075824042730' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14303091/posts/default/573580075824042730'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14303091/posts/default/573580075824042730'/><link rel='alternate' type='text/html' href='http://digital-compulsion.blogspot.com/2007/08/mutable-extension-to-immutable-domain.html' title='Mutable extension to immutable domain model: an alternative to the Test Data Builder pattern'/><author><name>Stacy Curl</name><uri>http://www.blogger.com/profile/01599842149600715942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14303091.post-5555132470078667178</id><published>2007-04-30T04:15:00.000+01:00</published><updated>2007-04-30T04:34:20.780+01:00</updated><title type='text'>Branching by Abstraction</title><content type='html'>&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;Ok&lt;/span&gt; &lt;a href="http://paulhammant.com/blog/branch_by_abstraction.html"&gt;Paul&lt;/a&gt;, I'll bite.&lt;br /&gt;&lt;br /&gt;Some time ago I was working for a client which was experiencing merge hell, come to think of it all the large clients I've worked for routinely experience merge hell, hopefully this isn't correlated with my presence. At the time I mused that when someone creates two implementations of an interface they are effectively branching and so I &lt;br /&gt;voiced that instead of using version control to branch some code perhaps we should Branch by Abstraction. I was working with Paul &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;Hammant&lt;/span&gt; at the time and he's apparently ran with this idea and achieved some notable improvements with it.&lt;br /&gt;&lt;br /&gt;I don't think &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;BBA&lt;/span&gt; it is really that novel, it's just another way of saying 'Hey!, Separate your Concerns', but since a lot of coding-land seems to be engaged in a energetic fight to do the opposite it's probably good to have as many ways of stating the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;bleedin&lt;/span&gt;' obvious as possible.&lt;br /&gt;&lt;br /&gt;I'm quite a lazy creature by habit so I've only drafted an article on this on C2, and intend (honest) to polish it up over time, here's a copy of the &lt;a href="http://c2.com/cgi/wiki?BranchByAbstraction"&gt;first draft&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Summary: Don't separate differing concerns by using a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;VCS&lt;/span&gt;, use an abstraction instead.&lt;br /&gt;&lt;br /&gt;Long story: Conceive the changes of a project as providing alternate implementations of abstractions already present in the software, or of extracting out an abstraction and making it explicit and them providing an alternate implementation. By doing so the abstraction and the varying implementations provide the separation and branches are need much less.&lt;br /&gt;&lt;br /&gt;Consider a possible project that aims to add more data to a business report, say a customer invoice. Suppose that the data being added is the date on which a transaction took place. The current &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;CustomerInvoice&lt;/span&gt; might obtain a bunch of &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;LineItems&lt;/span&gt; and render them. The new requirement is to add date information to the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;LineItem&lt;/span&gt; and display this on the invoice. At the same time as this project is going on bug fixes are being applied the existing invoice, so we can't just make changes to the invoice.&lt;br /&gt;&lt;br /&gt;Step 1) Extract out abstractions needed by the project which are not currently explicit in the code.&lt;br /&gt;&lt;br /&gt;1a) Extract the code which provides line items into an interface and implementation: &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;LineItemProvider&lt;/span&gt;, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;NameAndCostLineItemProvider&lt;/span&gt;, make the implementation the default the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;CustomerInvoice&lt;/span&gt; uses. Deprecate the implementation with a note to its impending replacement. Test and release to production.&lt;br /&gt;&lt;br /&gt;1b) Extract the code which renders line items into an interface and implementation: &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;LineItemRender&lt;/span&gt;, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;NameAndCostLineItemRenderer&lt;/span&gt;, make implementation the default the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;CustomerInvoice&lt;/span&gt; uses. Deprecate the implementation with a note to its impending replacement. Test and release to production.&lt;br /&gt;&lt;br /&gt;Since the changes in Step 1 should be expressible as a series of &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;refactorings&lt;/span&gt; it should be possible to make the test step very short, or arguably unnecessary.&lt;br /&gt;&lt;br /&gt;Step 2) Create alternate implementations of the abstractions created in step 1, or already existing before the project began. &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_15"&gt;NameCostAndDateLineItemProvider&lt;/span&gt;, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_16"&gt;NameCostAndDateLineItemRenderer&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Step 3) Release the new implementations in a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_17"&gt;QA&lt;/span&gt; environment configured to use the new implementations.&lt;br /&gt;&lt;br /&gt;Step 4) Release the new implementations in production configured to use them.&lt;br /&gt;&lt;br /&gt;Optional step) Back out the implementations from production, revert back to the previous &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_18"&gt;implementations&lt;/span&gt; at run time.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Whilst most of the project is going on (steps 2 &amp;amp; 3) bug fixes can still be applied to all other aspect of the system, and the dated-invoice project just receives these changes for free, as they are only changing the line item providing / rendering aspect. If a bug fix is needed in the line item providing / rending aspect the bug fix team easily become aware of the new implementation via the deprecation notice, alternately the dated-invoice team can monitor changes to the undated-implementation.&lt;br /&gt;&lt;br /&gt;If another project starts up whilst the dated-invoices is chugging along then it will have the same steps, and will involve work on some other abstraction. Should another project need to do work on the same abstractions they too will have the deprecation as a notice to be careful and consider interaction with the ongoing work on dated-invoice, otherwise they can work merrily in ignorant.&lt;br /&gt;&lt;br /&gt;So in short the encapsulation that abstractions provide can work for projects just as well as they work for code. When changes occur in other projects then as long as it doesn't involve the abstractions I'm working on in my project then I don't need to care.&lt;br /&gt;&lt;br /&gt;Compare this with &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_19"&gt;BranchByVcs&lt;/span&gt;. In this one creates a fork of a much larger set of code, probably all of it. Other projects / bug fixes will occur in the same code and later the two changes will be merged together, the merge will take place a series of poorly understood textual changes with an unspecified focus, additionally the merging of changes from some project is usually done by people not on the project.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14303091-5555132470078667178?l=digital-compulsion.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://digital-compulsion.blogspot.com/feeds/5555132470078667178/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14303091&amp;postID=5555132470078667178' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14303091/posts/default/5555132470078667178'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14303091/posts/default/5555132470078667178'/><link rel='alternate' type='text/html' href='http://digital-compulsion.blogspot.com/2007/04/branching-by-abstraction.html' title='Branching by Abstraction'/><author><name>Stacy Curl</name><uri>http://www.blogger.com/profile/01599842149600715942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14303091.post-116968512846932017</id><published>2007-01-25T00:31:00.000Z</published><updated>2007-01-25T00:32:08.476Z</updated><title type='text'>Poetic / pathetic version control</title><content type='html'>Old codebase&lt;br /&gt;Clearcase update&lt;br /&gt;Flop&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14303091-116968512846932017?l=digital-compulsion.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://digital-compulsion.blogspot.com/feeds/116968512846932017/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14303091&amp;postID=116968512846932017' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14303091/posts/default/116968512846932017'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14303091/posts/default/116968512846932017'/><link rel='alternate' type='text/html' href='http://digital-compulsion.blogspot.com/2007/01/poetic-pathetic-version-control.html' title='Poetic / pathetic version control'/><author><name>Stacy Curl</name><uri>http://www.blogger.com/profile/01599842149600715942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14303091.post-116930373696202208</id><published>2007-01-20T13:47:00.000Z</published><updated>2007-01-20T14:35:39.386Z</updated><title type='text'>Anti-censorship</title><content type='html'>A colleague raised a question about whether he should self-censor to remain visible to people behind the 'great firewall of China' or retain prohibited material and 'deny' all his content, prohibited or not.&lt;br /&gt;&lt;br /&gt;I offer the links below as my answer.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Appeasing Dictatorship: From Munich to Hong Kong: http://www.aynrand.org/site/News2?page=NewsArticle&amp;id=5137&lt;br /&gt;&lt;br /&gt;Save Tibet website:&lt;br /&gt;http://www.savetibet.org/index.php&lt;br /&gt;&lt;br /&gt;Tiananmen Square, Wikipedia article:&lt;br /&gt;http://en.wikipedia.org/wiki/Tiananmen_Square_protests_of_1989&lt;br /&gt;&lt;br /&gt;Taiwan independence, Wikipedia article:&lt;br /&gt;http://en.wikipedia.org/wiki/Taiwan_independence&lt;br /&gt;&lt;br /&gt;China Human Rights Fact Sheet:&lt;br /&gt;http://www.christusrex.org/www1/sdc/hr_facts.html&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14303091-116930373696202208?l=digital-compulsion.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://digital-compulsion.blogspot.com/feeds/116930373696202208/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14303091&amp;postID=116930373696202208' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14303091/posts/default/116930373696202208'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14303091/posts/default/116930373696202208'/><link rel='alternate' type='text/html' href='http://digital-compulsion.blogspot.com/2007/01/anti-censorship.html' title='Anti-censorship'/><author><name>Stacy Curl</name><uri>http://www.blogger.com/profile/01599842149600715942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14303091.post-115822567544970313</id><published>2006-09-14T09:54:00.000+01:00</published><updated>2006-09-14T15:40:06.813+01:00</updated><title type='text'>Java mocking without injection, same line count as Mocha</title><content type='html'>The Ruby &lt;a href="http://mocha.rubyforge.org/"&gt;Mocha/Stubba&lt;/a&gt; mocking framework written by &lt;a href="http://blog.floehopper.org/"&gt;James Mead&lt;/a&gt; allows one to code collaboration expectations very clearly in very few lines.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://stephenchu.blogspot.com/2006/09/ruby-constructor-dependency-injection.html"&gt;Stephen Chu has expressed some disbelief&lt;/a&gt; that the same would be as readable in Java. However I've found that I can mock in Java with comparable clarity in the same number of lines as Ruby.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;public class LaptopTest extends picounit.TestCase&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;  public void powerOnFailsWhenBatteryTooLow(Battery anyBatteryInstance) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    should.call(anyBatteryInstance.meter()).andReturn(9);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    Laptop laptop = new Laptop();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    laptop.powerOn();&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    verify.that(laptop.powerStatus()).isEqualTo(Power.Off);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;  }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I've implemented many different ways of mocking in PicoUnit, all of them using some flavour of dependancy injection.&lt;br /&gt;&lt;br /&gt;I haven't actually implemented the above one which requires much more infrastructure, it requires that PicoUnit modify every single class under test, specifically it requires all methods of all classes to have a pre-check injected into it (by altering the bytecode during class loading) for whether the method in question is being mocked and a subsequent redirect into PicoUnit if it is or a fall-through into the ordinary code if it isn't.&lt;br /&gt;&lt;br /&gt;I've already done plenty of class bytecode manipulation / observation for PicoUnit, many of the features of PicoUnit would be impossible without this, there's so much bytecode stuff going on that PicoUnit has its own mini-framework for just this purpose, so I should be able to implement injectless mocking easily enough.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14303091-115822567544970313?l=digital-compulsion.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://digital-compulsion.blogspot.com/feeds/115822567544970313/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14303091&amp;postID=115822567544970313' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14303091/posts/default/115822567544970313'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14303091/posts/default/115822567544970313'/><link rel='alternate' type='text/html' href='http://digital-compulsion.blogspot.com/2006/09/java-mocking-without-injection-same.html' title='Java mocking without injection, same line count as Mocha'/><author><name>Stacy Curl</name><uri>http://www.blogger.com/profile/01599842149600715942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14303091.post-114620176879501427</id><published>2006-04-28T06:20:00.000+01:00</published><updated>2006-04-28T06:22:48.796+01:00</updated><title type='text'>Convention, Configuration, and Communication Entropy</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;    The ever more popular web framework, Ruby on Rails, has at its core an interesting idiom: Convention over Configuration. The idea goes as follows: for the most part a data model will map directly to a database schema, and for the most part the display and editing of the data will map directly onto the model, therefore: don't specify the mapping in configuration, assume the mapping exists 1-1. &lt;p class="paragraph"&gt; The long established ideas of Algorithmic Information Theory back up these design choices very well, in particular the idea of Communication Entropy applies directly to this situation. The entropy associated with a given communication relates to the amount of information that one learns upon receiving the communication. So for instance when one learns that a table PERSON has a data model equivalent Person and a view person.rhtml then one learns very little because this 1-1 type mapping is very common. &lt;/p&gt;  &lt;p class="paragraph"&gt; In communication theory one uses the entropy of a message to compress the message, so for instance in English the letter E crops up very often, one learns very little from a message from the presence of E (you can test this by removing all the E's from this text, or indeed all the vowels, you will mostly likely find the text completely readable without them), therefore when we want to send an 'E' down a communication line we send the smallest encoding: 0, leaving the whole of the rest of the alphabet to begin with 1 (t = 101, a = 110, etc.). When one encodes English like this on average a letter can be communicated with about 2 bits. Without encoding the average would be around 5 bits, over twice as large. &lt;/p&gt;  &lt;p class="paragraph"&gt; Perhaps if the same ideas were applied to software we could also see a reduction in message size. In fact this idea underpins Domain Specific Languages (like those Rails uses): don't communicate that which you can take as a given. &lt;/p&gt; &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14303091-114620176879501427?l=digital-compulsion.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://digital-compulsion.blogspot.com/feeds/114620176879501427/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14303091&amp;postID=114620176879501427' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14303091/posts/default/114620176879501427'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14303091/posts/default/114620176879501427'/><link rel='alternate' type='text/html' href='http://digital-compulsion.blogspot.com/2006/04/convention-configuration-a_114620176879501427.html' title='Convention, Configuration, and Communication Entropy'/><author><name>Stacy Curl</name><uri>http://www.blogger.com/profile/01599842149600715942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14303091.post-114620172461220726</id><published>2006-04-28T06:19:00.000+01:00</published><updated>2006-04-28T06:22:04.616+01:00</updated><title type='text'>The parallels between TDD derived code and Artificial Neural Networks</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;    I'd like to draw an analogy between artificial neural networks and the code that often gets produced by poor TDD, i.e. TDD done with little respect paid to refactoring. &lt;h3 class="heading-1"&gt;Artificial Neural Networks&lt;/h3&gt; &lt;p class="paragraph"&gt; An artificial neural network (ANN) is a graph like structure that maps some set of inputs to a set of outputs. The ANN can make very complex mappings due to having multiple layers and weightings between nodes in the network. &lt;/p&gt;  &lt;p class="paragraph"&gt; One example of an ANN is one which can recognise a human face. To obtain such a network one stimulates a randomized network with samples of a face and of non-faces. For each sample the network will produce an output. One takes the output and calculates the difference between it and the desired output and then that difference is back propogated through the network. Back propogation of the 'error' causes the network to learn, to produce smaller and smaller errors. &lt;/p&gt;  &lt;p class="paragraph"&gt; After training one has a very useful tool that can classify things sometimes more accurately than a human can. The faustain bargain one has agreed to is this: One doesn't know how the network classifies its input. The 'knowledge' is just a bunch of numbers, it's a black box.  &lt;/p&gt; &lt;h3 class="heading-1"&gt;Code produced by TDD&lt;/h3&gt; &lt;p class="paragraph"&gt; With TDD the tests take the same role as input to the code and expected output. The developer takes the difference in actual and expected output and back propogates changes to reduce this difference to zero. &lt;/p&gt;  &lt;p class="paragraph"&gt; At the point when all the tests pass it can be very tempting to move onto the next feature but if one succumbs to this temptation, and does so regularly then the resulting code will closely resemble the neural network, it will work, but you won't know how it works, it too will be a black box.   &lt;/p&gt; &lt;h3 class="heading-1"&gt;Danger of over-specificity&lt;/h3&gt; &lt;p class="paragraph"&gt; Once one has a trained network one might have the danger of having an over specific network: it can recognize all of the faces in the sample set but cannot recognize faces outside the set, even if we might feel those additional faces are too similar to warrant misclassification. To address this problem one usually divides the sample into two sets; one set being used for training and both being used to verify. &lt;/p&gt;  &lt;p class="paragraph"&gt; But with TDD there is no equivalent to having a sample of tests used to drive the code and additional tests used to verify the code. So not only will the code be a black box but it could very likely be an over specific black box.  &lt;/p&gt; &lt;h3 class="heading-1"&gt;Conclusion&lt;/h3&gt; &lt;p class="paragraph"&gt; I find the conclusion to all of this quite obvious: Refactor your code if you want to retain the ability to understand it! Even if you have great tests and great coverage you may still have a murky black box that nobody wants to work on. &lt;/p&gt;  &lt;p class="paragraph"&gt; (*) It may be that black box code cannot be tested with good tests and so the existence of black box code will be noticed by the developers as an increasing difficulty when trying to write good tests.  &lt;/p&gt; &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14303091-114620172461220726?l=digital-compulsion.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://digital-compulsion.blogspot.com/feeds/114620172461220726/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14303091&amp;postID=114620172461220726' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14303091/posts/default/114620172461220726'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14303091/posts/default/114620172461220726'/><link rel='alternate' type='text/html' href='http://digital-compulsion.blogspot.com/2006/04/parallels-between-tdd-derived-code-and.html' title='The parallels between TDD derived code and Artificial Neural Networks'/><author><name>Stacy Curl</name><uri>http://www.blogger.com/profile/01599842149600715942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry></feed>
