Drawing boundaries

For the last nine months, I’ve primarily worked on an integration systems project, where my “User Interface” are things like flat files deposited on various SFTP servers, calls to web services, “RESTful” web services and so on. If there’s one thing from moving to a ginormous MVC application (2-300 controllers, 6-700 actions) to a system with NO user interface other than a thin customer service application, one thing that’s stayed constant in my experience with these system is the importance of drawing system boundaries.

The MVC application took the concept of a single, synchronous domain model to its just about maximum reach. When I first started on this current system, it was just about in the exact same place. But the problem that I ran into in both situations is that drawing the context boundaries that Evans laments should have come first in his Domain-Driven Design book.

We saw this in the MVC application, where we created a big board of user personas, like Larry the Barista and Carrie the Cashier. What was interesting about this exercise was that we separated the 30 or so personas into areas of concern, by color. As we closed the project, one of the most interesting aspects of these colors were that each area of concern reasoned about the domain in entirely different ways. There were similarities of course, but we found that by and large, the colors represented common reasoning about business processes and needed the domain distilled in different ways.

Fast forward to today, and we find that rules applied to one color don’t apply to another, and in general our highly intelligent domain model serves too many masters.

What we missed was drawing boundaries and separating our application into distinct areas of concern.

Applying boundaries

These days, my first question about applying a new feature to our system is “what component should be responsible for this logic”. Not class, but individual deployed component.

One example is that we’re transitioning our FTP sending from scheduled batch jobs that poll directories, to a push model where I send an NServiceBus message “PutFileToFooBucksMessage” on the bus, and the originator simply fires and forgets:

Bus.Send(new PutFileToFooBucksMessage(csvFilePath));

When the process sends this message, it continues on its way. The component that builds the file is separate from the component that actually sends the file using SFTP. Conceptually it’s similar to calling a method, as I’m coupled to an endpoint and contract, except it’s now asynchronous.

What’s really cool is that the FTP agent is a completely separate deployed component, started out with “File->New Project”, carrying none of the intellectual weight of the domain, and only containing the logic on how to FTP files. It knows how to do that, and only that.

In the past, I would have put this logic in some sort of Infrastructure project, but these days I tend to draw strict responsibility boundaries, so that one deployed component doesn’t need to know any of the How, but just the Who.

So far, I’m really impressed with how conceptually easier it is to reason about a system where the deployed component consists of only the things it needs to operate. Also, it opens many more architectural doors. Want to use stored procedures in that autonomous component? Who cares! Straight SQL? Who cares! Document databases? Go for it!

An architecture that divides responsibilities into distinctly deployed, autonomous components maximizes the technology options for each component because of the reduced system coupling. And that’s a good spot to be in.

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 DomainDrivenDesign. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • I think that FTP agent has well known about this component.. This component useful for SQL database.. Thanks for this..

  • Great thoughts, Jimmy. I’m also finding on my more recent projects that having good solid boundaries between contexts makes working with that component so much easier.

  • This post sounds like it came right out of Udi’s Advanced Distributed Systems Design course (highly recommended). We have begun identifying domain boundaries on our site and creating small, autonomous components that when assembled together make up a page. Literally a single “widget” on the page knows how to go end-to-end (UI to DB) in order fulfill its specific purpose. Talk about flexibility and decoupling; also faster, smaller, easier deployments that are happening more iteratively and more often. We don’t have it down to a science and probably won’t for a while, but it’s really growing on us and I think we’re headed in the right direction.

    Interestingly enough, as we were deciding on the architectural direction we wanted to head after taking Udi’s course, Jeremy started implementing his packaging solution for FubuMVC (“Bottles”) that is now working wonderfully with this type of system design.

    • Anonymous

      Bingo :)

  • jdn

    This is really well thought out. I think I’ve been doing it wrong.

  • Joe Future

    This sounds a lot like behavior-based robotics and the emergent “intelligence” that can be observed in robots when distinct/independent behaviors happily go about doing their own thing, unaware of the combined effect they’re having on the overall system.