전체 글 35

[우아한테크세미나] Kafka 이벤트 기반 아키텍처 구축

2024.01.08 시청 발단 : 이벤트 기반 아키텍처 왜 사용? 배달 시스템의 복잡도 증가 알림 기능 배달 시간 통계 배달 늦었을 때 쿠폰 기능 배달만 잘 수행하길 바랬지만 요구 사항이 늘어날 수록 복잡도가 커진다. 따라서 해결법으로는 시스템을 분리하자! 이다. 대부분의 기능은 배달과 강한 일관성을 필요로 하지 않는다. 즉, 배달이 변경되었을 때, 관련 기능도 동시에 반영되어야 하는 가가 강한 일관성의 기준이 된다. 통계나, 쿠폰과 같은 개념은 관련 기능이 “언젠가” 반영되면 된다. (= 결과적 일관성) 결과적 일관성 관련 기능이 언젠가 반영되면 된다. 이벤트는 시스템에서 일어난 행위이다. 해결법 → 이벤트 아키텍처를 이용하자! 이벤트 아키텍처 구현법 이벤트는 어떤 정보를 가지고 있어야 할까? 이벤트 ..

6장 영속성 어댑터 구현하기

의존성 역전 애플리케이션의 서비스에서는 영속성 기능을 사용하기 위해 포트 인터페이스를 호출한다. 육각형 아키텍처에서 영속성 어댑터는 주도되는 혹은 아웃고잉 어댑터이다. 즉, 애플리케이션에 의해 호출된다. 포트는 애플리케이션 서비스와 영속성 코드 사이의 간접적인 계층이다. 이를 통해 의존성을 역전 시켜, 영속성 코드를 리팩터링 해도 코어의 코드는 변경 되지 않는다. 영속성 어댁터의 책임 입력을 받는다. 포트 인터 페이스를 통해 입력을 받는다. 입력을 데이터 베이스 포맷으로 매핑한다. 입력 모델을 데이터 베이스 테이블 구조를 반영한 JPA 엔티티 객체로 매핑한다. 매핑하지 않는 전략은 8장에서 다룬다. 영속성 어댑터 입력 모델이 영속성 어댑터 내부에 있는 것이 아니라 애플리케이션 코어에 있다. → 이를 통해..

5장 웹 어댑터 구현하기

의존성 역전 인커밍 어댑터는 애플리케이션 서비스에 의해 구현된 인터페이스인 전용 포트를 통해 애플리케이션 계층과 통신한다. 여기서 왜 어댑터와 유스케이스 중간에 간접 계층을 넣어야 할까? 애플리케이션 코어가 외부 세계와 통신할 수 있는 곳에 대한 명세가 포트이기 때문이다. → 여기에 대한 이야기는 11장에서 더 하기로 한다. 웹 어댑터의 책임 Http 요청을 자바 객체로 매핑. 파라미터와 콘텐츠를 객체로 역직렬화 한다. 권한 검사 입력 유효성 검증 유스 케이스 입력 모델은 유스케이스의 맥락에서 유효한 입력만 허용해야 한다. 웹어댑터의 입력모델과 유스케이스의 입력 모델과는 또 다른 유효성 검증을 해야한다. 웹 어댑터의 입력 모델을 유스케이스의 입력 모델로 변환할 수 있다는 것을 검증해야 한다. 입력을 유스..

4장 유스케이스 구현하기

육각형 아키텍쳐의 장점은 애플리케이션, 웹, 영속성 계층이 아주 느슨하게 결합돼 있다는 점이다. 이를 통해, 도메인 코드를 자유롭게 모델링 하고, DDD, 풍부하거나 빈약한 도메인 모델을 구현할 수 있다. 유스케이스 입력의 유효성 검증 책임은 없다. 비즈니스 규칙을 검증할 책임이 있다. 도메인 엔티티와 이 책임을 공유한다. 유스케이스는 입력을 기반으로 어떤 방법으로든 모델의 상태를 변경한다. 아웃고잉 어댑터를 호출한다. 아웃고잉 어댑터에서 온 출력값을, 유스케이스를 호출한 어댑터로 반환할 출력 객체로 변환한다. 다음과 같이,, 하나의 서비스가 하나의 유스케이스를 구현한다. 도메인 모델을 변경하고, 변경된 상태를 저장하기 위해 아웃고잉 포트를 호출. 입력 유효성 검증 애플리케이션 계층에서 이를 검증한다. ..

