Well-constructed != Over-architected

Let’s imagine for a moment that we’re building a dog house for our beloved family pet. We want it to protect Rover from the elements, be a comfortable place for him to escape the sun and relax, and in general, have the structure hold up for quite some time.

We are probably going to select decent wood, rather than scraps. We’ll probably frame it out, make sure it’s sturdy, make sure the joints are secure, that it has a solid base, and that the roof is well put together. We’re probably going to plan it out, draw it up, and do the measurements to make sure Rover fits inside. If we aren’t that good at carpentry, we may grab a book or two and follow the recommendations of people more practiced than us. Sure, we can hammer nails, but we don’t necessarily know whether a miter joint is more appropriate than a dovetail joint in this case. We’re not just going to slap it together with glue and tacks, leaving gaps between boards, and not being too concerned if it skews in a strong wind. In short, we’re going to build a shelter that we’re happy to put a loved one in.

We aren’t going to support the walls with flying buttresses to future-proof the structure. We aren’t going to build it with steel girders. We aren’t going to turn it into the Winchester House.

There’s a difference between well-constructed and over-architected.

There’s an epidemic of misinformed opinion going around that adhering to commonly accepted good coding practices is synonymous with being an “architecture astronaut”. That somehow someone who insists on applying SOLID and other principles to their code is more likely to inappropriately “solve” simple problems with too much complexity. This is simply not the case, and in my experience, the opposite is usually true.

If I have a simple one-off forms over data application to deliver in a short time it’s very unlikely that I’m going to spend a lot of time applying everything I ever read about DDD to the problem, and put a message bus behind it, put NHibernate under it, and implement some extensibility framework ahead of time just in case.

I will, however, write the code to adhere to the Single Responsibility Principle, and I will employ Dependency Inversion, and I probably won’t have many Law of Demeter violations. And I’ll probably, but maybe not always, design it with TDD. Why? Because my experience leads me to understand that these are good things. They help ensure that this simple app is going to be understandable and readable in 6 months when I have to add a feature or fix a bug. And they’re internalized. It’s the way I code now. It’s no faster or slower than not employing SOLID principles because that’s a useless comparison at this point. I’m unlikely to not employ these techniques because it’s how I write code.

I believe that IoC containers are powerful tools. Every application I’ve written in the last couple of years does not, however, employ an IoC tool. Each of them does, however, make use of dependency inversion internally because that’s a good way to construct your classes.

I believe ORMs are powerful and useful tools. I do not, however, have a single application in production today that uses NHibernate (ok, it’s out, I’m the only alt.net guy not using NHibernate in production). I do, however, typically abstract data access away from the rest of the application as a natural result of applying SRP.

I believe that DDD is a very powerful design philosophy, and that DDD as a concept is composed of many useful parts, not just the patterns. Every application I have in production does not, however, have a complex domain model, and a layer of application and domain services, and a slew of repositories, and explicit aggregates with roots and so on.

I do, however, always think about my domain even if it’s an ActiveRecord type implementation, because it helps make sure I’m modeling the appropriate concepts. And I do always think about and build a lexicon for ubiquitous language for a project because it enhances communication and clarity. And I do think about what my bounded contexts are because it helps me understand the nature of the system.

Irrespective of the complexity of code to be written or the time allotted to write it, I always strive to make sure my code is readable, and that my APIs are intention-revealing. This isn’t about geeking out on code structure, this is about putting something together that someone else on your team can understand. There’s no time tradeoff to be made here, nor is there a complexity one. It’s just part of constructing your software well.

Nobody ever said that building software well meant employing every tool and technique in the alt.net toolbelt every time, so I don’t know why people insist on acting like that’s being said. These arguments about not having enough time to “do it right” or not wanting to overcomplicate “simple” solutions usually come from a position of either ignorance or fear.

Constructing something well means simply constructing something well. Have the professionalism to do so.

Technorati Tags:
, , , ,

Related Articles:

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

About Scott Reynolds

Scott C. Reynolds is a developer with over a decade of experience creating enterprise solutions, primarily in healthcare and biotechnology. He is passionate about the art and craft of applying software solutions to business problems. He is a frequent speaker and participant of community events nationwide.
This entry was posted in DDD, quality, software, SOLID. Bookmark the permalink. Follow any comments here with the RSS feed for this post.

6 Responses to Well-constructed != Over-architected

  1. Anon says:

    Surely your dog house would be better if it was held together with duct tape

  2. I think it would be better if it was made completely out of duct tape. And maybe some WD-40.

  3. Steve says:

    Scott,

    You are more of a rarity than you know in this business. Unfortunately, there is a very large percentage of the C# community that would attempt to build the Winchester Mystery House.

    I used to think that the most dangerous type of developer was the one that didn’t know anything, now I’m starting to think that it’s the one that knows too much, but doesn’t know how to apply it. The former isn’t setting company policy or designing architecture, they’re just watching the clock and cashing paychecks. The latter, the one who knows to much but lacks experience is the one over designing everything and getting you in much worse trouble than the former ever could.

  4. Well said Scott. Just because I have a hammer, it doesn’t mean everything is a nail, and just because I have a tool belt, doesn’t mean i’m going to use every tool for every job. Keep up the good work.

  5. Michael Levy says:

    Agreed. This message needs to be communicated more often.

  6. rtpHarry says:

    Agreed! Now if I could just figure out how I can join this elusive circle of developers… I read about agile techniques and all these nice things you talked about and then I sit down with my asp.net webforms page, double click an event handler and write my code into it! Maybe I just suck but I am having a problem making the jump from theory to practice.