Thursday, May 19, 2011

What is Software Architecture and How Can We Share It?

An instructor friend recently asked me for tips on how to introduce his students to his bag of architectural best practices.  This wily old veteran of the software trenches is well aware that he has a multifaceted challenge on his hands.  He knows that it is hard to talk about architecture yet it's important for his students to understand.

Let’s start by agreeing on what software architecture is, at least what it is in this conversation.

Clements and Kazman define architecture as:
"...the structure or structures of the system, which comprise software elements, the externally visible properties of those elements, and the relationships among them.   Architecture is concerned with the public side of interfaces; private details of elements - details having to do solely with internal implementation - are not architectural."
This definition resonates with me because it scales to the very small and the very large.  It also makes it clear that when you create a public element you are making an architectural decision.  This fits whether we are building an API, a set of web services, a class, or an output variable in a function.

This definition also includes one of the most important parts of architecture - the relationships among the elements.   More specifically, “relationship” refers to dependencies between elements.   Experienced developers know that the single most important thing you can do to keep your software agile and maintainable is to understand and manage the dependencies.


So, we've defined what software architecture is, now let's look at why we care.

Architecture should help us with the following :
  • Expose the structure of the system but hide the implementation details
  • Realize all of the use cases and scenarios
  • Address the requirements of the stakeholders
  • Ensure both the functionality and the quality requirements

From this we can form a working definition which combines the what with the why.
"Software architecture is the collection of public structures, and the relationships between them, which help our software realize our use cases and scenarios, address the needs of our stakeholders, and ensure that the functionality and quality requirements are met."
I like that definition.  I think we can use it to build a framework for communicating software architecture.

In practice, most software architecture gets implemented using the available component mechanisms (XAP, DLL, JAR, GEMs, modules) and/or a collection of design patterns.  Take another look at the definition - the first half is concerned with structure and dependency management, the second half is with delivering value, functionality, and quality.   The popularity of design patterns and the use of component mechanisms have made it very easy to fall into the trap of mastering the first half of architecture and forgetting about the second half.

I think this explains why communicating about architecture is difficult.  You have a lot of very smart people that have been exposed to the first half and understand it very well, but from an architectural point of view they have yet to master the second half.   Let me use the "use case controller or facade" as an example.

I'm a big fan of separating use case logic into a controller or a facade so that decisions about how the use cases are implemented are explicit.  Usually this use case controller is implemented as a light weight facade.  It is usually one class with method names that closely match the use case steps.  This class represents the structure from the first half of our definition and the manifestation of the goals expressed in the second half.  All developers seem to understand the first half, it's the second half where trouble starts.

The developers with whom I've shared this approach have fallen into two camps.  Camp one: those that don't do use case analysis and can't understand why I would want such a thing, and camp two: those that do use cases and nod, saying "Cool, that's a great way to organize the use case logic - in the past, I've done something similar."

It's become clear to me that many developers are using design patterns and best practices as a way to speed up their development, organize their work and to manage dependencies, but they have missed the part about the goals associated with software architecture.  They have not mastered the second part of our definition and you can see it in their code.

From a technical point of view their code is very good, but when I start asking about how a feature or use case is implemented, things get a bit murky.  You know the response, you've heard it before - it's a long technical ramble - something like:
"Well this event signals to the event monitory which sets a flag and when a certain time has passed the poll-er checks the flag and it calls this code we've injected as a delegate using this fluent interface on a component we got from our dependency injection container during system startup and then..."
At this point I stop them and point out that they've been rambling on about technical details - important, but technical.  They haven't mentioned (and probably were not going to mention) a single business term.   They've built software which may work but they've made it so technically convoluted that you can't see the forest through all the trees.

When you create a use case controller, you can point right at the method or methods that make up a use case.  Many developers do not understand the value of this approach.   In fact, they will often say it "gets in the way."   I'm quick to point out that their software supposedly performs the use cases so the functionality is in there somewhere.  I ask them how do they test that their software meets the use case requirements?  [Be careful here - by asking this question you've just crossed a line.  There is a good chance they are about to be embarrassed.  They may begin to hem and haw about test plans, QA, the lack of time in the schedule to do proper testing and a bunch of other baggage.  You may not be popular if you dig any deeper.  This is a predictable outcome of not understanding the second half of our definition.]

They've mastered half of architecture - the creation of structures and dependencies.  They may have also benefited by some of the quality and speed gains that can be had when architectural best practices are followed.  Software patterns are tried and true solutions, but many of them solve technical problems, not business problems.   Our definition of software architecture says very little about technical problems but a lot about business goals, functions, value, and quality.  The visibility of structures that implement purely technical solutions should be decreased and the visibility of business oriented components increased.  Unfortunately it's more common to see the opposite.

My recommendation to my instructor friend was that he start by explaining to his students the context for each of his architectural insights.  The context should include a clear statement of what business problem is being solved by the architectural insight.  Both Martin Fowler and Eric Evans have done great work in this area and lead by example.  When Eric Evans explains why he would create a "technology isolation layer" it is very clear why our solution might need one.  When Martin Fowler talks about why we should use a Repository or a Facade he starts explaining the context and problems these patterns help to solve before he explains how someone might build them.

Special care should be taken to explain how the context applies to the second half of our definition - the use cases, the stakeholder's needs, and the functionality and quality requirements.   This is not always easy for those of us that work with technology for a living but if you are having a hard time explaining how your architecture helps with these issues you should probably be rethinking your architecture.

After the students understand the context, then he can explain the patterns and practices he uses to build the software structures and relationships.   Along the way, he should explain how these patterns and relationships reveal the use cases and exactly where they help to meet the needs of the stakeholders, and help to ensure that the functionality and quality requirements are met.

That's a start anyway.

No comments:

Post a Comment