전체 글
-
영속성 어댑터 구현하기Architecture/Clean Architecture 2024. 12. 10. 21:42
의존성 역전코어의 서비스가 영속성 어댑터에 접근하기 위해 포트를 사용한다영속성 어댑터는 아웃고잉 어댑터로 불린다.어플리케이션에 의해 호출될 뿐, 어플리케이션을 호출하지 않기 때문이다.여기서 포트가 사실상 어플리케이션 서비스와 영속성 코드 사이의 간접적인 계층이기 때문에 가능하다.영속성 어댑터의 책임입력을 받는다입력을 데이터베이스 포맷으로 매핑한다.영속성 어댑터는 데이터베이스를 쿼리하거나 변경하는 데 사용할 수 있는 포맷으로 입력 모델을 매핑한다.입력을 데이터베이스로 보낸다.평범한 SQL 구문에 매핑해서 데이터베이스에 보내도 되고, 들어오는 데이터를 파일로 직렬화해서 그것으로부터 데이터를 읽어도 상관 없다.데이터베이스 출력을 어플리케이션 포맷으로 매핑한다.데이터베이스 응답을 포트에 정의된 출력 모델로 매핑..
-
웹 어댑터 구현Architecture/Clean Architecture 2024. 12. 3. 22:05
의존성 역전인커밍 어댑터는 어플리케이션 서비스에 의해 구현된 인터페이스인 전용 포트를 통해 어플리케이션 계층과 통신한다.웹 어댑터는 인커밍 어댑터다. 외부의 요청을 받아서 어플리케이션에게 해야 하는 일을 알려준다.여기서 제어흐름은 웹 어댑터에 있는 컨트롤러에서 어플리케이션 계층에 있는 서비스이다.위와 같은 구조에서 간접 계층이 생기게 되는데 이러한 계층을 통해서 자연스럽게 의존성이 역전된다.여기서 간접 계층을 없앨 수 도 있지만 그렇게 되면 어플리케이션의 명세가 사라져서 외부와의 통신이 어떻게 되는 지 식별하기 어려워진다.웹 어댑터의 책임웹 어댑터의 책임HTTP 요청을 자바 객체로 매핑권한 검사입력 유효성 검증입력을 유스케이스의 입력 모델로 매핑유스케이스 호출유스케이스의 출력을 HTTP로 매핑HTTP 응..
-
유스케이스 구현하기Architecture/Clean Architecture 2024. 12. 2. 21:36
도메인 모델 구현package study.cleanarchitecture.acount.domain;import lombok.Getter;import lombok.Value;import java.time.LocalDateTime;@Getterpublic class Account { private AccountId id; private Money baselineBalance; private ActivityWindow activityWindow; public Money calculateBalance() { return Money.add( this.baselineBalance, this.activityWindow.calcu..
-
코드 구성하기Architecture/Clean Architecture 2024. 11. 28. 20:41
계층으로 구성하기 계층으로 코드를 구성하면 기능적인 측면들이 섞이기 쉽다.문제점어플리케이션의 기능 조각이나 특성을 구분 짓는 패키지 경계가 없다.추가적인 구조가 없다면, 아주 빠르게 서로 연관되지 않는 기능들끼리 예상하지 못한 부수효과를 일으킬 수 있는 클래스들의 묶음으로 변모할 가능성이 크다어플리케이션이 어떤 유스케이스들을 제공하는지 파악할 수 없다.특정 기능을 찾기 위해서는 어떤 서비스가 이를 구현했는지 추측해야 하고, 해당 서비스 내의 어떤 메서드가 그에 대한 책임을 수행하는 지 찾아야한다.기능으로 구성하기기능을 기준으로 코드를 구성하면 기반 아키텍처가 명확하게 보이지 않는다.장점패키지 경계를 package-private 접근 수준과 결합하면 각 기능 사이의 불필요한 의존성을 방지할 수 있다.Acc..
-
의존성 역전하기Architecture/Clean Architecture 2024. 11. 27. 21:29
단일 책임 원칙하나의 컴포넌트는 오로지 한 가지 일만 해야 하고, 그것을 올바르게 수행해야 한다.컴포넌트를 변경하는 이유는 오직 하나뿐이어야 한다.만약 컴포넌트를 변경할 이유가 한가지라면 우리가 어떤 다른 이유로 소프트웨어를 변경하더라도 이 컴포넌트에 대해서는 전혀 신경 쓸 필요 없다.실제 컴포넌트를 구현할 때 하나의 컴포넌트가 단일 기능으로 만들기 참 어려운 것 같다.처음에 만들 때는 단일 기능을 생각하고 만들지만 시간이 지나 비슷한 기능을 만들 일이 생긴다면 이전 컴포넌트의 병합 유혹을 많이 느낀다.그래서 막상 프로젝트가 시간이 지나면 이전의 단일 기능 컴포넌트가 여러 이유로 변경 되고 컴포넌트의 신뢰도가 떨어지는 경우가 많이 발생한다.그 외에도 테스트 코드를 유기적으로 바꿔줘야 한다.반성하자...부..
-
Layered architecture 문제Architecture/Clean Architecture 2024. 11. 25. 22:40
Layered architecture는 데이터베이스 주도 설계를 유도한다전통적인 계층형 아키텍처의 토대는 데이터베이스다.웹 계층은 도메인 계층에 의존하고, 도메인 계층은 영속성 계층에 의존하게 된다.그래서 자연스레 데이터베이스에 의존하게 된다.필자도 Spring boot로 개발하면서 해당 내용에 너무 공감이 되었다.비즈니스 로직에 엔티티를 끌어와서 Dirty Check를 유도한다던지 DTO를 활용하여 웹 계층에 옮긴다는 명목하에 도메인 계층에 엔티티를 넣는 경우가 다반사였다.그러한 원인은 ORM 프레임워크 도입이 주된 원인이었다.이렇게 되면 영속성 계층과 도메인 계층의 강력한 결합이 생긴다.이러한 이유로 영속성 관련 작업들이 도메인 계층에 침범하게 된다.지름길을 택하기 쉬워진다.전통적인 계층형 아키텍처에..
-
SpringBoot Framework 왜 쓸까?Spring Framework 2023. 11. 27. 17:42
Framework란? 프레임워크는 뼈대나 기반 구조를 뜻하고, 제어의 역전 개념이 적용된 대표적 기술 소프트웨어의 특정 문제를 해결하기 위해서 상호 협력하는 클래스와 인터페이스의 집합 객체 지향 개발을 하게 되면서 통합성, 일관성의 부족이 발생되는 문제를 해결할 방법 중 하나라고 할수 있다. Framework와 Library 차이는 멀까? “ 제어 흐름에 대한 주도성이 누구에게, 어디에 있는가” 프레임워크는 전체적인 흐름을 스스로 쥐고 있으며 사용자는 그 안에서 필요한 코드를 짜 넣는다. 라이브러리는 사용자가 전체적인 흐름을 만들며 라이브러리를 가져다 쓴다. 즉 라이브러리는 사용하고 호출하는 측에 주도성이 있고 프레임워크는 틀안에 이미 제어 흐름에 대한 주도성이 내재되어 있다. 사용자가 흐름에 따라 필요..
-
Equals와 HashCodeJAVA 2023. 11. 27. 16:43
Equals Method 두 참조 변수 값이 같은지 다른지 동등 여부를 비교할 때 사용한다. String 타입의 변수를 비교할 경우 String s1 = "Hello"; String s2 = "Hello"; System.out.println(s1 == s2); // 주소 비교 false System.out.println(s1.equals(s2)); // 값 비교 true 객체를 비교할 경우 ( ==이나 equals()나 똑같다 ) class Person { String name; public Person(String name) { this.name = name; } public class Example { public static void main(String[] args) { Person person1..