Beyond top-down design

Here at Los Techies, we talk a lot about SOLID principles and design.  Two of the principles that have always resonated with me are the Single Responsibility Principle and the Dependency Inversion Principle.  With the two together, the need for some kind of inversion of control almost becomes required.  When I first started using the DIP, I didn’t really feel the pain of locating dependencies, I always provided some no-argument constructor or the various construction patterns to get my dependencies in play.

The combination of test-driven development and SOLID led me towards a sort of default top-down design, as Derick describes as a cloud of objects.  My objects take, for the vast majority, the following shape:

This is great and all, but in some cases, the level of nesting would get completely out-of-hand.  Small classes are great, but I had projects where the level of nesting hit double digits, making it quite difficult to figure out what was going on, and to understand the shape of the application.  At that point, I couldn’t understand what actually happened for a given request by looking at the code, and all of this traced back to top-down design.

But it is still a vast improvement upon the big-ball-of-mud architecture I created before, yet something still bothers me.  Is this all there is to good design?  Top-down, TDD, with SRP and DIP creating top-level controllers, down to a bunch of supporting classes that have a single responsibility but are hard to understand in the whole?

Another issue I run into with top-down design is that I often have vertical slices of functionality, but absolutely zero re-use.  I fully understand that re-use is not the motivator for creating small classes, but I still felt my application partitioned by top-level features.  Sure, there might be some similarities between disparate areas of the application, but I can’t help but feeling there are other, higher-level patterns to better architect an application than purely top down design.

Right now, I have no answers, and really no idea where to look for them.  I have a feeling there are some other crazy ideas out there, beyond top-down design, that I’m just not aware of.  So my question is: am I imagining things, or is there something else beyond top-down design and architecture?

My only inclination of a larger picture as of this moment is Ayende’s post on concepts and features.  Much of this post (and corresponding talk at Seattle) resonated quite a bit for me, and looks like one of those ideas that can get rid of much of the orthogonal duplication amongst various features that I don’t really see.

And no, I don’t think there is a magical chapter in the Big Blue Book on this one…

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 Design. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • I know the exact feeling.

    Actually, what I’ve found is that I really like SRP / DIP way of building apps, but have run into the same complexity that you mention. My inspiration on the point is actually some more framework-kind things, hooking into the rest of the app in a clean and compositional way. I have a few examples from my current project – but actually looking at the FuBuMVC code (and more specifically AltOxite) last week, the whole pipeline idea makes me feel sort of the same way.

    In fact, if we are going into DDD, I think application-centric frameworks as generic subdomains are somewhat in the right direction… Maybe spiffed up with some IOC :-)

    Hope it helps a bit – my random thoughts.

  • Nick Gieschen

    I love the architecture Ayende is suggesting, but it seems dangerously close to BDUF. If your client tells you to implement one feature for which you don’t have a concept, do you go design a concept for it? I’d have to call YAGNI on that.

  • Bill Christie

    I’ve had those very same feelings. Once the complexity of the application reaches a certain point the cohesion seems to disappear in a way that makes it very difficult relate different parts. My gut has lead me to begin investigating the concept of the metaphor that Extreme Programming talks about.

    It seems that the problem comes from being too concrete in class naming and NameSpace organization.

  • @Rasmus

    I’m starting to do that as well – to look towards other applications in a similar space, built by smart people to understand what other architectural ideas are out there.


    I agree. The tough part is to understand and detect when outliers become a pattern unto themselves, and to form a concept around them.

  • I feel like SRP is one of those things where you need to do what makes sense. If you followed SRP to the hilt, you would have lots of classes that had just one public method in it, but you wouldn’t do that in most cases because it would be overkill.

    With SRP, I mainly try and make sure that I don’t have huge “manager” classes that do tons of stuff. Usually when you have those kinds of classes, at some point it gets painful and I realize that I need to split things up, so then I go do it. But I don’t feel like I am consciously trying to make sure that I follow SRP 100% of the time because when I do that I end up overdoing it.

  • @Jimmy,

    I may just be tooting my own horn, here, but I think my ‘Decoupling Workflow’ presentation and sample app architecture may help.

    the massive levels of nesting and double-digit dependency lists, to ensure that all of the dependencies get down to the lowest levels, is one of the things that I’m trying to address in my presentation and sample code.

  • @Jimmy,

    I got halfway through a rather long blog post trying to illustrate why I thought my sample app architecture might help you out, and I just now realized that I’m only illustrating the exact problem that you’re describing… so scratch that last comment. I’m not sure it will help at all.

  • @Derick

    Yeah, I think the answer to this question is that I need to consider an architecture and OO beyond procedural, “this depends on that”.

    To get going, I’m reading Object Thinking and Object Design. It might just be that I need to get better at OO.

  • cYs3tY hepofcbbzhnd, [url=]hkvzevxejfsk[/url], [link=]lycxbsqilvlu[/link],