“The Standard” by Hassan Habib: A Dive into Modern Software Architecture Principles

Mabrouk Mahdhi
4 min readSep 12, 2023
Image from the Standard documentation on Github.

In an era where software is not just a utility but a necessity, the architecture and design of software systems have become increasingly important. Hassan Habib’s “The Standard” aims to provide a comprehensive set of guidelines for developing software systems that are maintainable, scalable, and robust. This article aims to unpack the essentials of “The Standard” and why it could be a game-changer in software engineering.

The Concept of Brokers

Hassan Habib’s “The Standard” begins with the notion of “Brokers,” which act as intermediaries between different components of a system. These brokers could be data storage, third-party services, or other external dependencies. The main goal is to isolate the core business logic from these external factors, making the system more robust and easier to test. Brokers are designed to be swappable components, allowing for greater flexibility and less friction when changes are needed.

The Importance of Services

Services are the workhorses of “The Standard.” They encapsulate the core business logic and are designed to be technology agnostic. Services are broken down into four main types:

Foundation Services

Foundation Services are low-level, reusable services that offer essential functionalities to the more complex, higher-level services in your architecture. Typically situated at the bottom layer of a layered architecture, these services interact directly with your data storage, messaging systems, and other infrastructure components. They encapsulate operations like data access (CRUD operations), logging, caching, and other utility functions that are commonly needed across various parts of your system.

Example:

public ValueTask<Student> AddStudentAsync(Student student) =>
TryCatch(async () =>
{
ValidateStudent(student);

return await this.storageBroker.InsertStudentAsync(student);
});

=> More details here.

Processing Services

Processing services can be best described as optional but potent enhancers of business logic. They usually come into play when the system requires more than just basic CRUD operations. These services could:

  • Combine two or more primitive-level functions from Foundation Services to create new functionalities.
  • Modify the output of a single primitive function by adding specific business logic.
  • Serve as a pass-through layer to introduce balance and symmetry in the overall architecture.

Consider a function in a hypothetical StudentProcessingService for upserting student records:

public ValueTask<Student> UpsertStudentAsync(Student student) =>
TryCatch(async () =>
{
ValidateStudent(student);

IQueryable<Student> allStudents =
this.studentService.RetrieveAllStudents();

bool studentExists = allStudents.Any(retrievedStudent =>
retrievedStudent.Id == student.Id);

return studentExists switch {
false => await this.studentService.RegisterStudentAsync(student),
_ => await this.studentService.ModifyStudentAsync(student.Id)
};
});

=> More details here.

Orchestration Services

Orchestration services are designed to encapsulate operations that require the interaction of two or three different business entities. They are the high-level decision-makers within your system architecture, ensuring that the right services are called in the right sequence for a given operation to succeed.

For example, consider a feature within an educational system where each student who enrolls should also receive a library card. This is not as simple as creating a new record in a database table for library cards; it involves several steps:

  1. Verifying that the student exists in the system,
  2. Checking the student’s enrollment status,
  3. Generating a new library card linked to the student’s profile.

Here’s a C# example that demonstrates how an Orchestration Service might tackle this:

public async ValueTask<LibraryCard> CreateStudentLibraryCardAsync(LibraryCard libraryCard) =>
TryCatch(async () =>
{
ValidateLibraryCard(libraryCard);

await this.studentProcessingService
.VerifyEnrolledStudentExistsAsync(libraryCard.StudentId);

return await this.libraryCardProcessingService.CreateLibraryCardAsync(libraryCard);
});

=> More details here.

Aggregation Services

Aggregation services are designed to bring together multiple services under one umbrella, exposing a unified contract to external components. They act as the gatekeepers of the core business logic layer, providing a simplified and centralized way for other layers to interact with your system’s functionalities.

Here’s a C# example that illustrates what an Aggregation service might look like:

public async ValueTask ProcessStudentAsync(Student student)
{
await this.studentRegistrationCoordinationService.RegisterStudentAsync(student);
await this.studentRecordsCoordinationService.AddStudentRecordAsync(student);
...
...
await this.anyOtherStudentRelatedCoordinationService.DoSomethingWithStudentAsync(student);
}

=> More details here.

Service Operations and Patterns

Services in “The Standard” follow a set of rules, such as the “Do or Delegate” principle, which states that a service should either perform a task or delegate it, but not both. Another significant pattern is the “Florance Pattern,” which ensures a balanced and symmetrical architecture by restricting the dependencies of Orchestrator services to two or three other services. These rules aim to enhance the readability, maintainability, and configurability of the system.

Exposers: The Final Frontier

“Exposers” serve as the interface between the core business logic and the external world. Whether it’s a RESTful API, a user interface, or some other communication protocol, exposers are responsible for mapping the responses from the system to the outside world. Importantly, they are designed to contain no business logic, focusing solely on accurate mapping and communication.

Why “The Standard” Matters

  • Maintainability: By isolating different concerns and making components swappable, the system becomes easier to maintain and update.
  • Scalability: The modular nature of the architecture means that different components can be scaled independently, making it easier to adapt to changing requirements.
  • Robustness: With built-in validation and a strong focus on isolating external dependencies, the system is more resilient to failures.

Community and Resources

One of the most compelling aspects of “The Standard” is the robust community that has grown around it. Developers from around the globe are actively participating in live sessions where they implement standardized systems and libraries. Hassan Habib’s YouTube channel serves as a valuable resource where these live sessions are hosted, offering a wealth of information and practical examples.

Summary

“The Standard” by Hassan Habib provides a structured approach to software architecture that can significantly improve the quality and longevity of software systems. By embracing the principles of brokers, services, and exposers, developers can build systems that are not only robust and scalable but also easier to maintain and upgrade.

In a world where software is ever-evolving, “The Standard” serves as a blueprint for building software that can stand the test of time.

--

--

Mabrouk Mahdhi
Mabrouk Mahdhi

Written by Mabrouk Mahdhi

Founder @ CodeCampsis, Microsoft MVP

Responses (1)