# Software Architecture

> Software Architecture

- Skill: `djordjemojsilovic/software-architecture` (Agent Skill)
- Install (CLI): `npx skillmds@latest add djordjemojsilovic/software-architecture`
- Raw SKILL.md: https://api.skillmd.com/api/skills/djordjemojsilovic/software-architecture/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: DjordjeMojsilovic (https://skillmd.com/u/djordjemojsilovic)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/djordjemojsilovic/software-architecture

---


# Software Architecture

## Clean Architecture

### Layer Structure (outside → inside)
```
┌─────────────────────────────────────┐
│  Frameworks & Drivers               │  ← FastAPI, Express, React, DB drivers
│  (Infrastructure Layer)             │
├─────────────────────────────────────┤
│  Interface Adapters                 │  ← Controllers, Presenters, Gateways
│  (Adapter Layer)                    │
├─────────────────────────────────────┤
│  Application Business Rules         │  ← Use Cases, Application Services
│  (Use Case Layer)                   │
├─────────────────────────────────────┤
│  Enterprise Business Rules          │  ← Entities, Domain Models
│  (Domain Layer)                     │
└─────────────────────────────────────┘
```

**Dependency Rule:** Dependencies only point inward. The domain knows nothing about the database.

### Practical Application
- Domain entities have no framework imports
- Use cases define interfaces (ports); infrastructure implements them (adapters)
- Controllers are thin — they translate HTTP to use case calls, nothing more
- The database is a detail, not the architecture

---

## SOLID Principles

**S — Single Responsibility**
A class/module has one reason to change. If you need "and" to describe what it does, split it.

**O — Open/Closed**
Open for extension, closed for modification. Add behavior via new classes, not by modifying existing ones. Strategy pattern is the classic implementation.

**L — Liskov Substitution**
Subtypes must be substitutable for their base types without breaking the program. If you find yourself checking `isinstance()` in business logic, Liskov is violated.

**I — Interface Segregation**
Many specific interfaces > one general interface. Clients shouldn't depend on methods they don't use.

**D — Dependency Inversion**
High-level modules don't depend on low-level modules — both depend on abstractions. Inject dependencies; don't construct them inside classes.

---

## Essential Design Patterns

### Creational
**Factory Method** — when you need to create objects without specifying the exact class
**Builder** — when constructing complex objects step by step

### Structural
**Repository** — abstracts data access behind an interface; use case calls `user_repo.find_by_id()`, doesn't know if it's Postgres or Redis
**Adapter** — wraps incompatible interfaces; isolates third-party code

### Behavioral
**Strategy** — encapsulates interchangeable algorithms; inject the algorithm, don't hardcode it
**Observer/Event** — decouple producers from consumers; domain events are the DDD version
**Command** — encapsulate requests as objects; enables undo, queuing, logging

---

## Domain-Driven Design (Core Concepts)

**Entity** — has identity (ID), state can change, two entities with same ID are the same object
**Value Object** — no identity, defined by its attributes, immutable (Money, Address, Email)
**Aggregate** — cluster of entities/VOs with a root; transactions happen within one aggregate
**Domain Event** — something that happened in the domain that other parts care about
**Repository** — collection-like interface to access aggregates
**Service** — domain logic that doesn't fit in an entity

---

## Architecture Patterns

### CQRS (Command Query Responsibility Segregation)
Separate read models from write models. Commands change state; queries return data. Use when read and write load patterns differ significantly.

### Event Sourcing
Store events, not state. Current state = replaying all events. Use when audit trail, temporal queries, or undo are requirements. Warning: significant complexity cost.

### Hexagonal Architecture (Ports & Adapters)
Application core defines ports (interfaces); adapters implement them. Database, HTTP, and message queue are all adapters. Core is fully testable without infrastructure.

---

## Anti-Patterns to Avoid

**Big Ball of Mud** — no clear structure, everything depends on everything
**Anemic Domain Model** — entities are just data bags, all logic in services
**God Object** — one class knows too much and does too much
**Leaky Abstractions** — database details seeping into business logic
**Premature Optimization of Architecture** — adding CQRS/Event Sourcing before scale requires it

---

## Architecture Decision Template

When making an architecture decision, document:
```
Context: [What situation are we in?]
Decision: [What we chose]
Rationale: [Why — including rejected alternatives]
Consequences: [What becomes easier, what becomes harder]
```

---

## Quick Heuristics

- If a change requires modifying multiple unrelated files → coupling problem
- If testing requires running the full application → dependency inversion violated
- If the code can't be understood without knowing the framework → architecture leaked
- If you're not sure where new code goes → the layer structure isn't clear enough

Source: adapted from ComposioHQ/awesome-claude-skills/software-architecture + standard references

