Context and Best Practices

Last night, I had a Skype/SharedView session with a buddy in Arkansas trying to apply DDD and “best practices” to an application he was building.  He wanted to use all the ALT.NET tools he’s heard so much about, such as NHibernate, StructureMap and so on.  The problem came when he went to go look at the sample applications for “Floogle Architecture”, and was basically stopped dead in his tracks.  His question to me was, “do I really have to do all this?  It seems like a little overkill”.  He had looked at several reference applications for every different Floogle Architecture out there, and all confused more than enlightened.

Back when I was getting started trying to apply design principles to my work, I also yearned for that golden reference application that would just tell me what I needed to do, or at least show me what I shouldn’t do.  I remember looking at JP Boodhoo’s application he built after a Nuthin But Dot Net course, and I had the same thoughts.  “Do I really have to do all this?  It seems like a little overkill.”  What my buddy and I were missing was context.

Earlier that day, I had a Q&A session with another buddy in town that’s been developing Rails apps to production for around 4 years.  Over the course of the past couple of years or so, I’ve also built up a set of mental best practices when it comes to building ASP.NET MVC applications.  But something had been nagging me.  Rails folks have built large, testable, scalable applications with far far less moving parts.  Why do I need all these moving parts, indirections, abstractions and so on to be successful, when plenty of other folks are successful without them?  Talking with these two folks in one day reminded me (again): Context is king.

The Right Way versus the Better Way

My .NET buddy was building a small application.  It had something like 4 entities and less than 10 screens.  It was a small application built for a specific purpose, and wasn’t really going to get much bigger.  The Floogle Architecture reference applications are built with a much different context .  They could be for applications with hundreds of controllers, dozens upon dozens of entities, and very complex screens.  However, all of that context is missing in each respective reference application.

One of the sticking points from Eric Evans when describing DDD was that DDD was never meant to be applied to every solution.  It’s hard, it’s complex, and it takes a lot of work and collaboration.  In fact, I’ve heard quoted that something like 95% of every application built is not complex enough to warrant a DDD solution.  So why is every application I build using the most complex DDD architecture?  Am I special?  Do I live solely in that 5%, or have I just decided to pick one architecture and apply it globally, no matter the context?

When reviewing my Rails buddy’s actual production Rails app, I was struck by how little code there was, and how flat the architecture is.  He had Model, Views and Controllers, and that’s it!.  All these pieces that I put in place to support complexity, such as a service layer, dependency injection, factories, indirection, facades, the list goes on, were just not needed in his projects.  That’s not to say that the Rails app wasn’t complex.  It had complex querying, validation, caching and so on, but it just didn’t need a lot of code to do so.  Rails apps don’t even have the concept of a project, yet all Floogle Architecture examples highlight the need for proper layer separation through project structure.

Instead of focusing on the “Right Way” to build an application, I should have focused on the “Better Way”.  Sometimes the better way to build an application is to pick the absolute simplest architecture imaginable.  Sometimes I don’t need DDD.  Sometimes I should just use ActiveRecord, because I just don’t have that domain complexity.  When I taught a class for ASP.NET MVC recently, I threw out all my default usage patterns, because building from scratch would pretty much guarantee I built the minimum I actually needed for the context at hand.

Default Architectures

One of the books that heavily influenced my understanding of DDD was Jimmy Nilsson’s book.  In it, he talks about a “new default architecture”.  So I developed an architecture, and applied it pretty much without any thought to every. single. project I worked on.  It works well because I know it and understand it, I know its limitations and its constraints, and I know where it can bend complexity-wise.  Over the years, this default architecture has grown and grown to basically handle every complexity I’ve ever seen.  It’s now very flexible…but very difficult to understand.  Pick any reference DDD architecture out there, and you’ll see the same thing.

And that’s where my .NET buddy went wrong.  He picked what he thought was a default MVC architecture, when instead it was a reference DDD architecture.  His first question should have been, “do I need DDD?”.  In his case, decidedly not.  In in most cases, decidedly not.  When talked with my Rails buddy and mentioned the word “Entity”, I was met with a blank stare.  When I sketched out the flow of control in our default architecture, all the pieces we had to develop, his (polite) response was “That looks…hard…”.  Yes, yes it is hard.  It was completely necessary for the context in which we first developed it, but not for every context.

