All systems are designed to achieve some human purpose: The web application Facebook connects people in a social network, an aircraft transports people long distances. A Boeing spokesman once quipped, “We view a 777 airliner as a collection of parts flying in close proximity.”
The job of a systems architect is to manage the design of these complex systems, and systems of systems such as the 777, to make sure that when put into service a particular system fits its assigned purpose and that none of its parts “break formation” to cause harm to people or property.
System design is the process of defining the hardware and Software architecture, components, modules, interfaces and data for a system to satisfy specified requirements. So simply put, system design is the process and system architecture is one of the results of system design.
System architecture is a conceptual model that describes the structure and behavior of multiple components and subsystems like multiple software applications, network devices, hardware, and even other machinery of a system.
There are a lot of parallels between software architecture and what most people think of architecture when it comes to building buildings. Architects, no matter which field it is, are that interface between the customer, what they want, and the contractor, the implementer, the person building the thing. And it’s always too across all architecture that bad architectural design can’t be rescued by good construction.
Architectural descriptions deal with complexity by decomposing systems into design entities such as sub-systems and components. Architectural blueprints describe this decomposition in terms of physical and logical structures, their components, their interfaces and the mechanisms they use to communicate both internally and with external systems and human beings.
What we really care about is partitioning large systems into smaller ones. And these smaller systems still individually and independently have business value. And that they can, supposedly,
if they’re written properly, be integrated with one another and other existing systems very easily. It is taking the entire large system and partitioning it into smaller ones that may or may not be individually built by your team. Or contracted out for build by someone else and then we merely integrate them into our system.
One of the reasons why we decompose systems into these components that are independent is so
that we can talk about parallelization. Who and what team are going to work on, project-manage, actually develop and test individual still potentially large sets of software that will eventually be integrated into this very large scale system.
In engineering, hardware architecture refers to the identification of a system’s physical components and their interrelationships. This description, often called a hardware design model, allows hardware designers to understand how their components fit into a system architecture and provides to software component designers important information needed for software development and integration. Clear definition of a hardware architecture allows the various traditional engineering disciplines (e.g., electrical and mechanical engineering) to work more effectively together to develop and manufacture new machines, devices and components
In computer science or software engineering, computer software is all information processed by computer systems, programs, and data. Computer software includes computer programs, libraries, patches, and related non-executable data, such as online documentation or digital media.
Software architecture refers to the process of creating high level structure of a software system. It is about the complete structure/architecture of the overall system means it converts software characteristics like scalability, security, reusability, extensibility, modularity, maintainability, etc. into structured solutions to meet the business requirement. Multiple high-level architecture patterns and principles are followed during defining architecture of a system. It mainly focuses more on externally visible components of the system and their interaction with each other.
The software has two categories of requirements. First, there is a need for a function that defines what the software should do. We usually refer to it as functional requirements and document it as FSD (functional specification document).
The second is the quality that must be provided by the software. We call this the quality of service requirement or quality of attributes. For example, these attributes are scalability, availability, reliability, performance, and security. Some attributes are defined as qualities during the development process, such as maintainability, testability, and employability.
Describing an Architecture
An architecture description is a formal description and representation of a system, organized in a way that supports reasoning about the structures and behaviors of the system. A system architecture can consist of system components and the sub-systems developed, that will work together to implement the overall system.
Architectural structures are described in terms of:
The physical arrangement of components
Logical arrangement of components usually with a layered architecture model. At the next level of detail, assuming an object-oriented approach, this arrangement may be fleshed out with object models such as class diagrams, communication diagrams, and sequence diagrams.
Physical arrangement of code. For software-intensive systems, the architecture maps the various code units onto the physical processors that execute them and describes the high-level structure of the code.
System Interface. A system architecture primarily concentrates on the internal interfaces among the system’s components or subsystems, and on the interface(s) between the system and its external environment, especially the user. In the specific case of computer systems, this latter, special, interface is known as the human-computer interface, or HCI; formerly called the man-machine interface.
Component interfaces. Interactions between components including, communications protocols, message structures, control structures and synchronisation. The scope of interfaces also includes the modes of interaction with human operators and the associated human factors.
System behaviour. The dynamic response of the system to events. System behaviours are typically described with use cases that illustrate how various components of the architecture interact to achieve some required result.
Design styles. Selection of appropriate architectural styles and design patterns. For example, client/server model, supervisory control, direct digital control, pipe and filter architectural style, layered architecture, model-view-controller architecture. The rationales for design decisions are also recorded.
Allocation of system requirements to components. Detailed mapping of all system requirements to system components.
There have been efforts to formalize languages to describe system architecture, collectively these are called architecture description languages (ADLs). A system architecture can be broadly categorize into centralized and decentralized architectural organizations.
Describing the Nonfunctional Characteristics of the Architecture
An architecture description also indicates how nonfunctional requirements will be satisfied. For example:
Specification of system/component performance. For example, data throughput and response times as a function of concurrent users.
Consideration of scalability. For example, can an air traffic control system designed to manage 100 aircraft be extended to manage 1000 aircraft?
System availability. For example, elements of the design that enable a system to operate 24/7.
Safety integrity. Elements of the design reduce the risk that the system will cause (or allow causation of) harm to property and human beings.
Fault tolerance. Elements of the design that allow the system to continue to operate if some components fail (e.g. no single point of failure).
Consideration of product evolution. The facility for individual components to be modified or dynamically reconfigured without the need for major modification of the system as a whole. Further, the ability to add functionality with new components in a cost effective manner.
Consideration of the emergent qualities of the system as a whole when components are assembled and operated by human beings. For example, can the missile launch system be effectively operated in a high stress combat situation?
Software Architectural patterns and models
When we talk about architectural patterns and architectural schools of thought, we’re talking primarily about enterprise-level software. Architecture at a small scale usually isn’t all that big a deal. But as soon as you start getting into even moderately sized pieces of software in an enterprise, you have to deal with these kinds of issues. Including, where are we going to get
the money, the budget to pay for the developers, the project managers, the designers, the testers and beta testing, user testing, acceptance testing, to actually make sure that this project is a success? All of that has to come from upfront because you need to secure the funding to do that. So software architecture is about looking at those components, determining how to separate them in order to actually make it at all practical that you’ll solve the solution in any way.
So there’s a variety of models that have become essentially go-to best practice models for
a number of different common problems. So these models are effectively best practice solutions for commonly occurring problems at the enterprise level.
There are many different architectural styles, including layered architectures, object-based, service-oriented architectures, RESTful architectures, pub/sub-architectures, and so on.
Pipe and Filter Architecture
Pipe and Filter is another architectural pattern, which has independent entities called filters (components) which perform transformations on data and process the input they receive, and pipes, which serve as connectors for the stream of data being transformed, each connected to the next component in the pipeline.
One scenario where the pipe and filter architecture is especially suitable is in the field of video processing, such as in the media-handling library, GStreamer. In video processing, a unprocessed video undergoes a series of transformations to become a processed video that can serve a more useful purpose. One example of this is in the real-time object detection from a live cameras.
In the example use case illustrated above, the image frames from the live video recorded serve as the input data and are sent into the application via the data source. Once in the pipeline, the data is transported via pipes between each component.
From the data source, the data goes through a series of filters sequentially, each processing the data to make it more useful for the next filter order to achieve the eventual goal of object detection. Eventually, the processed data, which in this case is the input image frame with bounding boxes drawn around objects of interest, is served as the application’s output in the data sink.
This Pipe-and-Filter architecture is particularly useful in those cases where we may want to expand, parallelize, or reuse components across large systems like this. So that’s one focus in architectural style that can be applied to something like this. And you see that, for example, in compilers. Compilers, for example, will have things like logical analysis, pair parsing, semantic analysis, and code generation. Those should all have essentially the same types of input and output so they can be reused.
Let’s start with layered architectures. In a layered architecture, components are organized in layers. Components on a higher layer make downcalls (send requests to a lower layer). While lower layer components can make upcalls (send requests up), they usually only respond to higher layer requests.
This approach is probably the most common because it is usually built around the database, and many applications in business naturally lend themselves to storing information in tables. The code is arranged so the data enters the top layer and works its way down each layer until it reaches the bottom, which is usually a database. Along the way, each layer has a specific task, like checking the data for consistency or reformatting the values to keep them consistent. It’s common for different programmers to work independently on different layers.
Consider Google Drive/Docs as an example:
- Interface layer: you request to see the latest doc from your drive.
- Processing layer: processes your request and asks for the information from the data layer.
- Data layer: stores persistent data like files and provides access to higher-level layers.
Each layer may or may not be placed on a different machine (this is a system architecture consideration).
The advantage of a layered architecture is the separation of concerns, which means that each layer can focus solely on its role. This makes it:
- Easy to assign separate “roles”
- Easy to update and enhance layers separately
Many programs spend most of their time waiting for something to happen. This is especially true for computers that work directly with humans, but it’s also common in areas like networks. Sometimes there’s data that needs processing, and other times there isn’t.
The event-driven architecture helps manage this by building a central unit that accepts all data and then delegates it to the separate modules that handle the particular type. This handoff is said to generate an “event,” and it is delegated to the code assigned to that type.
- Are easily adaptable to complex, often chaotic environments
- Scale easily
- Are easily extendable when new event types appear
Testing can be complex if the modules can affect each other. While individual modules can be tested independently, the interactions between them can only be tested in a fully functioning system.
Error handling can be difficult to structure, especially when several modules must handle the same events.
When modules fail, the central unit must have a backup plan.
Messaging overhead can slow down processing speed, especially when the central unit must buffer messages that arrive in bursts.
Object-Oriented, Service-Oriented Architectures, Microservices, and Mesh Architectures
Object-oriented, service-oriented architectures (SOA), microservices, and “mesh” architectures are all more loosely organized and represent an evolutionary sequence. While we’ve grouped them together, object-oriented isn’t an architectural style but rather a programming methodology that makes service-oriented architectures (SOAs) and microservices possible.
OBJECT-BASED ARCHITECTURAL STYLES
Object-oriented programming is a methodology generally used in the context of monolithic apps (although it’s also used in more modern architectures). Within the monolith, logical components are grouped together as objects. While they are distinguishable components, objects are still highly interconnected and not easy to separate. Object-oriented is a way to organize functionality and manage complexity within monoliths.
Each object has its own encapsulated data set, referred to as the object’s state. You may have heard of stateful and stateless applications that refer to whether or not they store data. In this context, state stands for data. An object’s method is the operations performed on that data.
Objects are connected through procedure call mechanisms. During a procedure call, an object “calls” on another object for specific requests. So when you hear ”procedure call”, think of a request.
Objects form the foundation of encapsulating services into independent units leading to the development of SOAs. Services are self-contained, independent objects that make use of other services. Communication happens over a network via “messages” sent to each interface.
Microservices are the next step in this evolutionary sequence. These microservices are smaller than services in an SOA, less tightly coupled, and more lightweight. The more significant difference from a business perspective, however, is their ability to decrease time to market.
Unlike with SOAs, where developers need to design and map out all interactions and interfaces before deploying a service (a process that can take months), microservices are more independent, allowing developers to push out updates without worrying about architectural details. Additionally, developers can use any programming language they want. Selecting the best language for a particular program further increases speed and thus time to market.
Mesh architectures are formed by services or processes running on nodes that cannot be easily accounted for. They may connect and disconnect frequently, some may not even use the internet. These services establish temporary peer-to-peer connections and can stay anonymous throughout the process. Examples are peer-to-peer technologies like TOR, torrents, p2p messengers, blockchain, etc.
Mesh architectures bring two additional qualities:
- Interacting services/processes are more uniform: there may be just a few or even one type of service participating in a mesh network. They are considered equal to each other — equally trustworthy or untrustworthy if we are speaking about security, for instance. This is quite different from traditional service-based architectures where there are usually dozens of non-uniform services.
- There is a higher emphasis on its distributed nature.
Mesh technologies are able to remain efficient even in highly unstable environments where connectivity between components is easily broken. Some components, in some cases even most components, are not directly connected. Instead, they communicate over multiple ”hops” via other system elements (messages “hop” or ”jump” from one element to another until reaching its destination).
Although you can see the fact that there is an evolution from object-oriented programming to SOAs, microservices, and mesh architectures, it doesn’t mean that this methodology is obsolete. Object-oriented merely refers to the separation of blocks inside a component or monolith. It’s a methodology that was, and still is, used. In fact, you can develop object-oriented microservices where microservices are composed of objects.