Search Knowledge

© 2026 LIBREUNI PROJECT

Software Engineering & OOAD / Architecture & Quality

Principles of Software Architecture

Principles of Software Architecture

Software architecture refers to the high-level structures of a software system, the discipline of creating such structures, and the documentation of these structures. It is the blueprint of the system and provides an abstraction to manage the complexity and establish a communication and coordination mechanism among components.

What is Software Architecture?

Architecture is about the significant decisions—decisions that are expensive to change. It defines how the system is partitioned into components, how those components interact (interfaces), and the constraints under which they operate.

Key Architectural Principles

1. Separation of Concerns (SoC)

SoC is a design principle for separating a computer program into distinct sections such that each section addresses a separate concern. A concern is a set of information that affects the code of a computer program.

2. Low Coupling and High Cohesion

  • Cohesion refers to the degree to which the elements inside a module belong together. We strive for High Cohesion.
  • Coupling is the degree of interdependence between software modules. We strive for Low Coupling.

3. Least Knowledge (Law of Demeter)

A component should have limited knowledge about other units: only units “closely” related to the current unit. In terms of code, an object should only call methods on itself, its fields, or its parameters.

4. Directing Dependency (Dependency Rule)

Dependencies should point towards higher-level policies and abstractions, not towards low-level details (like databases or UIs). This is closely related to the Dependency Inversion Principle (DIP).

Common Architectural Patterns

Architectural patterns provide a template for solving recurring design problems in a particular context.

Layers Pattern

This pattern organizes the system into layers, where each layer provides services to the layer above it and uses services from the layer below. Typical layers include Presentation, Business, and Data Access.

Microservices

An architectural style that structures an application as a collection of services that are highly maintainable, testable, loosely coupled, and independently deployable.

Event-Driven Architecture (EDA)

In EDA, components communicate by producing and consuming events. This allows for high scalability and decoupling between the producer and consumer.

Architecture for Scale and Resiliency

In modern distributed systems, architecture must account for failure as a first-class citizen and ensure the system can handle growth.

Horizontal vs. Vertical Scaling

  • Vertical Scaling (Scaling Up): Adding more resources (CPU, RAM) to an existing server. It has a hard ceiling and carries a single point of failure.
  • Horizontal Scaling (Scaling Out): Adding more servers to the pool. This is the preferred approach for high availability and cloud-native systems.

Resiliency Patterns

To prevent a failure in one service from cascading through the entire system, architects use resiliency patterns:

  • Circuit Breaker: Detects failures and encapsulates the logic of preventing a failure from constantly recurring, similar to an electrical circuit breaker. It “trips” after a certain number of failures, giving the failing service time to recover.
  • Bulkhead: Segregates resources into different “pools” such that if one group fails, the others continue to work. For example, assigning separate thread pools for different APIs.
  • Retry Pattern: Automatically retries a failed operation, which is useful for transient faults like temporary network glitches.

Quality Attributes (The “-ilities”)

Architecture is judged by its ability to satisfy quality attributes, often called non-functional requirements:

  • Scalability: The ability of the system to handle increased load.
  • Maintainability: The ease with which a system can be modified.
  • Reliability: The ability of a system to remain functional under pressure.
  • Availability: The proportion of time the system is functional and reachable.

Example: N-Tier Architecture with Java

// Logic Layer (Service)
public class OrderService {
    private final OrderRepository repository;

    public OrderService(OrderRepository repository) {
        this.repository = repository;
    }

    public void processOrder(Order order) {
        // Business logic here
        repository.save(order);
    }
}

// Data Access Layer (Repository)
public interface OrderRepository {
    void save(Order order);
}

In this example, the OrderService depends on an abstraction (OrderRepository), following the principle of Dependency Inversion and Separation of Concerns.