Every time we write a bit of code we implicitly use some kind of software architecture. There's not a single topic I've spent more time discussing than software architecture; for future reference, this is my opinion about it and how it relates to Software Design and Design Patterns.
So, what is software architecture? Wikipedia defines it as
(...) the fundamental structures of a software system, the discipline of creating such structures, and the documentation of these structures.
Spot on! It's how to create something more than trivial without making it complicated. And that's actually really hard.
For starters, writing code is not the hard part about creating software. Most people in the industry are able to write at least simple code snippets without failing miserably – given the right constraints and adequate training.
Software architecture is a completely different aspect. It's the ability to reason about a possibly complex problem and coming about with a sane process and plan for how to solve it in terms of the overall strategy. Architecture is both the process and the product. To put it in simple terms, it's the architecture that defines the number of rooms and their functions. It's a design detail how those rooms are built as long as they are rooms – everything else is irrelevant from an architectural point of view.
Software architecture is constrained by a lot of things. Some of these constraints are called requirements, others are imposed by different factors – like the team's familiarity with a certain stack.
Defining the basic building blocks of a system, thinking about their interactions and making decisions based upon that thinking is the basic task of a software architect. The ability to do just that requires both a solid understanding of the underlying constraints as well as deep knowledge about how problems can be solved; combining the two is the tricky part. Good software architects tend to have some traits that help them get their job done well. To be clear, I'm not referring to myself as a good architect.
Being certain is a great trait. It's the opposite of being right. There are countless opportunities in each and every piece of software to make brutal mistakes, the least one would expect is some humbleness. I make mistakes every day. Sometimes, I make big ones. None of those are intentional. The lesson here should be to approach the job with some humbleness. Being right is the opposite of being humble, it shuts down most discussions and leaves options uninspected. Being certain on the other hand communicates the product of a thought process that's being presented – without using the glory of the role or the hierarchy as a lever.
Having an open mind is mandatory. There's always at least two options, in most cases much more. Forcing oneself to evaluate even ridiculous ideas might not always be the first intuition, but it's a necessity when holding this job title. This openess often shows in the language used – be wary of using terms like must, never, only, need and no. Unless you have an absolute understanding of all the constraints and all possible solutions, communicating false certainty is just arrogant or judgemental.
Great architects should always assume themselves to be the biggest risk. Plan like every decision you make is wrong. Create a flexible system that can react to change. You want to be prepared for change. It's not only likely to happen, it's inevitable. The mode of being prepared to overthrow a two-week old conviction because you realized you were wrong is the overall humbleness at play.
But why have an architect and an architecture in the first place? True, there are a lot of places where the only sign of architecture is its absence. Those are not good places. As stated above, architecture is implicitly present even when not actively 'using' one. The problem is just that architecture is happening to you – and not emerging as the result of a planned, conscious effort. And as systems grow more complex, unorganized ones tend to become complicated.
In our modern world, software can be a precious asset. It can also be, and too often is, a liability. Software turns sour when there's no easy way to react to change, when no one knows why things are the way they are. Architecture tries to limit moments like that by outlining a structured path to solving problems.
How does software architecture relate to design patterns? A lot. If your office or apartment is above the ground floor, how did you get there today? You probably used either stairs or an elevator. The person responsible for planning the place didn't come up with a rocket chair that propels people up to the third floor. He or she didn't probably think about the topic too much because there are common solutions for enabling people to move to different stories. Stairs and Elevators. Using those are design patterns.
Not all design patterns apply to the domain of software architecture – common wisdom dictates that architectural patterns do, such as the infamous Model-View-Controller or Microservice pattern.
What's your understanding of MVC as a pattern? Let's assume for a moment that it's similar enough to mine for us to have a shared understanding of how to apply it in the context of a particular problem. And that's the key: Patterns are a language and thus establish a way to quickly and unambiguously solve problems without reinventing the wheel. It makes life easier. And this is the part where caution is warranted: familiarity with a particular solution model or design pattern can lead to the well-known 'if your only tool is a hammer, every problem is a nail'-situation.
I tend to view architectural patterns as a great way to communicate ideas and to form a mental model of a particular solution. But patterns are just guidelines, ideas, generalizations that need to be tailored to the problem of the day. Blindly applying off-the-shelf solutions has led to some questionable results a few years ago in the J-based community. It's the job of an architect to moderate the process from pattern to individual solution. Or to throw the pattern out and come up with something better. Maybe a rocket chair isn't the worst idea at all.
But what and where's software design in all of this? There are a few opinions on that. Some say that software design is just about the detailed implementation below the level of interfaces. Others say that software design is the process that includes software architecture, while different others are sure it's another way around.
It really doesn't matter. While I tend to view it as everything 'below' architecture – just for the sake of knowing when to stop making architectural decisions – whatever works for you is great. The important point is to understand that telling someone how to write 5 lines of code is not architecture. It might derive from it in a way, it might even be software design, but it's certainly not your primary job to do.