Skip to content

macdao/hands-on-clean-architecture-template

Repository files navigation

HoCAT 🐾

Java CI with Gradle

中文

What is HoCAT?

HoCAT (Hands-on Clean Architecture Template) is a template project based on the principles of Clean Architecture. It provides a production-ready, battle-tested, and evolvable architectural foundation for Java applications, designed to help developers build high-quality, maintainable software systems for the long term.

Core Architecture

The core value of HoCAT lies in its clear, decoupled architecture. It is not just a theoretical showcase but a set of engineering practices ready for production use.

HoCAT Diagram

For a detailed guide on the architecture design, please refer to the Clean Architecture Implementation Guide (in Chinese).

Design and Implementation Notes

For a deeper dive into the engineering decisions, implementation details, and the reasoning behind our technology and tooling choices (such as Gradle conventions and testing strategies), please refer to the HoCAT project's internal documentation: .hocat/README.md.

Core Design Philosophy

1. From Abstract Theory to Engineering Practice

Theories like Clean Architecture are highly abstract. HoCAT provides an executable, buildable engineering blueprint that translates them into practice. Through its Gradle multi-module structure, it physically enforces architectural dependency rules and answers concrete engineering questions like "how to organize code" and "how to guarantee dependency direction", making abstract theory concrete and actionable.

2. Strict Separation of Concerns and Dependency Control

HoCAT protects the core business logic by enforcing a unidirectional dependency rule, ensuring each component depends only on the bare minimum it needs:

  • domain: Defines pure business rules, independent of any external frameworks, making it the most stable part of the system.
  • application: Orchestrates business flows, defines Use Cases and Ports, and is also independent of specific technologies.
  • adapter: Implements the interaction logic with external technologies. This is the only place where specific frameworks and tools like Spring Web MVC or Spring Data JPA are introduced.
  • configuration: Assembles the application. It is responsible for introducing the Spring IoC container and wiring the concrete adapter implementations into the application's ports via dependency injection.

This design provides significant flexibility in technology choices. Since adapters are pluggable, you can easily swap implementations. For example, the project provides both adapter/persistence (JPA) and adapter/persistence-jdbc (Spring Data JDBC). You can switch between them with no changes to the business code. Likewise, adapter/web and adapter/web-openapi demonstrate that API implementation strategies are also swappable.

3. Pragmatic Data Structure Strategy

HoCAT adopts a balanced and pragmatic strategy for data transfer between layers, avoiding two common anti-patterns:

  1. Avoiding a single model that spans all layers: Exposing a database entity directly to the API can leak internal details and create security risks.
  2. Avoiding a DTO explosion: Creating a separate model for every interaction leads to a proliferation of boilerplate classes and mapping code.

HoCAT's strategy is that each layer owns the data structures for its boundaries. For instance, the web adapter has its own Request/Response models, while the persistence adapter has its persistence entities. This approach maintains clear boundaries without sacrificing developer productivity.

4. Deep Decoupling within Adapters

A well-designed adapter should also follow the separation of concerns principle internally. HoCAT isolates third-party library dependencies to the smallest possible scope within an adapter. For example, in the persistence adapter, only a few components, such as entity classes annotated with @Entity (e.g., OrderEntity) and repositories that inherit from Spring Data interfaces (e.g., OrderJpaRepository), are directly coupled with the specific data access technology (like Spring Data JPA). The rest of the adapter remains agnostic to the specific persistence technology, achieving a deeper level of isolation.

Codebase Tour

To understand how the architecture is implemented, here is a tour of the key modules:

  • domain: Defines the core business entities and rules; the most stable and pure part of the application.
  • application: Orchestrates business logic by defining Use Cases and the interfaces (Ports) that the outer layers must implement.
  • adapter: Connects the application to the outside world by providing concrete implementations for the ports defined in the application layer.
  • configuration: The final assembly module. It wires everything together using dependency injection.

Getting Started

Prerequisites

  • Install Java 21
  • Install Docker and Docker Compose

Build and Test

Use ./gradlew build to build and test the entire project.

Local Development

  • Use ./gradlew bootRun to run the application locally.
  • To start the database, run docker compose up -d in the configuration directory. You can check the dynamically assigned port with docker compose ps.
  • To start local third-party services for contract testing, run scripts/run-stub-runner-server configuration/src/test/resources/contracts/client 16581.

Package

Use ./gradlew bootBuildImage to build a Docker image.

IDE Setup

  • Formatter: Install the Spotless IDE plugin to auto-format code.

Technology Stack

  • Foundation: Java 21, Spring Boot 3.5, Spring Bean Validation, Lombok
  • Build: Gradle, JaCoCo, Spotless
  • Optional Adapters
    • Web Adapter: Spring Web MVC, Spring Security, Spring Cloud Contract
    • OpenAPI-based Web Adapter: OpenAPI Generator, Spring Web MVC, Spring Security
    • Persistence (JPA): Spring Data JPA, MySQL 8, Flyway, Spring Boot Docker Compose Support
    • Persistence (JDBC): Spring Data JDBC, MySQL 8, Flyway, Spring Boot Docker Compose Support
    • Client Adapter: Spring RestClient, Spring Cloud Contract Stub Runner
  • Testing: JUnit 5, AssertJ, Mockito
  • Documentation: Markdown, PlantUML

Related Projects

  • HoCATLing: A simplified, single-module version of HoCAT, suitable for smaller projects.

About

HoCAT,可落地的整洁架构模板

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published