Basics: an introduction to software architectures
In the last few pages of our diary, we have demystified some uncertainties that were clouding your perception of server-side elements. With that, we have closed an important chapter in building a strong foundation aimed at comprehending IT terms and methods. Today we are opening the door to the uncharted territory of how/why is software laid in a specific order, or to be more precise software architecture.
Computer programs started small both in size and scope. Old computers that used non-GUI and could only make use of a few megabytes of ram accompanied by low frequencies in CPU power measured in MHz. These were surely a harsh limitation on developing anything that would resemble a modern app. Equipment wasn’t the only imposing obstacle. Programming languages were also basic and somewhat under evolved, hence, their scope at that time was rather narrow.
Nevertheless, engineers pulled through the tides of time with countless breakthroughs as development went on and now it’s feasible to build software that can withstand requests from millions of people in a heartbeat.
Software is a broad term with seemingly unending limitations as long as there is a circuit board somewhere in whatever you’re trying to run on electricity. If you thought software is only related to lines written on a PC for other computers, you’d be surprised to learn that your car, as well as management & billing of electricity, is a relevant software example. Despite these two having a well-segregated scope, at their core, are all about software.
Both share a common thing, endless lines of code divided into hundreds of classes and other elements to facilitate communication between them.
At the start, engineers would draw diagrams to explain how different pieces connect, how they pull & request data or interconnect to achieve a requirement. Early problems could be solved by choosing the right data structures and algorithms, without having to rely on a backbone. It wasn’t until the 1990s that “software architecture” became a thing.
The underlying concept originates from the works of Edsger Dijkstra and David Parnas, pioneers emphasizing the importance of why choosing the right structure matters. This concept was further reinforced in the upcoming years, although the additions were imprecise and disorganized at first, they have been refined into standards.
To once again illustrate the need for software architecture, consider an imaginary case of you being the manager of a construction project. But there is one caveat, the schematics on how the owner would like it are missing. The only thing you know is that they want a type of structure. After you finish guessing the tastes of your owner and sketching an imaginary blueprint with untested measurements, you proceed to start erecting the building in its place. Only to find out that the electricians arrived before your main workers and are currently laying water instead of cement.
Diving straight in
According to Wikipedia, Software architecture refers to the fundamental structures of a software system and the discipline of creating such structures and systems. Each structure comprises software elements, relations among them, and properties of both elements and relations. The architecture of a software system is a metaphor, analogous to the architecture of a building.
In other words, software architecture is the fundamental organization of a system or the wiring of the highest level components. While many might not share the by-the-book definition, another interesting take on software architecture is that it’s a shared understanding of the expert developers on the system’s design. It comprises decisions one must get right early in the project because it would be too costly to change on a whim.
What is the value proposition of good architecture:
- It enables deliverability of high-quality products, with low cruft, at a lower cost.
- Due to the innate concept of code reusability, a good pattern allows for shorter software development turnarounds
- It facilitates adding new features and optimization of existing code
- Excellent communication pipeline between several departments
A software architect must consider:
- To state and comprehend the concerns of the end-user as preaching a choir, anticipating possible options in his behaviour and committing to making a performant, secure and easy-to-use application;
- Account for system administration and provide necessary means to properly monitor the system’s performance;
- Various marketing propositions based on cost, time to market, features, relative position to other products in the industry;
- Deliver clear requirements accompanied by comprehensible approaches for each developer on the team;
Various project management concerns and functionality buffers.The nitty-gritty
An architectural pattern or style is a standardized solution to common problems in software architectures. These patterns address different problems and come bundled with a set of pros and cons. No style is better than the other given an explicit context.
As the aim of this article is to provide an introduction to the world of software architecture and further be used as a trusty anchor when delving into more advanced theory regarding the subject, we will only be touching the surface of widely recognized architectural patterns, since space is a constraint in explaining such concepts.
The blackboard approach consists of three components: Blackboard, Knowledge-source, control. The first component can be considered the heart and acts as central data storage. Knowledge-sources are independent subsystems which contribute to solving the problem on the blackboard based on a condition statement. The control monitors, manages, and schedules changes that take place on the blackboard. This pattern is most suitable for problems that do not have a clear or feasible known solution also called non-deterministic problems, such as speech recognition.
Client-server (2-tier, 3-tier, n-tier)
The client-server architecture brings forward two main definitions: client (remote processes that request data) and server (host machine). This approach partitions the workload and forbids clients from contributing to the resource pool. Therefore, all the important checks and calculations are done by the server without allowing the data to be tempered locally. A well-known example that utilizes said architecture is the World Wide Web itself, check out this article to get a deeper dive.
Component-based Software architectures
Component-based architecture takes a different approach by segmenting different parts of the software into components thus achieving separation of concerns to the range of functionalities the application can employ. A component is an object that can interact with other components of the system, however, it is encapsulated to a degree that hides the direct implementation, yet brings out four main characteristics: reusability, replaceability, extensibility, autonomy.
Data-centric Software architectures
Data-centric architecture has not been clearly defined and leaves room for interpretation. This approach can imply several different meanings, however, it is seen as a preferred pattern for enterprises that want to base their decisions on logical views of data. One thing certain is that data-centric architecture involves relational database management systems and their respective methods of access and manipulation.
Event-driven (or implicit invocation) Software architectures
If you have not guessed it yet, events represent the core of event-driven patterns. They can be defined as any occurred change of the state, for example: when you open a book, you have successfully changed its state from closed to open. In computer software, there are several agents called listeners that check when this change of state occurs and suggest a possible pre-programmed action. Event consumers receive notifications through event channels.
Layered (or multilayered architecture)
The layered style is a subset of the client-server architecture more specifically n-tier architecture. It implies the physical separation of the stacked layers, which can be clearly defined, of an application. We’ve touched on a layered architectural pattern in our previous articles, but as a quick reminder check these out: presentation layer, service layer, business logic layer, persistence layer.
Microservices Software Architectures
Microservices architecture is akin to the component-based pattern as it divides the structure of an application into loosely coupled services that collaborate over a network. It enables the practice of independent work on the services be it: maintenance, testing, deployment, development.
A Monolithic Architecture is the complete opposite of segmented styles. Usually, it involves having everything in one file hence the majestic name “monolith”. This brings about a set amount of drawbacks, as you monolithic systems trade out modularity, which becomes a problem that needs to be addressed when reaching enterprise levels.
If you were to take the client-server model and remove the server you would achieve the P2P software architectures. It emphasizes equal privileges and defines the client as both consumer and contributor to the network. As there is no centralized power to fact-check, security measures are derived to be implemented by the users. This is the desired approach for when you lack resources for a dedicated server as the costs are incurred by the peer of the community.
Representational state transfer (REST)
REST is an architectural pattern that lays out a set of rules on how network resources are addressed. It is by no means a set of standards. Using communication protocols that leave no session information makes it perfect for high volume applications whilst reducing the server load attributed to retaining data. REST enables accessing and manipulating Web resources as textual representations in a unique way through a minimal set of commands.
A rule-based software architectures consists of four basic components: rule base (a defined knowledge base which encompasses close to all rules regarding the subject matter at hand), inference engine ( produces the necessary action based on the input and rules defined in the knowledge base ), working memory (the cognitive system that holds temporary information), user interface (enables input and output signals to be accepted)
Shared nothing architecture(SN)
SN is a distributed-computing architecture that involves having a network of nodes independent of one another that communicate through an interconnection network. As every node’s resources are segmented, this approach eliminates single points of failure and contention. It is a successful architecture due to the ease of scaling just by adding additional nodes into the network.
Space-based architecture (SBA)
SBA aims to achieve linear scalability akin to the SN architecture pattern through the usage of the tuple space paradigm. “The space” can be considered a form of distributed shared memory, thus allowing concurrent access to matching pieces of data from the memory space. Applications are built out of self-sufficient units, known as Processing Units (PU), that can be scaled due to the innate independence. Think of having one big warehouse instead of multiple specialized warehouses.
The difference between architecture and design
As the line between software architecture and design is quite blurry it may lead to some confusion and mix up between elements of both sides. It is paramount we are clear on any of these misconceptions.
Yet again the definition of software architecture is the structuring of a system to fit a unique business proposition at the same time employing four basic characteristics: reusability, scalability, flexibility, security. Therefore, an architecture pattern or style is a commonly used approach to solving a business demand.
In contrast, software design is responsible for code design and answers the questions of what each module is doing, the scope of methods and functions, etc. The SOLID principle intends to make software design patterns more understandable:
Single Responsibility Principle – A class should have only a sole purpose, a responsibility and a reason to change.
Open Closed Principle – A class is open to any extension factors, however, it is prohibited in modifying any existing functionality.
Liskov substitution principle – Implies the usage of inheritance in such a way that the inherited class (replicated functionality) must not alter the behavior of the parent class in a way that might break the application logic.
Interface Segregation Principle – Since a class can implement multiple interfaces, it is in good reason to use many specific interfaces as opposed to a single general-purpose one.
Dependency Inversion Principle – Invokes the usage of abstractions by changing the dependency relationship between software modules.
To sum up
As the size and complexity of software architectures increases, data flow and handling need to be clearly defined lest you lose them in silicone, thus laying down an overall system structure becomes one of the main concerns. It involves a whole new plethora of communication protocols and element re-distribution be it in functionality, scaling, or reusability. Software architecture takes its name from civil architecture
See how we have perfectly designed this piece of text to flow right into the button down below?