Briefly exploring the most granular level using UML Class diagrams for implementation specifics
Level 4: Code is the most detailed and least frequently used level in the C4 Model hierarchy. At this stage, the focus shifts from architectural abstractions to implementation specifics — showing how a single component (or small group of closely related components) is actually realized in code.
Unlike Levels 1–3, which remain conceptual and avoid language-specific or tool-specific details, Level 4 deliberately dives into the concrete code structure. It is used only when precise, low-level understanding is genuinely required and cannot be adequately conveyed through higher-level diagrams or documentation alone.
Purpose of Level 4 Code Diagrams
Level 4 diagrams answer very targeted questions:
- How is this particular component implemented in terms of classes, interfaces, and their relationships?
- What are the key data structures, value objects, or entities involved in a complex domain?
- How do inheritance, composition, or dependency patterns manifest in the codebase?
- Where are critical business rules or invariants enforced at the code level?
- What does the schema look like for a database-backed component (entity-relationship view)?
These diagrams are almost always supplementary and narrowly scoped — they cover only the parts of the system where deep clarity adds real value (e.g., tricky domain logic, security-critical code, legacy areas needing refactoring, or onboarding to a particularly dense module).
Most Common Forms of Level 4 Diagrams
- UML Class Diagrams (the most typical choice)
- Show classes, interfaces, enums, relationships (inheritance, composition, association, aggregation), attributes, and key methods.
- Focus on public API and structural relationships — omit private implementation details unless essential.
- Example use case: Visualizing the domain model inside an “Order Aggregate” component, showing Order, OrderLine, Money, CustomerId, Status transitions, and invariants.
- Entity-Relationship Diagrams (ERDs)
- For components that heavily rely on relational databases.
- Show tables, columns, primary/foreign keys, relationships (one-to-many, many-to-many), indexes, and constraints.
- Often generated from schema tools (e.g., pgAdmin, DBeaver, dbdiagram.io) or maintained in PlantUML/C4-PlantUML.
- Other specialized views (less common)
- Package/namespace dependency diagrams
- Simplified sequence diagrams for critical methods
- Annotated code snippets or IDE-generated structure views
- State machines for complex lifecycle objects
When to Create Level 4 Diagrams
Create them only when:
- The component contains non-trivial domain logic or business rules that are hard to understand from reading code alone.
- You are onboarding developers to a particularly dense, legacy, or security-sensitive piece of code.
- Conducting detailed code reviews, refactoring planning, or security audits of implementation-level concerns (e.g., input validation, crypto usage, concurrency controls).
- Documenting critical invariants or design patterns that must be preserved during changes.
- There is regulatory/compliance need to demonstrate exact data handling at the code level.
Do not create Level 4 diagrams:
- For simple CRUD components
- For infrastructure/utility code
- When higher-level explanations (Level 3 + code comments + tests) suffice
- As a default for every component — this violates the “just enough” philosophy of C4
Practical Guidelines
- Keep scope very narrow — one diagram per component or per critical subdomain (rarely more than 10–15 classes).
- Use existing tools — generate from IDEs (IntelliJ, Visual Studio), PlantUML, Mermaid, or database tools rather than hand-drawing from scratch.
- Treat as living documentation — ideally auto-generate on build or commit so they stay reasonably current (e.g., via Structurizr extensions or PlantUML in CI).
- Combine with Level 3 — show the Level 3 component box as a container, then zoom inside to show the classes/interfaces that implement it.
- Avoid over-detailing — omit getters/setters, trivial fields, boilerplate — focus on structure and intent.
Example Use Case
For a “Payment Processing” component (from Level 3):
- Level 3 shows “Payment Orchestrator”, “Provider Adapter”, “Transaction Repository”
- Level 4 UML class diagram might show:
- PaymentRequest (value object)
- Payment (entity with status transitions)
- PaymentProviderPort (interface)
- StripeProviderAdapter (implementation)
- PaymentRepository (interface + JPA impl)
- Relationships: composition, dependency injection points, invariants
This level of detail is rarely needed across the entire system — but when it is needed, Level 4 provides the final piece of precision.
In practice, most teams create very few (if any) formal Level 4 diagrams, relying instead on code itself, tests, and architectural fitness functions to enforce design intent. When you do need one, keep it focused, generated where possible, and tied directly to a Level 3 component.
This concludes our exploration of the full C4 hierarchy and its supporting views — from the broadest enterprise landscape down to the most granular code-level specifics. You now have the complete toolkit to choose exactly the right level of detail for any audience or purpose.