Communitygithub.com

giuseppe-trisciuoglio/clean-architecture

Java 21+ Spring Boot 3.5+ 애플리케이션에서 클린 아키텍처, 헥사고날 아키텍처(포트와 어댑터), 도메인 주도 설계를 구현하기 위한 패턴을 제공합니다. 계층화된 아키텍처 구조화, 도메인 로직과 프레임워크 분리, 포트와 어댑터 구현, 엔티티/값 객체/집합체 생성, 테스트 용이성과 유지보수성을 위한 모노리식 코드베이스 리팩토링 시 사용하세요.

clean-architecture란 무엇인가요?

이 스킬은 Java 21+ 및 Spring Boot 3.5+ 기반 애플리케이션에서 클린 아키텍처(Clean Architecture), 헥사고날 아키텍처(Hexagonal Architecture, Ports & Adapters), 그리고 도메인 주도 설계(DDD)의 구현 패턴을 체계적으로 제공합니다. 핵심 목표는 도메인 로직을 프레임워크나 인프라 세부사항(데이터베이스, 웹, 메시징 등)으로부터 완전히 분리하여 비즈니스 규칙의 테스트 용이성과 유지보수성을 극대화하는 것입니다. 엔티티(Entity), 값 객체(Value Object), 집합체(Aggregate)와 같은 DDD 구성 요소를 정의하고, 포트(Port) 인터페이스와 어댑터(Adapter) 구현을 통해 의존성 역전 원칙(Dependency Inversion Principle)을 실현하는 방법을 설명합니다. 이 가이드는 기존의 모노리식(Monolithic) 또는 레이어드 아키텍처(Layered Architecture) 코드베이스를 점진적으로 리팩토링하고자 하는 개발자와 팀에게 매우 유용합니다. 본 스킬은 Java, Spring Boot 환경에 최적화되어 있으며, 구체적인 패키지 구조, 클래스 다이어그램, 샘플 코드 등을 통해 실무에 바로 적용 가능한 지침을 제공합니다.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/giuseppe-trisciuoglio/developer-kit/tree/main/skills/clean-architecture

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

clean-architecture은(는) 무엇을 하나요?

Java 21+ Spring Boot 3.5+ 애플리케이션에서 클린 아키텍처, 헥사고날 아키텍처(포트와 어댑터), 도메인 주도 설계를 구현하기 위한 패턴을 제공합니다. 계층화된 아키텍처 구조화, 도메인 로직과 프레임워크 분리, 포트와 어댑터 구현, 엔티티/값 객체/집합체 생성, 테스트 용이성과 유지보수성을 위한 모노리식 코드베이스 리팩토링 시 사용하세요.

개요

이 스킬은 최신 Java 및 Spring Boot 생태계에서 클린 아키텍처, 헥사고날 아키텍처, 그리고 도메인 주도 설계(DDD) 원칙을 적용하는 방법을 안내합니다. 주요 목표는 다음과 같습니다:

  • 관심사의 분리: 도메인 로직을 인프라스트럭처(데이터베이스, 웹, 메시징 등)로부터 완전히 분리합니다.
  • 테스트 용이성: 도메인 계층을 독립적으로 단위 테스트할 수 있도록 만듭니다.
  • 유지보수성: 코드 변경이 시스템의 다른 부분에 미치는 영향을 최소화합니다.
  • 프레임워크 독립성: 비즈니스 로직이 특정 프레임워크에 결합되지 않도록 합니다.

주요 개념

1. 계층 구조

다음은 일반적인 의존성 방향을 보여줍니다:

[인프라스트럭처] --> [애플리케이션] --> [도메인]
      |                                     |
      +------------- (인터페이스) -----------+

2. 핵심 용어

용어설명
도메인 (Domain)비즈니스 규칙과 로직 (프레임워크에 의존하지 않음)
애플리케이션 (Application)유스케이스 조정 및 트랜잭션 관리
인프라스트럭처 (Infrastructure)데이터베이스, 메시징, 외부 API 등과의 통신
엔티티 (Entity)고유 식별자를 가진 도메인 객체
값 객체 (Value Object)속성에 의해 식별되는 불변 객체
집합체 (Aggregate)일관성 경계로 묶인 엔티티 및 값 객체의 클러스터
포트 (Port)애플리케이션 계층이 정의하는 인터페이스 (인바운드/아웃바운드)
어댑터 (Adapter)포트를 구현하여 외부 시스템과 통신하는 클래스

