Software Development Process 7 | Software Architecture, Software Architecture Examples, and…

Series: Software Development Process

Software Development Process 7 | Software Architecture, Software Architecture Examples, and Software Architecture Styles

  1. Software Architecture

(1) The Definition of Software Architecture (SWA) by Perry and Wolf

The definition of SWA by Perry and Wolf is a combination of elements, form, and rationale.

  • What: the elements are the what, which means the processes, data, and connectors that compose a software architecture
  • How: the form is the how, the set of properties off in relationships among these elements
  • Why: the rationale is the why, the justification for the elements and their relationships

(2) The Definition of Software Architecture (SWA) by Shaw and Garland

They defined software architecture as a level of design that involves four main things,

  • a description of elements from which these systems are built
  • the interactions among those elements
  • the patterns that guide their composition
  • the constraints on these patterns

(3) The General Definition of Software Architecture (SWA)

The general definition of SWA can be defined as a set of principal design decisions about the system, where principle here, implies a degree of importance that grants a design decision architectural status. The bottom line is that if you believe that something is an important design decision, it becomes an architectural decision.

(4) The Functions of the Software Architecture (SWA)

We can see a software architecture as the blueprint for a software system, that we can use to construct and evolve the system. And the key point about software architecture is that this blueprint encompasses every facet of the system under development including,

  • the structure
  • the behavior of the system
  • the interactions within the system
  • the non-functional properties of the system

(5) Temporal Aspect for SWA

Another important point about SWA is that there is a temporal aspect to it, which means you don’t build the software architecture in a single shot, but you do it iteratively over time. So, basically, you go from having no architecture to your final architecture, and the architecture is expected to change over time. This happens because design decisions are made, unmade, and changed over a system’s lifetime.

(6) Prescriptive Vs. Descriptive Software Architecture

A prescriptive architecture captures the design decisions that are made prior to the system’s construction. This is what we normally call the as-conceived software architecture.

Conversely, a descriptive architecture describes how the system has actually been built. So it’s based on observing the system as it is and extracting the architecture from the observation. This is what we call the as-implemented software architecture.

(7) Architectural Evolution

Ideally, when a system evolves, its prescriptive architecture should be modified first. When you modify a building, you change the blueprint and then you change the actual building. In software, unfortunately, this rarely ever happens in practice. What happens is that the architecture as conceived does not change, whereas the architecture as implemented, does change. This really happens for a number of reasons,

  • Developer’s plain sloppiness
  • Preception of short deadlines
  • Lack of documentation

(8) Architectural Degradation

There are two important and related concepts that have to do with the way a software architecture evolves,

  • Architectural Drift: the introduction of architectural design decisions that are orthogonal to a system’s prescriptive architecture (e.g. adding pieces without a clear plan)
  • Architectural Erosion: the introduction of architectural design decisions that violate a system’s prescriptive architecture (e.g. decisions that don’t comply with the prescriptive architecture)

Sometimes, architectural drift and erosion gets you so far away from the point where your software architecture should be, that your architecture is completely degraded. And at this point, you have two main options,

  • Keep frantically tweaking the code: typically disastrous. The best way to repair a degraded architectural design is to first, understand the current architecture, and then, try to fix it in a more principled way as follows
  • Derive and fix the software system: normally called architectural recovery and this is recommended

2. Software Architecture Examples

(1) Linux Kernel

The first example I want to use is an example from the early version of the Linux kernel.

Source: https://docs.huihoo.com/linux/kernel/a1/index.html

The figure on the left is the software architecture at the level of Linux’s main subsystems. So this is the prescriptive architecture of Linux at the level of Linux’s main subsystems. The researchers then studied the source code of Linux and reverse engineered its actual architecture. So they determined the architecture as implemented (i.e. descriptive architecture), and this one here, on the right, is the result.

Actually, they found a number of differences or violations between the prescriptive architecture and the descriptive architecture. So the bottom line here is that not even the developers realized how the actual architecture of the system was, and how it was different from the architecture they have conceived.

(2) iRods

Next up, let’s see the architecture of the iRods system. This is a data grid system that was built by a biologist and it’s a system for storing and accessing big data.

Source Left: Here ; Source Right: Here

So here, even if we don’t go in and look at the details, you can see very easily that the system is badly drifted and eroded.

(3) Hadoop

As many of you probably already know, HADOOP is an open source software framework for storage and large scale processing of data sets. Because this architecture is so broad and so intertwined, it may not be clear to view. But also, in this case, you don’t really have to look at details.

Hadoop Complete Architecture

The important point here is that in this architecture 61 out of the 67 components in the system have circular dependencies, which means that they depend on each other in a circular way and this is normally not a good thing. Also, in this case a few developers when shown the diagram had no idea that the structure of the system was so complex and messy.

(4) Bash

Bash is a Unix shell written as a free software replacement for the traditional Bourne shell, also called sh.

Bash Architecture

