2025/03 8

[클린 아키텍처] 애플리케이션 조립하기 & 아키텍처 경계 강제하기

왜 조립까지 신경 써야 할까?모든 의존성은 안쪽, 도메인 방향으로 향해야 한다도메인 코드가 바깥으로부터 안전해진다.한 클래스가 필요로 하는 모든 객체를 생성자로 전달할 수 있다면 실제 객체 대신 목으로 전달할 수 있고, 이렇게 되면 격리된 단위 테스트를 생성하기 쉬워진다.설정 컴포넌트는 우리가 제공한 조각들로 애플리케이션을 조립하는 것을 책임진다. 이 컴포넌트는 다음과 같은 역할을 수행해야 한다.웹 어댑터 인스턴스 생성HTTP 요청이 실제로 웹 어댑터로 전달되도록 보장유스케이스 인스턴스 생성웹 어댑터에 유스케이스 인스턴스 생성유스케이스에 영속성 어댑터 인스턴스 제공영속성 어댑터가 실제로 데이터베이스에 접근할 수 있도록 보장스프링의 클래스패스 스캐닝으로 조립하기@Component 애노테이션이 붙은 클래스를..

아키텍처 2025.03.28

[클린 아키텍처] 아키텍처 요소 테스트 전략 & 경계 간 매핑하기

육각형 아키텍처에서 사용하는 전략도메인 엔티티를 구현할 때는 단위 테스트로 커버하자유스케이스를 구현할 때는 단위 테스트로 커버하자어댑터를 구현할 때는 통합 테스트로 커버하자사용자가 취할 수 있는 중요 애플리케이션 경로는 시스템 테스트로 커버하자경계 간 매핑하기각 계층의 모델을 매핑하는 것에 대해매핑에 찬성하는 개발자두 계층 간에 매핑을 하지 않으면 양 계층에서 같은 모델을 사용해야 하는데 이렇게 하면 두 계층이 강하게 결합됩니다.매핑에 반대하는 개발자하지만 두 계층 간에 매핑을 하게 되면 보일러플레이트 코드를 너무 많이 만들게 돼요. 유스케이스들이 오직 CRUD만 수행하고 계층에 걸쳐 같은 모델을 사용하게 되기 때문에 계층 사이의 매핑은 과합니다.매핑하지 않기 전략 ..

아키텍처 2025.03.28

[클린 아키텍처] 웹 어댑터 구현하기 & 영속성 어댑터 구현하기

의존성 역전adapter.in.web || application.port.in || application.service컨트롤러 → 포트 ← 서비스컨트롤러 → 포트 ← 서비스웹 어댑터는 ‘주도하는’ 혹은 ‘인커밍’ 어댑터다. 외부로부터 요청을 받아 애플리케이션 코어를 호출하고 무슨 일을 해야 할지 알려준다. 이때 제어 흐름은 웹 어댑터에 있는 컨트롤러에서 애플리케이션 계층에 있는 서비스로 흐른다.애플리케이션 계층은 웹 어댑터가 통신할 수 있는 특정 포트를 제공한다. 서비스는 이 포트를 구현하고, 웹 어댑터는 이 포트를 호출할 수 있다.왜 어댑터와 유스케이스 사이에 또 다른 간접 계층을 넣어야할까? 애플리케이션 코어가 외부 세계와 통신할 수 있는 곳에 대한 명세가 포트이기 때문이다. 포트를 적절한 곳에 위치..

아키텍처 2025.03.28

[클린 아키텍처] 유스케이스