구현 가이드

패키지 구조 예시

com.example.myapp
├── domain
│   ├── model          // 엔티티, 값 객체, 집합체
│   ├── service        // 도메인 서비스
│   ├── repository     // 리포지토리 인터페이스 (포트)
│   └── event           // 도메인 이벤트
├── application
│   ├── port           // 인바운드 포트 (유스케이스 인터페이스)
│   ├── service        // 유스케이스 구현
│   └── dto            // 애플리케이션 DTO
├── infrastructure
│   ├── persistence    // JPA, MyBatis 등 구현 (어댑터)
│   ├── web            // REST 컨트롤러 (어댑터)
│   └── messaging      // 메시징 구현 (어댑터)
└── shared
    └── kernel         // 공통 기본 클래스 or 유틸리티

샘플 코드

1. 도메인 엔티티 (Java 21 Record 사용)

package com.example.myapp.domain.model;

import java.util.UUID;

public record Customer(UUID id, String name, Email email, LoyaltyPoints points) {

    public Customer {
        if (name == null || name.isBlank()) {
            throw new IllegalArgumentException("고객 이름은 필수입니다.");
        }
    }

    public Customer addPoints(int additionalPoints) {
        return new Customer(this.id, this.name, this.email, this.points.add(additionalPoints));
    }
}

2. 값 객체 (불변)

package com.example.myapp.domain.model;

public record Email(String value) {

    private static final String EMAIL_PATTERN = "^[A-Za-z0-9+_.-]+@(.+)$";

    public Email {
        if (value == null || !value.matches(EMAIL_PATTERN)) {
            throw new IllegalArgumentException("유효하지 않은 이메일 주소입니다.");
        }
    }
}

3. 포트 인터페이스 (아웃바운드)

package com.example.myapp.domain.repository;

import com.example.myapp.domain.model.Customer;
import java.util.Optional;
import java.util.UUID;

public interface CustomerRepository {
    Customer save(Customer customer);
    Optional<Customer> findById(UUID id);
    void delete(Customer customer);
}

4. 유스케이스 (애플리케이션 계층)

package com.example.myapp.application.service;

import com.example.myapp.domain.model.Customer;
import com.example.myapp.domain.repository.CustomerRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@RequiredArgsConstructor
@Transactional
public class UpdateCustomerLoyaltyPointsUseCase {

    private final CustomerRepository customerRepository;

    public Customer execute(UUID customerId, int pointsToAdd) {
        Customer customer = customerRepository.findById(customerId)
                .orElseThrow(() -> new IllegalArgumentException("고객을 찾을 수 없습니다: " + customerId));
        Customer updatedCustomer = customer.addPoints(pointsToAdd);
        return customerRepository.save(updatedCustomer);
    }
}

5. 인프라스트럭처 어댑터 (JPA)

package com.example.myapp.infrastructure.persistence;

import com.example.myapp.domain.model.Customer;
import com.example.myapp.domain.repository.CustomerRepository;
import jakarta.persistence.EntityNotFoundException;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;

import java.util.Optional;
import java.util.UUID;

@Repository
@RequiredArgsConstructor
public class JpaCustomerAdapter implements CustomerRepository {

    private final JpaCustomerEntityRepository jpaRepository;

    @Override
    public Customer save(Customer customer) {
        // 엔티티 변환 로직 포함
        CustomerEntity entity = CustomerEntity.fromDomain(customer);
        CustomerEntity savedEntity = jpaRepository.save(entity);
        return savedEntity.toDomain();
    }

    @Override
    public Optional<Customer> findById(UUID id) {
        return jpaRepository.findById(id).map(CustomerEntity::toDomain);
    }

    @Override
    public void delete(Customer customer) {
        jpaRepository.deleteById(customer.id());
    }
}

