Software architecture patterns - Layered, Event-driven, Microkernel, Microservices, Space-based and CQRS

Last updated Apr 21, 2024 Published Oct 17, 2020

The content here is under the Attribution 4.0 International (CC BY 4.0) license

This is a short post on the book Software Architecture Patterns by Mark Richards, published by O’Reilly. The book catalogs five architectural styles: Layered, Event-Driven, Microkernel, Microservices and Space-Based. For each of them, the author goes through six aspects and ranks them [1], which collects a broader named:

  • Overall agility
  • Ease of deployment
  • Testability
  • Performance
  • Scalability
  • Ease of development

It covers high-level scenarios for each pattern to be used and also diagrams that help the reader to understand the details. Therefore, the book doesn’t have code examples or concrete implementations, which might open the definition to different implementations. Furthermore, for building up this material I used heavily the content provided by the original author. For each architectural style, I used the original definition, and in addition to that, I merged my thoughts on each one of them.

Software architecture in general is perceived as something that is far away from developers, which I strongly disagree with.

Layered

Components within the layered architecture pattern are organized into horizontal layers, each layer performing a specific role within the application. Popular frameworks for any language that uses the MVC (3 layers) as a foundation usually are bound to the layered architecture [2].

One of the powerful features of the layered architecture pattern is the separation of concerns among components.

The layers of isolation concept means that changes made in one layer of the architecture generally don’t impact or affect components in other layers, which in the MVC style follows this definition. The view is the layer that displays data and receives the user interaction, the controller handles the data from the view, and the model interacts with the database.

Web frameworks that follow this approach:

  • Laravel
  • CakePHP
  • Codeigniter
  • SpringBoot

The MVC was born from the Smalltalk project at Xerox PARC in response to organizing Graphic User Interface applications [3].

Event-driven

The event-driven architecture pattern is a popular distributed asynchronous architecture pattern used to produce highly scalable applications

The event-driven architecture pattern consists of two main topologies, the mediator and the broker. The event-driven architecture pattern is a relatively complex pattern to implement, primarily due to its asynchronous distributed nature.

Microkernel

The microkernel architecture pattern (sometimes referred to as the plug-in architecture pattern) is a natural pattern for implementing product-based applications. A product-based application is packaged and made available for download in versions of a typical third-party product.

The core system of the microkernel architecture pattern tradition‐ ally contains only the minimal functionality required to make the system operational.

Perhaps the best example of the microkernel architecture is the Eclipse IDE. However, once you start adding plug-ins, it becomes a highly customizable and useful product. Another example is WordPress, where users can download as many plugins as needed. Pat Kua [4] in his talk named the following software that was built using microkernel architecture:

One great thing about the microkernel architecture pattern is that it can be embedded or used as part of another architecture pattern.

For product-based applications, the microkernel architecture pattern should always be your first choice as a starting architecture.

Microservices

The microservices architecture pattern is quickly gaining ground in the industry as a viable alternative to monolithic applications and service-oriented architectures.

The first of these concepts is the notion of separately deployable units, perhaps the most important concept to understand with this pattern is the notion of a service component. Designing the right level of service component granularity is one of the biggest challenges within a microservices architecture.

James Lewis and Martin Fowler defined those components as: “a component is a unit of software that is independently replaceable and upgradeable”.

Another key concept within the microservices architecture pattern is that it is a distributed architecture, meaning that all the components within the architecture are fully decoupled from one other and accessed through some sort of remote access protocol (e.g., JMS, AMQP, REST, SOAP, RMI, etc.).

While there are dozens of ways to implement a microservices architecture pattern, three main topologies stand out as the most common and popular: the API REST-based topology, application REST-based topology, and centralized messaging topology.

Spaced-based

In any high-volume application with an extremely large concurrent user load, the database will usually be the final limiting factor in how many transactions you can process concurrently. The space-based architecture pattern is specifically designed to address and solve scalability and concurrency issues.

This pattern gets its name from the concept of tuple space, the idea of distributed shared memory. High scalability is achieved by removing the central database constraint and using replicated in-memory data grids instead.

The space-based architecture pattern is a complex and expensive pattern to implement. It is a good architecture choice for smaller web-based applications with variable load (e.g., social media sites, bidding and auction sites).

CQRS - Command Query Responsibility Segregation

Command Query Responsibility Segregation is focused on splitting the write data from the read data, allowing the decoupling of those two operations [5]. Microsoft documentation compares how the CRUD (Create, Read, Update and Delete) operations fit in a CQRS architecture, in a few points should be taken into account. The first is that CRUD usually operates in the same entity, all the operations are made in the same system, according to their documentation:

For example, a data transfer object (DTO) representing a customer is retrieved from the data store by the data access layer (DAL) and displayed on the screen. A user updates some fields of the DTO (perhaps through data binding) and the DTO is then saved back in the data store by the DAL. The same DTO is used for both the read and write operations.

Microsoft’s Cloud Design Patterns: Prescriptive Architecture Guidance for Cloud Applications under the section Design Patterns

Having both operations in the same entity, is, somehow, standard for most applications that start from scratch, using a boilerplate. For example, in Java, SpringBoot by default uses JPA, in PHP, Laravel uses Eloquent, and in JavaScript, the typed ORM project. All of those three operate in a CRUD fashion by default.

Microsoft depicts the following disadvantages of CRUD:

  • Mismatch of read and write operations, and adding columns (when talking about relation databases) when writing will affect reading, even though they are different operations.
  • When working in parallel, conflicts can happen when locking the data to be updated - read can be outdated until the operation finishes.
  • Security can be an issue, as read and write operations are subjected to the same entity - both will share the same security properties at the same time.

Implementing Domain Driven Design by Vaughn Vernon also describes what CQRS is and how it binds to Event Sourcing (but with the care of making them two different things that can be used together).

The argument opposed to CRUD also comes along and from his perspective in the book it makes it simpler to use two different models for writing and reading - Chapter 4 dives into more details.

A visual aid

References

  1. [1]R. Mark, Software Architecture Patterns. O’Reilly Media, Inc, 2015.
  2. [2]S. Mancuso, “MVC, Delivery Mechanism and Domain Model,” 2022 [Online]. Available at: . [Accessed: 09-Nov-2022]
  3. [3]A. Freeman and S. Sanderson, “The MVC Pattern,” in Pro ASP.NET MVC 3 Framework, Berkeley, CA: Apress, 2011, pp. 63–88 [Online]. Available at: https://doi.org/10.1007/978-1-4302-3405-0_4
  4. [4]P. Kua, Evolutionary Architecture by Patrick Kua. Devoxx, 2017 [Online]. Available at: https://youtu.be/iDYAtys2oK0
  5. [5]Microsoft, “Command and Query Responsibility Segregation (CQRS) Pattern,” 2015 [Online]. Available at: https://docs.microsoft.com/en-us/previous-versions/msp-n-p/dn568103(v=pandp.10)?redirectedfrom=MSDN. [Accessed: 04-Dec-2021]

Changelog

  • Apr 21, 2024 - Added visual aid under Related subjects section