Design your Software to Manage People as well as Complexity
on
The key to making your software architecture successful is to design it with people in mind. If you architect software projects then you've no doubt heard of the Single Responsibility Principle (SRP).
SRP is often presented with Products/Categories style code examples of how you can easily abstract data access concerns from your business logic. I'm an advocate of keeping my layers of complexity separate but I'm also an advocate of being pragmatic and making tasks as easy as possible to get done.
Yes, we must create suitable abstractions to manage complexity. But we need to put people first.
The Single Responsibility Principle will improve your Software Architecture
Thinking about how we can use the SRP with regard to people adds another dimension to our decision making process. Architecture is about making the big design decisions upfront and so we must try to make decisions that will make our software as easy as possible for the people living and breathing it.
You should design your software to manage people as well as complexity.
Abstracting away database logic is a valid example of SRP but the more I use it the more I realise it runs much deeper than just keeping complex responsibilities separate. What about the responsibilities of the complex human beings involved in a software project? How can architects make projects simpler for everyone involved?
How to design for Single Responsibility
Let's consider a common development team setup:
Looking at each person let's visualise how the software architecture may be defined to allow each person to work without too much involvement with another's responsibility:
Each person in this example is linked to a logical layer within the application. To make a complete system all of these components need to work together but each person can work without conflicting another layer.
- HTML Designer: works in the HTML layer editing HTML markup and CSS.
- Front End Developer: works in the UI layer editing UI related functionality such as validation, dynamic page elements, JavaScript etc.
- Software Developer: responsible for the core business logic. Must be kept away from UI elements or anything aesthetic at all times!
- DBA: works at the database level managing database complexities such as tables and stored procedures.
- QA: creates automated tests with little or no involvement with application code such as unit tests. GUI tools are preferable.
A Real World Example
A recent project I was involved with had a very similar team structure to what we described in the previous diagram. It made use of the MVC design pattern for the UI allowing the HTML Designer to work at the view level and the Front End Developer looked after the Controller, View Model and JavaScript logic. This developer also maintained an HTTP API.
The Software Developers took care of the core business logic that was in its own separate project. They didn't make changes to any UI code.
This team also had a DBA which meant ALL their SQL calls used stored procedures. The DBA worked only in SQL and didn't have to look at a line of code in the business logic project.
QA used automated tools to test the UI and API. In particular QA made use of SOAP UI to create automation tests for the HTTP API taking the task of creating automation tests away from the developer. The developers worked with unit tests leaving the full integration/automation testing to QA.
Each layer had its own suite of unit tests so that developers could verify some form of correctness without having to integrate all application layers e.g. the Front End Developer had unit tests for the UI Controllers that didn't depend on a working core logic implementation.
For Smaller Teams
A smaller team might have a development team that resembles something like this:
In this example the Software Developer is juggling multiple layers. The architecture defined in the previous example might be overkill for this team, so how could we make the Software Developer's job easier in this example?
We could:
- Use an ORM rather than hand crafting all SQL via stored procedures.
- Use the Active Record design pattern.
- Move the core logic into the UI layer so it can be used as a single project.
- Use Integration Testing over Unit Testing so that the developer can test against the full stack rather than writing unit tests for UI Controllers, Business Logic etc.
The point is not to advocate high coupling and poor cohesion in smaller teams, rather to try and think about software layers in the context of people.
The Single Responsibility Principle is not just about keeping complex components separate. It's about allowing people to work separately without conflicting each other.
Additional Content
Watch this presentation from Robert C. Martin from the Norwegian Developers Conference titled: The Single Responsibility Principle.
To see working code for the smaller development team example take a look at Real-World ASP.NET MVC3 from Tekpub.com. The source code that accompanies the screencast is on Github.