And if we look at this architecture, two design problems of the component can kind of jump at us,

  • Lack of cohesion within the component: only a few connections exist between the sub-components
  • High coupling: component has tons of connections with other components

So basically, this component has low cohesion and high coupling, which is exactly the opposite of how a good design should be.

3. Software Architecture Styles

(1) The Defintion of Architectural Elements

A software system’s architecture typically is not, and should not be, a uniform monolith. On the contrary, an architecture should be a composition and interplay of different elements. As we have mentioned before, there are three main types of elements in an architecture,

  • Processing elements: implement the business logic and perform transformations on data
  • Data elements: elements that contain the information that is used and transformed by the processing elements
  • Interaction elements: the glue that holds the different pieces of the architecture together

The processing elements and the data elements are contained into the system components, whereas the interaction elements are maintained and controlled by the system connectors.

(2) The Defintion of Components

Components and connectors get all cooked together into a systems configuration, which models components, connectors and their relationships. A software component is an architectural entity that encapsulates a subset of the system’s functionality and/or the system’s data. Therefore, components typically provide,

  • Application specific services
  • Restricted accesses to the subset via an explicitly defined interface
  • explicitly defined dependencies on its required execution environment

(3) The Definition of Connectors

In complex systems, interactions might become more important and challenging than functionality. And this is why connectors are very important architectural elements. A software connector is an architectural building block tasked with effecting and regulating interactions among components. So basically, connectors typically provide,

  • application independent interaction facilities
  • services as procedure calls or shared data accesses.

(4) The Defintion of Architectural Configuration

But consider that much more sophisticated and complex connectors are also possible. And components and connectors are composed in a specific way in a given system architecture to accomplish that system’s objective and this is expressed through an architectural configuration. More precisely, an architectural configuration, or topology, is a set of specific associations between the components and connectors of a software system’s architecture.

(5) The Definition of Architectural Styles

There are certain design choices that when applied in a given context regularly result in solutions with superior properties. What this means is that, compared to other possible alternatives, these solutions are more elegant, effective, efficient, dependable, evolve-able, scale-able, and so on. Architectural styles capture exactly these solutions. As it is defined by Mary Shaw and David Garlan, architectural style is,

  • a family of systems in terms of a pattern of structural organization
  • a vocabulary of components and connectors
  • constraints on how this components and connectors can be combined

So in summary we can say that an architectural style is a named collection of architectural design decisions applicable in a given context.

(6) Benefits of Architectural Styles

It is important to study and know these architectural styles for several reasons,

  • Knowing them allows us to avoid reinventing the wheel.
  • It also allows us to choose the right solution to a known problem

(7) Types of Architectural Styles

Let’s see some of the architectural styles now,

  • Pipes and filters: pipes and filters indicate an architectural style in which a chain of processing elements, which can be processes, threads, co-routines, is arranged so that the output of each element is the input of the next one and usually with some buffering in between consecutive elements (e.g. Unix)
  • Event-Driven: an event-driven system, typically consists of event emitters, like the alarm over here, and event consumers, like the fire truck, down here, and consumers are notified when events of interests occurred and have the responsibility of reacting to those events (e.g. Groovy)
  • Publish-Subscribe: an architectural style in which senders of messages, they’re called publishers, do not send messages directly to specific receivers. Instead, they publish messages with one or more associated texts without knowledge of who will receive such messages. Similarly subscribers will express interest in one or more tags and will all receive messages of interest according to such tags (e.g. Twitter)
  • Client-Server: the server provides the resources and functionality. And the client initiates contact with the server, and requests the use of those resources and functionality (e.g. email)
  • P2P (i.e. Peer-to-peer): a type of decentralized and distributed network system in which individual nodes in the network, that are called peers, act as independent agents that are both suppliers and consumers of resources. This is in contrast to the centralized client-server model, where client nodes interact with the central authority (e.g. Skype, Napster)
  • REST: a hybrid architectural style for distributed hypermedia systems, that is derived from several other network based architectural styles and that is characterized by uniform connector interface

Now let’s see some typical examples,

  • Android: Event-driven & Publish-subscribe
  • Skype: Client-server & P2P
  • World-Wide Web: Client-server & REST
  • Dropbox: Client-server

(8) P2P Example: Napster

Napster was a peer-to-peer file sharing system. It was mostly used, actually, to illegally share MP3s, which is also why it got used, and later on, it basically ceased operations. Now, let’s see the basic configuration of Napster and the interactions between its elements.

  • We have Peer A that will start by registering, here, with the content directory
  • Peer B will also register with the content directory.
  • And when these two peers register, the content directory will know what kind of content they can provide
  • Later on, Peer A will request a song
  • At this point, after Peer A has requested the song, the peer and content directory will look up its gigantic index and will see that Peer B actually has the song that Peer A requested
  • If Peer B actually has the song that Peer A requested, it will send to Peer A a handle that Peer A can use to connect directly to Peer B
  • After getting the request from Peer A, then Peer B will start sending the content to Peer A