모범 사례

  1. 도메인 계층을 순수하게 유지하세요: 도메인 클래스에 @Entity, @Table, @Service 등의 프레임워크 애노테이션을 넣지 마십시오.
  2. 의존성 역전을 사용하세요: 도메인 계층이 인터페이스(포트)를 정의하게 하고, 인프라스트럭처가 이를 구현하게 하십시오.
  3. 값 객체를 선호하세요: 원시 타입 대신 값 객체를 사용하면 타입 안전성이 향상되고 비즈니스 규칙이 캡슐화됩니다.
  4. 집합체를 사용하여 일관성 경계를 유지하세요: 트랜잭션 경계를 명확히 하고 집합체 외부의 수정은 리포지토리를 통해서만 이루어지도록 하십시오.
  5. 인바운드와 아웃바운드 포트를 분리하세요: port.in 및 port.out과 같은 별도의 패키지나 레이블을 사용하십시오.

추가 리소스

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

giuseppe-trisciuoglio/aws-lambda-java-integration

Provides AWS Lambda integration patterns for Java with cold start optimization. Use when deploying Java functions to AWS Lambda, choosing between Micronaut and Raw Java approaches, optimizing cold starts below 1 second, configuring API Gateway or ALB integration, or implementing serverless Java applications. Triggers include "create lambda java", "deploy java lambda", "micronaut lambda aws", "java lambda cold start", "aws lambda java performance", "java serverless framework".

giuseppe-trisciuoglio/aws-lambda-php-integration

Provides AWS Lambda integration patterns for PHP with Symfony using the Bref framework. Creates Lambda handler classes, configures runtime layers, sets up SQS/SNS event triggers, implements warm-up strategies, and optimizes cold starts. Use when deploying PHP/Symfony applications to AWS Lambda, configuring API Gateway integration, implementing serverless PHP applications, or optimizing Lambda performance with Bref. Triggers include "create lambda php", "deploy symfony lambda", "bref lambda aws", "php lambda cold start", "aws lambda php performance", "symfony serverless", "php serverless framework".

giuseppe-trisciuoglio/aws-lambda-python-integration

Provides AWS Lambda integration patterns for Python with cold start optimization. Use when deploying Python functions to AWS Lambda, choosing between AWS Chalice and raw Python approaches, optimizing cold starts, configuring API Gateway or ALB integration, or implementing serverless Python applications. Triggers include "create lambda python", "deploy python lambda", "chalice lambda aws", "python lambda cold start", "aws lambda python performance", "python serverless framework".

giuseppe-trisciuoglio/aws-lambda-typescript-integration

Provides AWS Lambda integration patterns for TypeScript with cold start optimization. Use when creating or deploying TypeScript Lambda functions, choosing between NestJS framework and raw TypeScript approaches, optimizing cold starts, configuring API Gateway or ALB integration, or implementing serverless TypeScript applications. Triggers include "create lambda typescript", "deploy typescript lambda", "nestjs lambda aws", "raw typescript lambda", "aws lambda typescript performance".

giuseppe-trisciuoglio/aws-rds-spring-boot-integration

Provides patterns to configure AWS RDS (Aurora, MySQL, PostgreSQL) with Spring Boot applications. Configures HikariCP connection pools, implements read/write splitting, sets up IAM database authentication, enables SSL connections, and integrates with AWS Secrets Manager. Use when setting up RDS connections in Spring Boot, configuring connection pooling, or managing database credentials securely.

giuseppe-trisciuoglio/aws-sdk-java-v2-bedrock

Provides Amazon Bedrock patterns using AWS SDK for Java 2.x. Invokes foundation models (Claude, Llama, Titan), generates text and images, creates embeddings for RAG, streams real-time responses, and configures Spring Boot integration. Use when asking about Bedrock integration, Java SDK for AI models, AWS generative AI, Claude/Llama invocation, embeddings for RAG, or Spring Boot AI setup.

giuseppe-trisciuoglio/aws-sdk-java-v2-core

Provides AWS SDK for Java 2.x client configuration, credential resolution, HTTP client tuning, timeout, retry, and testing patterns. Use when creating or hardening AWS service clients, wiring Spring Boot beans, debugging auth or region issues, or choosing sync vs async SDK usage.

giuseppe-trisciuoglio/aws-sdk-java-v2-dynamodb

Provides Amazon DynamoDB patterns using AWS SDK for Java 2.x. Use when creating, querying, scanning, or performing CRUD operations on DynamoDB tables, working with indexes, batch operations, transactions, or integrating with Spring Boot applications.

giuseppe-trisciuoglio/aws-sdk-java-v2-kms

Provides AWS Key Management Service (KMS) patterns using AWS SDK for Java 2.x. Use when creating/managing encryption keys, encrypting/decrypting data, generating data keys, digital signing, key rotation, or integrating encryption into Spring Boot applications.

