Beating the duct programmer with generic domains, subdomains, and core domains

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.





About Ian Cooper

Ian Cooper has over 18 years of experience delivering Microsoft platform solutions in government, healthcare, and finance. During that time he has worked for the DTi, Reuters, Sungard, Misys and Beazley delivering everything from bespoke enterpise solutions to 'shrink-wrapped' products to thousands of customers. Ian is a passionate exponent of the benefits of OO and Agile. He is test-infected and contagious. When he is not writing C# code he is also the and founder of the London .NET user group.
This entry was posted in Uncategorized. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • Heroic programmer

    Why is everyone always assuming that heroic programmers are dirty and hacky? :/

  • Domain Names

    Well, it’s amazing. The miracle has been done. Hat’s off. Well done, as we know that “hard

    work always pays off”, after a long struggle with sincere effort it’s done.
    mark gibs
    Domain Names

  • tibia gold

    I like your article very much!I can get lots of from it!

  • Geoff Payne

    This is a great discussion and I really got a lot out of Eric’s presentation as well.
    Making the case for “more short term investment for long term savings” is often hard and the “hero programmer” will probably always be with us. Project sponsers often have to learn the hard way, and when they do, then they are more likely to listen.

  • Ian Cooper


    Sure but within your supporting sub-domain this is less of an issue, because the problem is usually well understood or simple

  • Reido

    I agree with some of the other commenters that the actual problem with the duct tape programmer is an impatience in acquiring the requirements the client needs, as opposed to the requirements the client mistakenly communicates to the programmer up-front. The duct tape programmer doesn’t say “No” and doesn’t say “Please elaborate”, which is precisely why clients like it. The problems start to show up after the duct tape solution is out the door, and the client begins to realize the fundamental lacks of understanding shared between client and duct tape programmer.

    “Oh, I didn’t think of exceptions A, B, and C. And without feature Q, I might as well fire up my Excel spreadsheet to do this task. Oooo, look, ‘Access’. I can throw together a database and UI without that darn programmer at all!”

  • Ian Cooper


    I’m not saying duct-tape guy is bad, but that his approach is better for some tasks than others. That’s the key here, knowing when to deploy different approaches. And that’s not news in many ways, but worth re-stating in this case.

    Our current project has off-the-shelf applications, out-sourced sub-domain components and an core domain element. It’s getting the mix right that works.

  • Ian Cooper


    No offence taken

  • Ian Cooper

    @Steve Py

    Steve I can understand why you might think version #1 is a good place for duct-tape, after all version #1 may be about gathering feedback. But if you use agile methodologies, even with a core domain model you can release early and release often. The difference for version #1 would be whether or not you knew it was core domain. If this is ‘special sauce’ to the customer its still core domain, and you want automated tests with CI, uqbiquitous language and all that good stuff. If its not core domain then its likey to be supporting sub-domain. The version #1 nature does not change the problem.

    One reason it may seem natural for duct-tape programmer to do version #1 is that you do not know whether this is core or sub-domain. It is important to bear in mind that a feature can change between these domains. You may spot a ‘quick-win’ that can be hacked together by duct tape guy to provide supporting sub-domain, that takes off and becomes core-domain, so you have to re-build it using solid engineering principles.

  • Steve Py

    The conflict comes into play for both sides when they become a hammer and every project looks like a nail. I duct-Tape on demand, but I make damned sure that customers know the implications up-front.

    I’ve heard and read countless spews from what I consider “elitist” engineers playing down cowboy coders and duct-tape developers, making anyone who justifies cutting corners look like Red Green.
    Some would say there’s nothing worse than a hero coder on a project that needs to be engineered, but the truth is there is something that is just as bad. Engineers on projects that need to get to market.

    IMO the best place for hero coders is Product Version #1. Adaptation, and time to market is critical and these are the duct-tape coder’s specialties. This gets under the skin of Engineers because this is where all the cool, new energies are invested. The problem is that once v1.0 is out you get into a situation where the business wants to add on to it while “common sense” would dictate that a better engineered, extendable product would serve them best in the long run. THAT is the fight to make. v1.0 is the concept to prove the market. v2.0 is the legacy. Once you commit to maintaining v1.0, you’re hooped.

    I’ve had the pleasure of working on nearly two dozen significant projects and one of my favorite “discussions” with engineers about frameworks and domains and sub-domains, yadda-yadda. Most of them want to design an application for the next 10 years, that will be easy to maintain and so much better than someone might ever duct-tape together… Yet every one of them groans at the thought of maintaining a legacy application from 5 years ago, regardless of how well it might have been written. .Net 1.1? *ew!*

    Things to make you go “Hmm…”

  • MauricioC

    (And I’m not talking about Ian Cooper when I talk about the knee-jerk response either. Sorry for the confusion.)

  • MauricioC


    I thought this usage of the term “duct-tape programmer” was invented by Joel himself in the article, and doesn’t describe the same programming practices that other terms (such as the derogatory, but commonly used, “cowboy programming”). In fact, the article is full of statements that say that: see, for example, the entire last paragraph of it. I agree with you that using it as a defense of poor coding standards is a bad idea, but I sincerely think this is a distorted version of the definition in the article.

    I get from the replies to Joel’s article, however, the message that those things shouldn’t even be discussed, either for believing that that’s *never* a good idea, or for fears that less experienced programmers (i.e., ones that don’t read CodeBetter blogs, for example) might ruin software projects when following such advice. I think the logo, the one with a guy running with scissors, represents a lot in this sense: developers are dealing with potentially risky things every day, it’s important for people to realize it and plan/act accordingly, and that means considering duct-tape if it’s pragmatic to do so. For developers doing important things, foolproof techniques just don’t cut it, only good judgment does.

    (Also, I think it’s important to discuss that because, although coders like jwz are extremely rare, most experienced coders are competent enough to follow *some* of the advice jwz gives in that book.)

    I now understand perfectly what you meant, and I guess I agree with you in most senses, but I think developers must avoid the knee-jerk response to articles that mention not using unit testing (not that you did that, I’m talking about the responses on other blogs that distorted the notion of “programmer who is interviewed in the same book as Donald Knuth” to “inexperienced coder”) and other agile practices in order to do their job better.

  • Eyston


    So using Joel’s article as a defense of poor coding standards in order to ship a product is meaningless because Duct Tape programmers are 1 in a million geniuses who can control complexity in their head.

    This is definitely not the impression I get from most people who prescribe to the duct tape methodology.

  • Ian Cooper


    You’re right the point is not that the duct tape programmer is bad, but that there are places where you can hack a duct-tape solution and places where you can’t. The trick is strategic planning to know the difference

    Disagree the core is precisely where duct tape programming has no place. Total cost of ownership is important there. In other places, time to market is the driver.

  • Eric

    The pragmatic answer is that it depends. The higher the complexity and size of the codebase, the higher the risk that any bugs bring, the more work you will do up front with frameworks, etc to mitigate it.

    MauricioC is dead on with the swiss army knife. If it’s a low complexity, low risk module of code, why put all the extra work into it? Ship it!

  • jdn


    Very well stated, thanks.

  • MauricioC


    “Because it isn’t amenable to change. ”

    You seem to be assuming a duct-tape programmer is an average guy who happens to tackle architectural complexity problems in an absent-minded way, and would get crushed by the complexity as soon as things get bigger. Here’s the thing I think you’re not getting because of prejudices due to Joel’s stance on TDD and other things: The duct-tape programmer (which I’m assuming to be a person like jwz) is the greatest example of YAGNI, but he takes that to a higher level.

    jwz is famous for, for example, hating databases for everything except complicated scenarios in data analysis. Because no one needs the full power of relational databases for a few simple queries. When was the last time you thought “Hey, a simple storage system using a file system could be better for this”? When was the last time you thought “Is object-oriented programming really needed for this project”? When was the last time you thought “This code is a one-liner… Do I really need unit tests for those things”? (Ayende just posted a blog entry about this last question, by the way). Keep in mind that it’s not wrong to say Yes to the above questions, of course. But a duct-tape programmer is the one who would even consider those questions, in my opinion.

    The duct-tape programmer picks the right tool for the job, it’s just that the less sophisticated tool in his toolkit isn’t a swiss-army knife. That doesn’t mean he won’t use the swiss-army knife when the occasion asks for it, it just means he won’t use it when the occasion doesn’t ask for it.

    Duct-tape programmers are *extremely* rare, and if you think you’ve seen lots of them, then perhaps you missed the point of Joel’s article.

  • jdn

    Then I’m putting my hero coder on the core domain because he gets things done.

  • Eyston


    But this isn’t what the post is about at all. It isn’t saying you should ‘never do X’ or ‘always do Y’. It’s about exploiting the right development practice for the job.

  • Eyston


    Because it isn’t amenable to change. The hero coder can get a feature out. He can probably even get a few more features out, but at some point the code is untouchable to adding a feature without great cost. This matters to the customer. Dealing with change and complexity is the strength of XP / DDD.

    But not all parts change rapidly, and if they are infrequent then a higher cost is fine. So yah, there is room for both types of methodology. Ian isn’t saying you should never have a hero coder, he is just laying out a strategy of identifying where each practice is best suited.

  • jdn


    You seem to be making the assumption that either code is maintainable or it isn’t. This is false.

    People *can* maintain even the most horrible codebase, they do it all the time. It’s just difficult.

    As a developer, I’m all about the SOLID. As a business owner, I hear a bunch of people (self included) prattling on and on about these idealistic “you must do this or your project will die” mumbo-jumbo principles when what I want is the customer requirements to be fulfilled. And I’ve heard all this before, every couple of years it’s this or that will save the world. Last time it was SOA, now it’s TDD (or whatever), blah blah blah.

  • Eyston


    Absolutely. If you can write code and never have to maintain it, then there is no sense making it maintainable.

    Most people don’t have this luxury, but it does exist.

    Right tool for the job, etc.

  • MauricioC

    “The truth is they just don’t care about your engineering principles.”

    And why should they? They want code that meets their business needs, engineering practices are just a way to get this done.

    Netscape Navigator shipped in no small part due to jwz and other Netscape engineers with the same attitude. It was a *huge* success. To quote jwz:

    “When we started this company, we were out to change the world. And we did that. Without us, the change probably would have happened anyway, maybe six months or a year later, and who-knows-what would have played out differently. But we were the ones who actually did it. When you see URLs on grocery bags, on billboards, on the sides of trucks, at the end of movie credits just after the studio logos — that was us, we did that.”

    The main reason it was a success was that they had a good product, and they had it sooner than anybody else did, as you can see from the quote above. It appears you’re always valuing architecture/process over business value (which was all in shipping a usable browser IMMEDIATELY), which sounds a bit non-pragmatic to me. Sure, the project could have ended up a bit buggy, but no one cares about that when you’re doing something novel, and that’s where jwz’s project differs from the ones people usually talk about. That’s not to say jwz’s advice applies to every project, but I believe every developer should be pragmatic enough to know that both strategies are useful in different situations.

  • jdn

    “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 if he continues to provide value to the customer, they shouldn’t care about your principles.

    The hero coder isn’t a bad coder.

  • Scott Sparkman

    Thanks Ian for the thoughtful response to Joel’s post. Many have just lambasted it with little reasons to why one should not take pride in being a duct tape programmer. Also reminded me where I should be putting the majority of my time.

  • Ed Blackburn

    Excellent summary Ian, thanks for taking the time to write it up.

    Very little code is written for altruism. Code is written to perform a function for an organisation. The sum of the investment (hopefully) reflects the maintainability and time until entropy of the project. A financial services organisation doesn’t need a handcrafted world beating CRM. Many media organisations may need so.

    Look at or almost any other UK online train ticket service. Their time tabling views are often pretty shoddy and almost exactly the same. That’s because they all syndicate the data from the same source, which also provides a generic web interface. These companies core domain isn’t to provide an elegant train timetable, it’s to cream commission from a sale *and* to operate as a lead generator for destination services, such as car rental, hotel, theatre etc. Hence why the provided supported sub domain is so bland and ripe for UX improvement.

  • Barry Kelly

    People read into this character what they want to, not what Joel necessarily wrote.

    There’s a line in software engineering; stay on one side, and you idolize perfection and never ship until it’s too late; stay on the other, and your code rots over time as debt builds up.

    Engineers who’ve seen too many people on one side of the line point out the benefits of going over to other. That doesn’t mean that you should overdo it, and stay on the other.

    I’m fine with Joel’s article, because I recognize the pathology he’s talking about. That doesn’t mean I glorify hacks, and I don’t think Joel is talking about that either.

    Shipping is a feature. Some engineers lose sight of that. That’s all the article was about.

  • Rainer Hilmer

    Excellent statement. Joel’s post made me furious.