육각형 아키텍처는 도메인 중심의 아키텍처에 적합하기 때문에 도메인 엔티티를 만드는 것으로 시작한 후 해당 도메인 엔티티를 중심으로 유스케이스를 구현한다.도메인 모델 구현하기한 계좌에서 다른 계좌로 송금하는 유스케이스를 구현import java.time.LocalDate;import java.time.LocalDateTime;public class Account { private AccountId id; private Money baselineBalance; private ActivityWindow activityWindow; public Money calculateBalance() { return Money.add( this.baselineBa..

아키텍처 2025.03.27

[Kotlin] 기본 문법 정리

최근 코틀린 개발에 관심이 많아져서 코틀린 기본 함수를 한번 정리하고 개발을 진행하기 위해 기초 문법을 정리했습니다. 메인 함수fun main() { print("Hello World!")}코틀린의 코드 끝에는 ;를 붙여도 실행이 되지만 안붙이는걸 지향한다.코틀린은 메인 함수에서 실행된다변수fun main() { var i = 10 var name = "재혁" var point = 3.3}코틀린은 타입 추론기능을 갖고 있어서 타입을 지정해주지 않아도 된다.타입을 지정하고 싶다면 변수 뒤에 : 타입명 을 입력해서 명시적 지정도 가능하다.fun main() { var i : Int = 10 var name : String = "재혁" var point : Double = 3..

[디자인 패턴] 유연한 설계를 하려면 OCP와 DIP를 지켜라

개방 폐쇄 원칙은 “확장에는 열려 있어야 하고, 변경에는 닫혀 있어야 한다” 다시말해, “객체의 기능을 확장할 수 있으면서 기존의 코드(클라이언트)는 수정하지 않는다”런타임 의존성과 컴파일타임 의존성OCP는 런타임 의존성과 컴파일타임 의존성에 관한 이야기다.  Movie는 DiscountPolicy(구현체가 아닌 인터페이스나 부모클래스)에 의존하기 떄문에 자식 클래스로 OverlappedDiscountPolicy 클래스를 추가하더라도 기존의 코드는 변하지 않는다.변경의 이유가 1가지이다. 그건 바로 서비스 계층의 할인 정책 인터페이스추상화OCP의 핵심은 추상화에 의존하는 것이다. ’폐쇄’를 가능하게 하는 것은 추상화에 대한 의존성의 방향이다.public class Movie { //... pr..

아키텍처 2025.03.24

[클린 아키텍처] 의존성 역전하기

단일 책임 원칙SRP: 하나의 컴포넌트는 오로지 한 가지 일만 해야 하고, 그것을 올바르게 수행해야 한다.단일 책임 원칙의 실제 정의는 “컴포넌트를 변경하는 이유는 오직 하나뿐이어야 한다.”‘책임’은 ‘변경할 이유’로 해석해야 한다.(Reason to change)만약 컴포넌트를 변경할 이유가 한 가지라면 우리가 어떤 다른 이유로 소프트웨어를 변경하더라도 이 컴포넌트에 대해서는 전혀 신경 쓸 필요가 없다. 여전히 우리가 기대한 대로 동작하기 떄문이다.단일 책임 원칙을 위배하기 때문에 시간이 갈수록 변경하기가 더 어려워지고 그로 인한 비용도 증가한다. 변경할 이유가 많이 쌓인 후에는 한 컴포넌트를 바꾸는 것이 다른 컴포넌트가 실패하는 원인으로 작용할 수 있다. 의존성 역전 원칙도메인 코드는 애플리케이션에서..

아키텍처 2025.03.23

[클린 아키텍처] 계층형 아키텍처(Layered Architecture)의 문제는 무엇일까?

일반적인 3계층 아키텍쳐(전형적인 웹 애플리케이션 구조): 웹 → 도메인 → 영속성계층형 아키텍처의 문제점은 무엇일까? 코드에 나쁜 습관들이 스며들기 쉽게 만들고 시간이 지날수록 소프트웨어를 점점 더 변경하기 어렵게 만드는 수많은 허점들을 노출한다.계층형 아키텍처는 데이터베이스 주도 설계를 유도한다정의에 따르면 전통적인 계층형 아키텍처의 토대는 데이터베이스이다.웹 계층은 도메인 계층에 의존하고, 도메인 계층은 영속성 계층에 의존하기 때문에 자연스레 데이터베이스에 의존하게된다.우리는 보통 비즈니스를 관장하는 규칙이나 정책을 반영한 모델을 만들어서 사용자가 이러한 규칙과 정책을 더욱 편리하게 활용할 수 있게 한다. 이때 우리는 상태(state)가 아니라 행동(behavior)을 중심으로 모델링한다. 어떤 애..

아키텍처 2025.03.23