In the systems I have worked on in my career, none have been more complex than the software systems I see in the market now. There is constant pressure to add new features and new features get added at a dizzying rate. Some features are so complex that I can barely understand how they are to be used. And it’s not just one company that produces this complexity, software systems seem to be becoming more feature loaded. The systems are just plain bigger with more lines of code than when I started in the industry 25 years ago.
I’m reading a book right now titled “Just Enough Software Architecture and I’ll have a review in a few weeks. But in the first chapter, George Fairbanks discusses ways to deal with software complexity:
Partitioning: This is what the book Universal Principles of Design refers to as Modularity – A method of managing complexity that involves dividing large systems into multiple, smaller self contained systems. My experience with making systems modular is that I often can’t modularize completely in the first iteration of the system. I need to gain knowledge of that system and I tend to break it down into smaller pieces once I learn more. This approach works well when using an iterative process.
Knowledge: This is applying experience of prior problems to the current one. This reminds me of using design patterns. Although this may not be what Fairbanks had in mind, but I liken this to “Design by Committee” as described in the book Universal Principles of Design. This is a group process based on consensus building, group decision making, and extensive iteration. Recently I was involved in an architecture decision we had made that was found to be incorrect. But we weren’t sure. We took an iteration to do some tests, do some research, and then we all reconvened. We applied our group knowledge with our different perspectives to solve the issue, along with iterative research. We came to a final answer that I feel a lot more confident about than if I had done it myself.
Abstraction: Abstraction allows software designers to hide the lower level details when working with the architecture. The definition in Thefreedictionary.com says it means “a concept or idea not associated with any specific instance”. We use abstraction all the time when discussing our design and architecture. It is the only we can talk about the complex systems we work with and is key to communicating software architecture to all the stakeholders involved.
I’m not sure how I would add another category but I find communication to be just as important as the others. Architecture is about communicating what the structure and behavior of the system is, and how the structure and behavior meets the goals. That message must be evangelized to the developers and the business people.
Software Architecture is everyone’s business. The developers often don’t want to get involved with abstractions and the business people often don’t want to or can’t understand the partitioning, but the knowledge of that group, with a software architects guidance, can produce the strongest architecture with the least complexity. This is not easy to do and to get a diverse group to agree but it pays off when problems arise - the group owns the architecture.