Many ideas behind software architecture has been developed from the fundamentals of mechanical and building construction experiences, because “building software” had analogies in construction of buildings. There is an idea of what the system should do (building spec or functional requirements), how the system should look (design), what the system is internally represented as (blueprint) and how to go about constructing it (waterfall methodology). Many theories stem from this base – architecture, blueprints, waterfall, strategy, review – all these are terminologies that go back to construction work.
Somewhere along the way, a realization dawned that software architecture is not really like house construction. The analogies break down pretty soon as the analysis go deep – software does change as it is built, building a house does not. You cannot plan software to the absolute last detail, but the house construction is. The obvious reason is, in creating a software, change is less expensive and damaging than the house creation, during the construction phase. It is easy to change a variable, name, algorithm compared to breaking the drywall and replacing that electric wire. At best, software development is like building a Lego model – add, remove, swap pieces until you feel its right, the expense of rebuilding is limited – only about the labor and not much about the materials.
From this realization, alternative approaches have sprung – agile, scrum etc. where change to software is presumed as a necessity and the efforts is not to curtail the change, but to apply them in a controlled manner. With that also comes the extrapolation in thought that software design is not a predecessor to development, but happens along with its development. Also the thought that architecture is emergent, evolving and is felt to be finished only as a time-bound specification.
I think the fundamentals of software architecture is much closer to another field – Linguistics. Spoken language is a remarkably fascinating system where humans learn how to communicate effectively with each other. Think about it – two persons, growing up in completely different parts of the world, different culture, different backgrounds and different thought processes are still able to exchange their thoughts, as long as their communication channel is the same language, like English for example. Well, except for the accents.
What is it that makes two people understand what they say to each other? Let me rephrase that in a more elaborate way – What is it that makes one person think that he (she) ensured that the intention in what was spoken is what the second person really understood as intended? In other words, what is behind the reasoning, that you understood what I intended?
That reasoning of a sentence is provided by grammar of the language. Grammar did not evolve before the language, instead it evolved from the language, but once evolved, it scaffolds the language and ensures that it stays valid. The intention behind what I want to say and ensure that it is understood by the second person as intended, is reasoned by the grammar of the language – by how I use the language’s Quality Attributes – nouns, verbs, prepositions, objects, adverbs, adjectives etc. – these scaffold the language for that intention. When I make a grammatical error, it is immediately evident that something is not valid. In effect, the grammar puts a constraint around a language to justify and reason so that it makes sense.
Software Architecture should behave exactly the same way – it should evolve from the underlying systems (from programming languages to os to network protocols etc.) and then in-turn scaffold the system by constraints. Just like there is little room for the language to evolve arbitrarily, because grammar provides the check, once a software system is developed, its architecture should provide the reasoning and justification on how the system should behave. But languages do change overtime (albeit slowly) and acquire new meanings and new constructs. Nouns become verbs, new verbs are created and then the new constructs are justified by expanding the grammar. Similarly a system does change overtime and its architecture should expand to provide scaffolding back to the system and justify it. An effective communication is established with a well defined style of writing (good grammar), a software architecture is well communicated only when it is well documented. Yet, just like even a well defined style of writing is not sufficient to ensure that the intention is understood, a good documentation alone is not sufficient to ensure that a system will be understood correctly. Only experience enhances the understanding.
Software architecture is an abstraction of underlying systems, just like grammar is the abstraction of a language. If product is a book, application the story, modules the chapters, marketing the cover, development the language, unit testing the spell-check, testing the proof-reading, printing the production, architecture is the grammar of software systems.