3장 코드 구성하기

계층으로 구성하기 buckapl |--- domain | |----- Account | |----- Activity | |----- AccountRepository | |----- AccountService |--- persistence | |----- AccountRepositoryImpl |--- web | |----- AccountController 기능을 구분짓는 패키지 경계가 없다. 애플리케이션이 어떤 유스 케이스를 제공하는지 파악하기 어렵 패키지 구조를 통해서는 우리가 목표로 하는 아키텍처를 파악할 수 없다 기능으로 구성하기 buckapl |--- account | |----- Account | |----- Activity | |----- AccountRepository | |----- Sen..

2장 의존성 역전하기

목차에 앞서서, SOLID 의 핵심 기능 중 하나인 S와 D를 먼저 이야기 나누어 보겠다. 단일 책임 원칙 (SRP) Single Responsibility Principle 로 직역하자면 하나의 컴포넌트는 오로지 한 가지 일만 해야하고, 그것을 올바르게 수행해야 한다는 의미이다. 하지만, 실제 정의는 다음과 같다. 컴포넌트를 변경하는 이유는 오직 하나뿐이어야 한다. 즉, 책임은 오로지 한가지 일을 하는 것 보다 “변경할 이유” 로 해석되어야 한다. 다음과 같이, E는 다른 컴포넌트에 의존하지 않으므로, E를 변경할 이유는 새로운 요구사항에 의해 E의 기능을 바꾸어야 할 때이다. 하지만, A와 같은 경우, 여러 컴포넌트에 의존하고 있기 때문에, 직접적인 B, C 의존성은 물론, 간접적인 D, E의 변경 ..

1장 계층형 아키텍처의 문제는 무엇일까?

계층형 아키텍쳐란? 웹, 도메인, 영속성 계층으로 이루어져있다. 웹 계층에서는 요청을 받아 도메인 혹은 비즈니스 계층에 있는 서비스로 요청을 보낸다. 서비스는 비즈니스 로직과 도메인 엔티티의 상태 조회 및 변경을 위해 영속성 계층의 컴포넌트를 호출한다. 1. 데이터 베이스 주도 설계를 유도 웹 계층은 → 도메인 계층, 도메인 계층은 → 영속성 계층에 의존한다. 데이터 베이스 중심 아키텍쳐가 만들어지는 큰 원인은 ORM을 사용하기 때문이다. ORM에 의해 관리되는 엔티티들은 일반적으로 영속성 계층에 둔다. 이를 통해 영속성 계층과 도메인 계층에 강한 결합이 생긴다. 서비스는 영속성 모델을 비즈니스 모델처럼 사용하게 되고, 도메인 로직 뿐만 아니라, 즉시 로딩, 지연 로딩, 데이터 베이스 트랜잭션, 캐시 플..

[카카오 기출] 호텔 방 배정 풀이

알고리즘 Union-find 풀이 과정 1 ≤ k ≤ 10^12 이하이므로 long 으로 자료형을 설정한다. 주의사항 : 배열 같은 경우, index를 long으로 설정하지 못한다. → Map 자료구조 관리하여야 한다. 어려웠던 점 : parent를 찾을 때 일반적으로 배열을 사용했는데 map 자료구조를 떠올려야 했다. 시간초과 난 부분 맨 처음에 Map을 parent[i] = i 와 같은 식으로 k범위 까지 초기화 시켜줬는데, 시간초과 난다. parent를 계속 갱신 시켜주며, 가장 가까운 호텔을 parent로 다시 갱신한다. 코드 import java.util.*; class Solution { public Map parent = new HashMap(); public long findParent(l..

[백준] 1823 수확 풀이

알고리즘 DP 풀이 과정 n이 최대 2000이므로, 브루트 포스는 안될 것 같다. → 자연스레 DP를 하는 방향으로 갔다. DP는 작은 문제를 → 큰문제로 확장시켜 나가는 방식이다. 즉, 크기를 확장시키는 순서가 있어야 한다. ex) 13152 같은 경우, 양 끝쪽만 빠져나가는 것을 확인 할 수 있었다. 따라서 다음과 같은 점화식을 도출해냈다. BaseCode가 중요한데, start==end 일 경우, 맨 마지막 숫자이므로, dp[start][start] = arr[start] * n이 된다. 이를 코드로 옮기면 다음과 같다. import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import ..