So why do I try and apply that architecture to every context?  Because I’m lousy at predicting complexity.  However, Rails folks have happily developed large systems to production without all the pieces I decided I needed for every project.  Instead of looking for a “Default Architecture”, I should instead be looking for the “Better Architecture Choice for This Context”.

Starting Small

In the upcoming conversations with my .NET buddy, I’m going to have him throw out all the default architectures he’s looked at.  They are interesting from a patterns/style perspective, but utterly useless if you don’t understand the context behind the decisions that brought the samples to that point.  And for his case, he just doesn’t need them.

Instead, he needs things like “how do I integrate NHibernate?” and “why should I use a DI framework?”.  All the rest can be built up as needed, in a YAGNI fashion, when (or if) the application and the business requirements demand the need for DDD and a complex architecture.

Related Articles:

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

About Jimmy Bogard

I'm a technical architect with Headspring in Austin, TX. I focus on DDD, distributed systems, and any other acronym-centric design/architecture/methodology. I created AutoMapper and am a co-author of the ASP.NET MVC in Action books.
This entry was posted in Domain-Driven Design. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://scottcsims.com Scott

    Well said Jimmy!

  • http://codebetter.com Rod Paddock

    Well put Jimmy. This is what I have been talking with Eric Anderson about extensively

  • http://blog.robustsoftware.co.uk Garry Shutler

    Great post Jimmy.

    The simplest thing that could possibly work often gets forgotten or overlooked at the architecture level which is the place it’s needed most!

    We should start experimenting in how simple we can make the foundations of our projects rather than how simple we can make the 5th layer of abstraction.

  • mendicant

    I couldn’t agree more. I’ve always had this nagging feeling about ASPNet MVC (after also building a pretty large rails site) when I used it and I think until I read this I wasn’t quite able to say what it was. But it really is a “Do I really need all this” kind of feeling.

  • http://ajepst.devlicio.us/ Anne Epstein

    I agree, a lot of the default architectures out there seem like extreme overkill for smaller apps, esp if the people working on those smaller apps don’t really understand what all that unneeded abstraction could be getting them-particularly for them, but truthfully for anyone working on these small-scale projects, it’s cruft, frankly.

    Still, unless it is a really, really simple app it seems like the goal is to do this in a way that doesn’t shut the door to sane future growth if complexity increases. I’m not a dynamic language expert by any means, but I’d guess this is why Rails works so well-dynamic languages allow a simple design while providing most of the flexibility you might want in this regard without having to do anything special (extra layers of abstraction, etc) upfront. I wonder how possible this is with static langs like C#? How simple is it possible to get without shooting yourself in the foot if you need more? Hmmm.

  • http://jason.lostechies.com Jason Meridth

    My C# applications have become much simpler due to my daily use of Ruby and Rails.

    Great post Jimmy.

  • Raif

    Hey,
    Yes it would be nice to trim down some of the pieces, but what can we really get rid of? I mean
    1. NHibernate is a must,
    2. as is fluent NHibernate,
    3. You certainly can’t use the html.helper stuff in mvc so you need your own or to use the contrib.
    4. I know that there’s a lot of talk about a di container not always being necessary, but you wont find me writing an app with out it. what a pain.
    5. while a validation service layer is maybe not always necessary, it often does actually help reduce the amount of code by allowing the attributes on your model to filter up through the different layers.
    6. you have to have your javascript layer.
    7. plus all your tdd infastructure.
    I guess this is more a list of components, some of which are part of the architeture some are supplemental, but when taken as a whole there are a lot of parts that can take some considerable time to build up and master. which of course can look daunting and like over kill. But to work with out any of those pieces would end up being more difficult then to work with them.

  • http://www.lostechies.com/members/bogardj/default.aspx bogardj

    @Anne

    On our current project we’ve gone through several different architectures, each building upon the one before, each justified by the complexity of our domain. The techniques we used were YAGNI, KISS, DRY, “the simplest thing that could possibly work”, and evolutionary design.

    @Raif

    Yes, I put components in a different light than architecture. There are good and bad practices for components, but not “best practices”.

  • sharpoverride

    It’s striking when you see an app built with simplicity. Indeed the amount of knowledge we usually put into building even the simplest app is astounding for someone that hasn’t had the time to build up momentums of best practices.

    Using the bare minimum of DDD building blocks is usually where I start.

    However I’m working on a project that has been in development for 15 years. And the guys have a framework that like it or not is easy to extend, and mantain. It is however NOT the way I would do it, it isn’t even close to what I would have expected from a big application, but it has a forward way of developing. Adding something new is just a matter of dropping some files that become applications.
    It’s kind of frustrating when I think about it, these guys got something working without NHIbernate, without IoC, heck they don’t even know what a controller, or presenter is about. Still the project is the base of 3 major application that bring a lot of revenue. PSSS, and don’t tell this to nobody else ;) they even use inline SQL. AND IT ALL KEEPS WORKING!! WTF!!

    It’s something I’ve been thinking about, I tend, and most of the blogs I read do the same, to overcomplicate strait forward activities. And for what the extra layers of indirections?
    Maybe I need to rethink the whole I need layer X and layer Y. Having a way as simple as dropping an assembly or two, plus the coresponding views should be the direction.

    A very smart man said: Every problem can be solved with a new layer of abstractions, except when you have too many abstractions!

  • http://tracker1.info/ Michael J. Ryan

    I’ve been doing client-heavy web-applications for over a decade now. I must admit, it’s much better than the bad old days, and for the 2002-2004 time frame I was so frustrated I leaned towards heavier server-side code. Today, it can be really nice. I can do a client-side MVC layer with something like ExtJS and do a server-side communications layer in whatever I choose.

    I’m currently working on a major refactor of a web-app, where the UI is being rewritten with jQuery+UI and jqGrid for the main script/ui helper pieces. The server-side portion of another project has a WCF service setup to support the ExtJS front end. I’ve found the additional complexity and separation frustrating, as there’s already a complex set of business and data layers.

    This app will simply use .ASMX which blend in easily enough with the existing project to support those Ajaxy needs. This layer directly supports the client UI, why separate it into a service that will only ever have one target, with an interface definition and DI that re-utilizes an ORM + BLL that are already in place?

    I’ve also used (and honestly love) the ASP.Net MVC structure as a backend for ajaxy web-based apps. It just doesn’t fit as well into the existing app, and this refactor. I have found that using something with a nice IQueryable interface definition works wonders for servicing a query+grid based UI.

    I think DI is a real nice to have, and invaluable if you need to support different back-ends, otherwise it may not be worth the added layer of complexity. I find that TDD really helps, if you have the time/ability to flush out a specification before building. Otherwise you wind up re-creating a lot of tests to fit your environment, or are constantly fixing tests. What it comes down to is when it is worth the additional difficulty.

    My own preferences today are NHibernate + Fluent + Linq (contrib), with ASP.Net MVC with either StructureMap or Unity, Moq and a front-end with either jQuery+UI+jqGrid or ExtJS. That’s just me though. The team I’m working with and the projects I’m working on today are using LLBLGen for the data layer, which works, but I prefer the finer-grained control and ease combinations you get with Fluent+NHibernate. Though I’ve used Castle ActiveRecord and have looked at Subsonic.

  • http://www.marisic.net Chris Marisic

    @Raif, I agree with most of your points however I disagree about using attributes for validation. Why should my domain model be polluted with validation attributes?

    It’s the interface’s job to not let users enter invalid data and it’s the service’s job to not persist invalid data. Why should the objects themselves know anything about the business logic on what makes a string invalid or valid for a StreetAddress?

  • Raif

    @Chris
    Ha. yea I tossed a few bombs out there. I can’t help my self. I tend to put my entities on the model so that I can draw validation, type and other sorts of info in to the view from the entities. But I know that’s largely frowned upon.
    I keep the validation information as close to the source as possible. It needs to be somewhere either in the validation service or the entites. It seems to me that it is the entites job to define it’s self and part of it’s definition is what kinds of information are permissible. It is the services job to read that meta data, compare it to the entities state and create error messages or what have you.

  • http://www.lostechies.com/members/bogardj/default.aspx bogardj

    @Raif

    In the rails world, the word “entity” has no meaning. It’s all Model. Yet they’re successful. Why? Perhaps DDD is not useful in those apps. Perhaps DDD is not useful in _your_ app. Perhaps it’s all just overkill.

  • Mehdi

    Thanks for the post Jimmy. This is one of my big questions in software architecture!

    You say start small and simple because your application may not require complicated architecture! I guess I may be very unlucky, but whatever small and to-be-thrown-away-in-a-year application I started, ended up growing much bigger and it was never thrown away. So I am quite scared of starting a new small application with a small/simple architecture. Though obvious, I would like to emphasize that architecture is not something you can change, easily, after the application has gone live. For example, you start a simple CRUDy application without DDD in mind, and then all of a sudden domain complexity grows beyond what for example active record for database access or request-response for communication can handle!

    This all makes me want to use a default complex architecture for even a phonebook application ;-) but is this really necessary?

    Even though, I think we should always look for the simplest solution, business (functional and non functional) requirements tends to change much more frequently than a simple architecture can cope with!

    What are your thoughts on this Jimmy?

  • http://moleseyhill.com Mat Roberts

    I think the idea of starting small, and building incrementally is great (KISS, YAGNI etc.)

    When doing this though the area I’ve had trouble with is Data Access. If you start off with the Active Record pattern, it gets baked in to how the whole thing works. I’ve found it very hard to see a migration path to get to the Repository Pattern, when the application has got to a significant size. It seems to me like this is one of those choices where once it’s made it’s very hard to change, so you’re better off starting with Repository, even on a small application.

    Thoughts?

  • Chris Carter

    I’ve found DDD to be most useful in applications where the actual logic in the domain has a lifecycle much longer than a single web request. Ie, long running processes that involve external systems. This is the domain in which DDD thrives, and the web is just an interface to it. The majority of web applications aren’t this way. They are truly stateless and the logic they work with can live completely in the scope of a single web request.

    Maybe its just me, but I’m coming to realize that the .NET ecosystem just isn’t as suitable for these kinds of apps as other frameworks (if you have the flexibility in your environment to stretch out that is). Rails and its immitators are engineered precisely for rapid web development, and it shows. Even the new JEE 6 has a leg up on ASP.NET (and derivatives), in my opinion, with all the built in plumbing and (new) lack of required configuration.

    I still prefer .NET for those apps that require complexity in infrastructure and design, and have the myriad requirements that long lived business logic does.

  • Vitaly Stakhov

    It makes perfect sense only when you *understand* the best practices. Otherwise people will come up with something cumbersome and may still think that those best practices are an overkill just because they don’t have enough skills.

  • http://www.corebvba.be Tom Janssens

    Hey Jimmy,

    The difference between Rails and the MVC architecture is that Rails has a component plugged in by default for every functionality.
    This means that you do not have to wire everything up (unless you really want to). It is applying it’s own convention over configuration mantra to it’s choice of libraries as well…
    In the .Net world everybody thinks they need solution x combined with alternative y, so that is probably why most of these projects are not successful.
    This being said, I can currently see 3 possible solutions :
    1. A component that auto-registers/integrates every DLL reference in the project. jglozano’s MVCTurbine does just that afaik. Checking this out is still on my todo-list…
    2. A prebuilt DLL/package that has a few things set-up by default. This is the way I have been doing things. I created (for my own projects) a library that sets up everything I need by calling a single function, after which I can register my project-specific things like mappings/modelbinders etc using the exposed registry interfaces.
    I have to say this has been working out just fine, and it makes starting a new project a lot simpler…
    Shameless plug, since it is open source: :
    http://www.corebvba.be/blog/post/Build-aspnet-MVC-applications-FAST-with-MVCExtensions-v04.aspx
    3. If you are in to it, I suppose you could use monorail (although I have to admit that I have not tried this yet), but since it is based on rails, it could probably be worthwhile to check it out…

    Tom

  • http://blog.bobcravens.com Bob Cravens

    I agree with Mat Roberts in that I prefer an approach closer to the YAGNI principle. Starting a project with all the frameworks in place seems a little complex. The simpler the better. Introducing a framework or component just because that’s our default shell application may make one developer feel ‘right at home’. However, that approach generally makes an app more complex than necessary and make it more difficult for other developers to maintain.

  • Arul Livingston

    Well said!