There has been a certain amount of noise and comment around Joel Spolsky’s post on the duct tape programmer.
This is, for me, just another manifestation of the hero coder – the guy the business love because he ‘gets things done’. He is the guy who is turning out the features to the customer while you are still implementing top down from your acceptance to your unit tests. While you are trying to build a domain model, focusing on the ubiquitous language, and trying to create a model expressed in software, he has hacked out some procedural code that just works. While you create your ORM mappings in Fluent NHibernate, his DataReader has grabbed everything he needs from a custom stored procedure and pumped out the web page. In the customer’s eyes he is responsive, he gets their needs, and you don’t.
The trouble with the hero programmer is that the customer does not know he uses duct tape, and your explanation of why it is an issue anyway is so complicated they lose interest. The truth is they just don’t care about your engineering principles. And the worst of it is that he will go on to write new features, while you fix
up his last duct-tape special, because he is the guy the customers want,
the hero programmer. He is the guy they think of when they used the word agile – responsive, adaptable to new requirements.
Eric Evans has a fair amount to say about engineers being beaten by the duct tape, or hero programmer, and how those of committed to strong engineering priniciples can thrive in this presentation. We talked this over at our development book club, con-incidentally the day after Joels’ post broke.
The presentation draws on the ‘second-half’ of the DDD ‘blue’ book, , the Strategic Design section, a part that is tragically overlooked in favor of the patterns in the first. Tragic because some of the strongest insights of Eric’s work are in this second half, but everyone focuses on aggregates and repositories in the first.
The key idea here is that we need to focus on dividing our solution up into three areas: generic domain, supporting subdomain, and core domain.
Generic Sub-domain: This part of the software can just be bought off the shelf, or found from open source, because it has become ubiquitous and is comoditized. It might be a generic application such as accounts, document generation, CRM, ERP. It might be a generic framework such ORM, RDBMS, Reporting etc. Your customers are not doing anything here that gives them competitive advantage. In some cases they make want to work in a different way to that supported by the generic software; even so, in this case there is no return on supporting their way of working, so they need to conform to the generic model. Note the inclusion of both inftrastructure frameworks and applications. You might think you can build a better ORM or BUS, but unless your customer gains competitive advantage from that, do not tackle it.
Supporting Sub-domain: This is not commoditized, but your customer gains very little here. There is no special sauce, no clear case on return on investment. Identifying this area can be hard, because this is often specific to your customer’s domain, and you can’t find it off the-shelf. The key is that there is little competitive advantage to this code. The code here might be non-customer facing admin utilities such as user administration, but it also might be code that faces your customers, but provides little competitive advantage for you to get right. This is an area where use an off-the-shelf model if one exists. It is the area where you might outsource your requirements. It is the area where you deploy your hero programmer, because you just need it done and you don’t care if it is done with duct-tape. Often when there is change here your strategy is just to throw away your existing implementation and start again. This is highly disposable code.
Core Domain: This is where your customer gains competitive advantage. it is where custom development has a high return on investment. This is where you deploy your best programmers to build a domain model, make sure you use disciplined engineering approaches like automated tests and CI. This is where you don’t deploy your duct-tape programmer, you are worried about total cost of ownership here, because you don’t want to throw this code away and start again. It is a strategic investment.
The core domain is almost certainly not the whole solution, but perhaps more suprisingly it may not even be a whole application. If your cutomer’s special sauce is a better rating, shipping, or pricing algorithm then that is your core domain. The web site that collects the data which you pass to that engine may not be – it might just be a supporting sub-domain your hero/duct-tape coder hacks out for you while your engineering team focuses on the core domain.
You may well need an anti-corruption layer between your core domain and generic and supporting sub-domains, to prevent their model bleeding into your domain model. That anti-corruption layers also allows you to be defensive to quality concerns.
The key here is working smarter, figuring out where the team focused on a costlier but disciplined engineering approach, can get return on the investment. With this approach you get to deliver the parts that make a difference to the customer instead of expending your effort on the supporting infrastructure.
We watched Eric’s presentation above for our Developer Book Club and the war stories agreed with Eric. This pattern seems to be ubiquitous and we need to fnd a smarter way out that simply sticking our heads in the sand and denying the problem while pursuing an ‘ivory tower architecture’ that the customer will never remain committed too.