giuseppe-trisciuoglio/aws-sdk-java-v2-lambda

Provides AWS Lambda patterns using AWS SDK for Java 2.x. Use when invoking Lambda functions, creating/updating functions, managing function configurations, working with Lambda layers, or integrating Lambda with Spring Boot applications.

giuseppe-trisciuoglio/aws-sdk-java-v2-messaging

Provides AWS messaging patterns using AWS SDK for Java 2.x for SQS queues and SNS topics. Handles sending/receiving messages, FIFO queues, DLQ, subscriptions, and pub/sub patterns. Use when implementing messaging with SQS or SNS.

giuseppe-trisciuoglio/aws-sdk-java-v2-rds

Provides AWS RDS (Relational Database Service) management patterns using AWS SDK for Java 2.x. Use when creating, modifying, monitoring, or managing Amazon RDS database instances, snapshots, parameter groups, and configurations.

giuseppe-trisciuoglio/aws-sdk-java-v2-s3

Provides Amazon S3 patterns and examples using AWS SDK for Java 2.x. Use when working with S3 buckets, uploading/downloading objects, multipart uploads, presigned URLs, S3 Transfer Manager, object operations, or S3-specific configurations.

giuseppe-trisciuoglio/aws-sdk-java-v2-secrets-manager

Provides AWS Secrets Manager patterns for AWS SDK for Java 2.x, including secret retrieval, caching, rotation-aware access, and Spring Boot integration. Use when storing or reading secrets in Java services, replacing hardcoded credentials, or wiring secret-backed configuration into applications.

giuseppe-trisciuoglio/better-auth

Provides Better Auth integration patterns for NestJS backend and Next.js frontend with Drizzle ORM and PostgreSQL. Use when setting up Better Auth with NestJS backend, integrating Next.js App Router frontend, configuring Drizzle ORM schema, implementing social login (GitHub, Google), adding plugins (2FA, Organization, SSO, Magic Link, Passkey), implementing email/password authentication with session management, or creating protected routes and middleware.

giuseppe-trisciuoglio/chunking-strategy

Provides chunking strategies for RAG systems. Generates chunk size recommendations (256-1024 tokens), overlap percentages (10-20%), and semantic boundary detection methods. Validates semantic coherence and evaluates retrieval precision/recall metrics. Use when building retrieval-augmented generation systems, vector databases, or processing large documents.

giuseppe-trisciuoglio/docs-updater

Provides automated documentation updates by analyzing git changes between the current branch and the last release tag. Performs git diff analysis to identify modifications, then updates README.md, CHANGELOG.md following Keep a Changelog standard, and discovers documentation folders for contextual updates. Use when preparing a release, maintaining documentation sync, or before creating a pull request. Triggers on "update docs", "update changelog", "sync documentation", "update readme", "prepare release documentation".

giuseppe-trisciuoglio/drawio-logical-diagrams

Creates professional logical flow diagrams and logical system architecture diagrams using draw.io XML format (.drawio files). Use when creating: (1) logical flow diagrams showing data/process flow between system components, (2) logical architecture diagrams representing system structure without cloud provider specifics, (3) BPMN process diagrams, (4) UML diagrams (class, sequence, activity), (5) data flow diagrams (DFD), (6) decision flowcharts, or (7) system interaction diagrams. This skill focuses on generic/abstract representations, not AWS/Azure-specific architectures (use aws-drawio-architecture-diagrams for cloud diagrams).

giuseppe-trisciuoglio/drizzle-orm-patterns

Provides comprehensive Drizzle ORM patterns for schema definition, CRUD operations, relations, queries, transactions, and migrations. Proactively use for any Drizzle ORM development including defining database schemas, writing type-safe queries, implementing relations, managing transactions, and setting up migrations with Drizzle Kit. Supports PostgreSQL, MySQL, SQLite, MSSQL, and CockroachDB.

giuseppe-trisciuoglio/github-issue-workflow

Provides a structured 8-phase workflow for resolving GitHub issues in Claude Code. Covers fetching issue details, analyzing requirements, implementing solutions, verifying correctness, performing code review, committing changes, and creating pull requests. Use when user asks to resolve, implement, work on, fix, or close a GitHub issue, or references an issue URL or number for implementation.

관련 스킬