SlideShare a Scribd company logo

도메인구현 KSUG 20151128

beom kyun choi
beom kyun choi
beom kyun choiSoftware Develper at SCGS

KSUG 2015-11-28 발표 자료

도메인구현 KSUG 20151128

1 of 78
Download to read offline
몇 가지
도메인 구현 이야기
최범균(madvirus@madvirus.net),	
  2015-­‐11-­‐28
내용
• DIP
• AGGREGATE과 참조
• CQRS
• 이벤트
2
#1, 아키텍처와 DIP
3
흔한 구조
ReserveService JavaMailService
Reservation Reservation
Repository
4
인프라
스트럭처
도메인
impl
패키지
응용
모듈 구조
ReserveService
JavaMailService
Reservation
Reservation
Repository
JpaReservation
Repository
JPA
5
인프라
스트럭처
도메인
impl
패키지
응용
인프라로의 의존
ReserveService
JavaMailService
Reservation
Reservation
Repository
JpaReservation
Repository
JPA
6
Ad

Recommended

DDD로 복잡함 다루기
DDD로 복잡함 다루기DDD로 복잡함 다루기
DDD로 복잡함 다루기beom kyun choi
 
도메인 주도 설계의 본질
도메인 주도 설계의 본질도메인 주도 설계의 본질
도메인 주도 설계의 본질Young-Ho Cho
 
DDD 구현기초 (거의 Final 버전)
DDD 구현기초 (거의 Final 버전)DDD 구현기초 (거의 Final 버전)
DDD 구현기초 (거의 Final 버전)beom kyun choi
 
DDD와 이벤트소싱
DDD와 이벤트소싱DDD와 이벤트소싱
DDD와 이벤트소싱Suhyeon Jo
 
[수정본] 우아한 객체지향
[수정본] 우아한 객체지향[수정본] 우아한 객체지향
[수정본] 우아한 객체지향Young-Ho Cho
 
Java Spring framework, Dependency Injection, DI, IoC, Inversion of Control
Java Spring framework, Dependency Injection, DI, IoC, Inversion of ControlJava Spring framework, Dependency Injection, DI, IoC, Inversion of Control
Java Spring framework, Dependency Injection, DI, IoC, Inversion of ControlArjun Thakur
 

More Related Content

What's hot

Jpa 잘 (하는 척) 하기
Jpa 잘 (하는 척) 하기Jpa 잘 (하는 척) 하기
Jpa 잘 (하는 척) 하기경원 이
 
이벤트 기반 분산 시스템을 향한 여정
이벤트 기반 분산 시스템을 향한 여정이벤트 기반 분산 시스템을 향한 여정
이벤트 기반 분산 시스템을 향한 여정Arawn Park
 
객체지향적인 도메인 레이어 구축하기
객체지향적인 도메인 레이어 구축하기객체지향적인 도메인 레이어 구축하기
객체지향적인 도메인 레이어 구축하기Young-Ho Cho
 
Dependency injection - the right way
Dependency injection - the right wayDependency injection - the right way
Dependency injection - the right wayThibaud Desodt
 
Legacy code refactoring video rental system
Legacy code refactoring   video rental systemLegacy code refactoring   video rental system
Legacy code refactoring video rental systemJaehoon Oh
 
자바 직렬화 (Java serialization)
자바 직렬화 (Java serialization)자바 직렬화 (Java serialization)
자바 직렬화 (Java serialization)중선 곽
 
애플리케이션 아키텍처와 객체지향
애플리케이션 아키텍처와 객체지향 애플리케이션 아키텍처와 객체지향
애플리케이션 아키텍처와 객체지향 Young-Ho Cho
 
REST API 설계
REST API 설계REST API 설계
REST API 설계Terry Cho
 
Amazon Elastcsearch Service 소개 및 활용 방법 (윤석찬)
Amazon Elastcsearch Service 소개 및 활용 방법 (윤석찬) Amazon Elastcsearch Service 소개 및 활용 방법 (윤석찬)
Amazon Elastcsearch Service 소개 및 활용 방법 (윤석찬) Amazon Web Services Korea
 
Event source 학습 내용 공유
Event source 학습 내용 공유Event source 학습 내용 공유
Event source 학습 내용 공유beom kyun choi
 
객체지향 개념 (쫌 아는체 하기)
객체지향 개념 (쫌 아는체 하기)객체지향 개념 (쫌 아는체 하기)
객체지향 개념 (쫌 아는체 하기)Seung-June Lee
 
webservice scaling for newbie
webservice scaling for newbiewebservice scaling for newbie
webservice scaling for newbieDaeMyung Kang
 
도메인 주도 설계 - 6장 도메인 객체의 생명주기
도메인 주도 설계 - 6장 도메인 객체의 생명주기도메인 주도 설계 - 6장 도메인 객체의 생명주기
도메인 주도 설계 - 6장 도메인 객체의 생명주기JangHyuk You
 
[TECHCON 2019: MOBILE - Android]3.안드로이드 개발자 로드맵
[TECHCON 2019: MOBILE - Android]3.안드로이드 개발자 로드맵[TECHCON 2019: MOBILE - Android]3.안드로이드 개발자 로드맵
[TECHCON 2019: MOBILE - Android]3.안드로이드 개발자 로드맵NAVER Engineering
 
오딘: 발할라 라이징 MMORPG의 성능 최적화 사례 공유 [카카오게임즈 - 레벨 300] - 발표자: 김문권, 팀장, 라이온하트 스튜디오...
오딘: 발할라 라이징 MMORPG의 성능 최적화 사례 공유 [카카오게임즈 - 레벨 300] - 발표자: 김문권, 팀장, 라이온하트 스튜디오...오딘: 발할라 라이징 MMORPG의 성능 최적화 사례 공유 [카카오게임즈 - 레벨 300] - 발표자: 김문권, 팀장, 라이온하트 스튜디오...
오딘: 발할라 라이징 MMORPG의 성능 최적화 사례 공유 [카카오게임즈 - 레벨 300] - 발표자: 김문권, 팀장, 라이온하트 스튜디오...Amazon Web Services Korea
 
스프링 부트와 로깅
스프링 부트와 로깅스프링 부트와 로깅
스프링 부트와 로깅Keesun Baik
 
[2018] MyBatis에서 JPA로
[2018] MyBatis에서 JPA로[2018] MyBatis에서 JPA로
[2018] MyBatis에서 JPA로NHN FORWARD
 
Domain Driven Design
Domain Driven DesignDomain Driven Design
Domain Driven DesignYoung-Ho Cho
 
Roles, Responsibilities, Collaborations
Roles, Responsibilities, CollaborationsRoles, Responsibilities, Collaborations
Roles, Responsibilities, CollaborationsYoung-Ho Cho
 
Introduction to JWT and How to integrate with Spring Security
Introduction to JWT and How to integrate with Spring SecurityIntroduction to JWT and How to integrate with Spring Security
Introduction to JWT and How to integrate with Spring SecurityBruno Henrique Rother
 

What's hot (20)

Jpa 잘 (하는 척) 하기
Jpa 잘 (하는 척) 하기Jpa 잘 (하는 척) 하기
Jpa 잘 (하는 척) 하기
 
이벤트 기반 분산 시스템을 향한 여정
이벤트 기반 분산 시스템을 향한 여정이벤트 기반 분산 시스템을 향한 여정
이벤트 기반 분산 시스템을 향한 여정
 
객체지향적인 도메인 레이어 구축하기
객체지향적인 도메인 레이어 구축하기객체지향적인 도메인 레이어 구축하기
객체지향적인 도메인 레이어 구축하기
 
Dependency injection - the right way
Dependency injection - the right wayDependency injection - the right way
Dependency injection - the right way
 
Legacy code refactoring video rental system
Legacy code refactoring   video rental systemLegacy code refactoring   video rental system
Legacy code refactoring video rental system
 
자바 직렬화 (Java serialization)
자바 직렬화 (Java serialization)자바 직렬화 (Java serialization)
자바 직렬화 (Java serialization)
 
애플리케이션 아키텍처와 객체지향
애플리케이션 아키텍처와 객체지향 애플리케이션 아키텍처와 객체지향
애플리케이션 아키텍처와 객체지향
 
REST API 설계
REST API 설계REST API 설계
REST API 설계
 
Amazon Elastcsearch Service 소개 및 활용 방법 (윤석찬)
Amazon Elastcsearch Service 소개 및 활용 방법 (윤석찬) Amazon Elastcsearch Service 소개 및 활용 방법 (윤석찬)
Amazon Elastcsearch Service 소개 및 활용 방법 (윤석찬)
 
Event source 학습 내용 공유
Event source 학습 내용 공유Event source 학습 내용 공유
Event source 학습 내용 공유
 
객체지향 개념 (쫌 아는체 하기)
객체지향 개념 (쫌 아는체 하기)객체지향 개념 (쫌 아는체 하기)
객체지향 개념 (쫌 아는체 하기)
 
webservice scaling for newbie
webservice scaling for newbiewebservice scaling for newbie
webservice scaling for newbie
 
도메인 주도 설계 - 6장 도메인 객체의 생명주기
도메인 주도 설계 - 6장 도메인 객체의 생명주기도메인 주도 설계 - 6장 도메인 객체의 생명주기
도메인 주도 설계 - 6장 도메인 객체의 생명주기
 
[TECHCON 2019: MOBILE - Android]3.안드로이드 개발자 로드맵
[TECHCON 2019: MOBILE - Android]3.안드로이드 개발자 로드맵[TECHCON 2019: MOBILE - Android]3.안드로이드 개발자 로드맵
[TECHCON 2019: MOBILE - Android]3.안드로이드 개발자 로드맵
 
오딘: 발할라 라이징 MMORPG의 성능 최적화 사례 공유 [카카오게임즈 - 레벨 300] - 발표자: 김문권, 팀장, 라이온하트 스튜디오...
오딘: 발할라 라이징 MMORPG의 성능 최적화 사례 공유 [카카오게임즈 - 레벨 300] - 발표자: 김문권, 팀장, 라이온하트 스튜디오...오딘: 발할라 라이징 MMORPG의 성능 최적화 사례 공유 [카카오게임즈 - 레벨 300] - 발표자: 김문권, 팀장, 라이온하트 스튜디오...
오딘: 발할라 라이징 MMORPG의 성능 최적화 사례 공유 [카카오게임즈 - 레벨 300] - 발표자: 김문권, 팀장, 라이온하트 스튜디오...
 
스프링 부트와 로깅
스프링 부트와 로깅스프링 부트와 로깅
스프링 부트와 로깅
 
[2018] MyBatis에서 JPA로
[2018] MyBatis에서 JPA로[2018] MyBatis에서 JPA로
[2018] MyBatis에서 JPA로
 
Domain Driven Design
Domain Driven DesignDomain Driven Design
Domain Driven Design
 
Roles, Responsibilities, Collaborations
Roles, Responsibilities, CollaborationsRoles, Responsibilities, Collaborations
Roles, Responsibilities, Collaborations
 
Introduction to JWT and How to integrate with Spring Security
Introduction to JWT and How to integrate with Spring SecurityIntroduction to JWT and How to integrate with Spring Security
Introduction to JWT and How to integrate with Spring Security
 

Viewers also liked

Ddd start 부록 지앤선&ksug
Ddd start 부록 지앤선&ksugDdd start 부록 지앤선&ksug
Ddd start 부록 지앤선&ksugbeom kyun choi
 
모델링 연습 리뷰
모델링 연습 리뷰모델링 연습 리뷰
모델링 연습 리뷰beom kyun choi
 
객체 지향 발담그기 JCO 컨퍼런스 14회
객체 지향 발담그기 JCO 컨퍼런스 14회객체 지향 발담그기 JCO 컨퍼런스 14회
객체 지향 발담그기 JCO 컨퍼런스 14회beom kyun choi
 
아꿈사 DDD(Domain-Driven Design) 5장 소프트웨어에서 표현되는 모델
아꿈사 DDD(Domain-Driven Design) 5장 소프트웨어에서 표현되는 모델아꿈사 DDD(Domain-Driven Design) 5장 소프트웨어에서 표현되는 모델
아꿈사 DDD(Domain-Driven Design) 5장 소프트웨어에서 표현되는 모델명환 안
 
도메인 주도 설계 (Domain Driven Design)
도메인 주도 설계 (Domain Driven Design)도메인 주도 설계 (Domain Driven Design)
도메인 주도 설계 (Domain Driven Design)Ashal aka JOKER
 
Domain driven design 8장
Domain driven design 8장Domain driven design 8장
Domain driven design 8장kukuman
 

Viewers also liked (8)

Ddd start 부록 지앤선&ksug
Ddd start 부록 지앤선&ksugDdd start 부록 지앤선&ksug
Ddd start 부록 지앤선&ksug
 
모델링 연습 리뷰
모델링 연습 리뷰모델링 연습 리뷰
모델링 연습 리뷰
 
객체 지향 발담그기 JCO 컨퍼런스 14회
객체 지향 발담그기 JCO 컨퍼런스 14회객체 지향 발담그기 JCO 컨퍼런스 14회
객체 지향 발담그기 JCO 컨퍼런스 14회
 
DDD 산책
DDD 산책DDD 산책
DDD 산책
 
MVP 패턴 소개
MVP 패턴 소개MVP 패턴 소개
MVP 패턴 소개
 
아꿈사 DDD(Domain-Driven Design) 5장 소프트웨어에서 표현되는 모델
아꿈사 DDD(Domain-Driven Design) 5장 소프트웨어에서 표현되는 모델아꿈사 DDD(Domain-Driven Design) 5장 소프트웨어에서 표현되는 모델
아꿈사 DDD(Domain-Driven Design) 5장 소프트웨어에서 표현되는 모델
 
도메인 주도 설계 (Domain Driven Design)
도메인 주도 설계 (Domain Driven Design)도메인 주도 설계 (Domain Driven Design)
도메인 주도 설계 (Domain Driven Design)
 
Domain driven design 8장
Domain driven design 8장Domain driven design 8장
Domain driven design 8장
 

Similar to 도메인구현 KSUG 20151128

From event storming to spring cloud implementation
From event storming to spring cloud implementationFrom event storming to spring cloud implementation
From event storming to spring cloud implementationuEngine Solutions
 
The Cucumber for Java
The Cucumber for JavaThe Cucumber for Java
The Cucumber for JavaJonghwa Lee
 
안드로이드 오픈소스 그리고 패턴
안드로이드 오픈소스 그리고 패턴  안드로이드 오픈소스 그리고 패턴
안드로이드 오픈소스 그리고 패턴 YoungSu Son
 
안드로이드 오픈소스 패턴 - 0.1
안드로이드 오픈소스 패턴 - 0.1안드로이드 오픈소스 패턴 - 0.1
안드로이드 오픈소스 패턴 - 0.1YoungSu Son
 
CloudWatch 성능 모니터링과 신속한 대응을 위한 노하우 - 박선용 솔루션즈 아키텍트:: AWS Cloud Track 3 Gaming
CloudWatch 성능 모니터링과 신속한 대응을 위한 노하우 - 박선용 솔루션즈 아키텍트:: AWS Cloud Track 3 GamingCloudWatch 성능 모니터링과 신속한 대응을 위한 노하우 - 박선용 솔루션즈 아키텍트:: AWS Cloud Track 3 Gaming
CloudWatch 성능 모니터링과 신속한 대응을 위한 노하우 - 박선용 솔루션즈 아키텍트:: AWS Cloud Track 3 GamingAmazon Web Services Korea
 
기업 IT 담당자라면 꼭 알아야 할 Enterprise AWS 사례와 특징::김종호, 조영준 BSG Partners::AWS Summit ...
기업 IT 담당자라면 꼭 알아야 할 Enterprise AWS 사례와 특징::김종호, 조영준 BSG Partners::AWS Summit ...기업 IT 담당자라면 꼭 알아야 할 Enterprise AWS 사례와 특징::김종호, 조영준 BSG Partners::AWS Summit ...
기업 IT 담당자라면 꼭 알아야 할 Enterprise AWS 사례와 특징::김종호, 조영준 BSG Partners::AWS Summit ...Amazon Web Services Korea
 
기업 IT 담당자라면 꼭 알아야 할 Enterprise AWS 사례와 특징::김종호, 조영준 BSG Partners::AWS Summit ...
기업 IT 담당자라면 꼭 알아야 할 Enterprise AWS 사례와 특징::김종호, 조영준 BSG Partners::AWS Summit ...기업 IT 담당자라면 꼭 알아야 할 Enterprise AWS 사례와 특징::김종호, 조영준 BSG Partners::AWS Summit ...
기업 IT 담당자라면 꼭 알아야 할 Enterprise AWS 사례와 특징::김종호, 조영준 BSG Partners::AWS Summit ...Amazon Web Services Korea
 
GraphQL in Action - REST와 이별할 때 생각해야 하는 것들
GraphQL in Action - REST와 이별할 때 생각해야 하는 것들GraphQL in Action - REST와 이별할 때 생각해야 하는 것들
GraphQL in Action - REST와 이별할 때 생각해야 하는 것들Kivol
 
GKAC 2015 Apr. - Battery, 안드로이드를 위한 쉬운 웹 API 호출
GKAC 2015 Apr. - Battery, 안드로이드를 위한 쉬운 웹 API 호출GKAC 2015 Apr. - Battery, 안드로이드를 위한 쉬운 웹 API 호출
GKAC 2015 Apr. - Battery, 안드로이드를 위한 쉬운 웹 API 호출GDG Korea
 
안드로이드 개발자에 필요한 오픈소스이야기
안드로이드 개발자에 필요한 오픈소스이야기안드로이드 개발자에 필요한 오픈소스이야기
안드로이드 개발자에 필요한 오픈소스이야기YoungSu Son
 
Cloud-Barista 제5차 오픈 컨퍼런스 : 멀티클라우드 인프라 연동 (CB-Spider)
Cloud-Barista 제5차 오픈 컨퍼런스 : 멀티클라우드 인프라 연동 (CB-Spider)Cloud-Barista 제5차 오픈 컨퍼런스 : 멀티클라우드 인프라 연동 (CB-Spider)
Cloud-Barista 제5차 오픈 컨퍼런스 : 멀티클라우드 인프라 연동 (CB-Spider)Cloud-Barista Community
 
엔터프라이즈 클라우드 마이그레이션 준비와 실행. 그리고, 클라우드 운영 모범 사례 공유-최지웅, 오픈소스컨설팅 CTO / 장진환, 스마일샤...
엔터프라이즈 클라우드 마이그레이션 준비와 실행. 그리고, 클라우드 운영 모범 사례 공유-최지웅, 오픈소스컨설팅 CTO / 장진환, 스마일샤...엔터프라이즈 클라우드 마이그레이션 준비와 실행. 그리고, 클라우드 운영 모범 사례 공유-최지웅, 오픈소스컨설팅 CTO / 장진환, 스마일샤...
엔터프라이즈 클라우드 마이그레이션 준비와 실행. 그리고, 클라우드 운영 모범 사례 공유-최지웅, 오픈소스컨설팅 CTO / 장진환, 스마일샤...Amazon Web Services Korea
 
Aurora MySQL Backtrack을 이용한 빠른 복구 방법 - 진교선 :: AWS Database Modernization Day 온라인
Aurora MySQL Backtrack을 이용한 빠른 복구 방법 - 진교선 :: AWS Database Modernization Day 온라인Aurora MySQL Backtrack을 이용한 빠른 복구 방법 - 진교선 :: AWS Database Modernization Day 온라인
Aurora MySQL Backtrack을 이용한 빠른 복구 방법 - 진교선 :: AWS Database Modernization Day 온라인Amazon Web Services Korea
 
ksqlDB로 시작하는 스트림 프로세싱
ksqlDB로 시작하는 스트림 프로세싱ksqlDB로 시작하는 스트림 프로세싱
ksqlDB로 시작하는 스트림 프로세싱confluent
 
React native 개발 및 javascript 기본
React native 개발 및 javascript 기본React native 개발 및 javascript 기본
React native 개발 및 javascript 기본Tj .
 
기업 IT 담당자라면 꼭 알아야 할 Enterprise AWS 사례와 특징::김종호 상무, 조영준 상무, BSG::AWS Summit Se...
기업 IT 담당자라면 꼭 알아야 할 Enterprise AWS 사례와 특징::김종호 상무, 조영준 상무, BSG::AWS Summit Se...기업 IT 담당자라면 꼭 알아야 할 Enterprise AWS 사례와 특징::김종호 상무, 조영준 상무, BSG::AWS Summit Se...
기업 IT 담당자라면 꼭 알아야 할 Enterprise AWS 사례와 특징::김종호 상무, 조영준 상무, BSG::AWS Summit Se...Amazon Web Services Korea
 
[2017 AWS Startup Day] AWS 비용 최대 90% 절감하기: 스팟 인스턴스 Deep-Dive
[2017 AWS Startup Day] AWS 비용 최대 90% 절감하기: 스팟 인스턴스 Deep-Dive [2017 AWS Startup Day] AWS 비용 최대 90% 절감하기: 스팟 인스턴스 Deep-Dive
[2017 AWS Startup Day] AWS 비용 최대 90% 절감하기: 스팟 인스턴스 Deep-Dive Amazon Web Services Korea
 
자바 웹 개발 시작하기 (6주차 : 커뮤니티를 만들어보자!)
자바 웹 개발 시작하기 (6주차 : 커뮤니티를 만들어보자!)자바 웹 개발 시작하기 (6주차 : 커뮤니티를 만들어보자!)
자바 웹 개발 시작하기 (6주차 : 커뮤니티를 만들어보자!)DK Lee
 

Similar to 도메인구현 KSUG 20151128 (20)

From event storming to spring cloud implementation
From event storming to spring cloud implementationFrom event storming to spring cloud implementation
From event storming to spring cloud implementation
 
The Cucumber for Java
The Cucumber for JavaThe Cucumber for Java
The Cucumber for Java
 
CQRS
CQRSCQRS
CQRS
 
안드로이드 오픈소스 그리고 패턴
안드로이드 오픈소스 그리고 패턴  안드로이드 오픈소스 그리고 패턴
안드로이드 오픈소스 그리고 패턴
 
안드로이드 오픈소스 패턴 - 0.1
안드로이드 오픈소스 패턴 - 0.1안드로이드 오픈소스 패턴 - 0.1
안드로이드 오픈소스 패턴 - 0.1
 
CloudWatch 성능 모니터링과 신속한 대응을 위한 노하우 - 박선용 솔루션즈 아키텍트:: AWS Cloud Track 3 Gaming
CloudWatch 성능 모니터링과 신속한 대응을 위한 노하우 - 박선용 솔루션즈 아키텍트:: AWS Cloud Track 3 GamingCloudWatch 성능 모니터링과 신속한 대응을 위한 노하우 - 박선용 솔루션즈 아키텍트:: AWS Cloud Track 3 Gaming
CloudWatch 성능 모니터링과 신속한 대응을 위한 노하우 - 박선용 솔루션즈 아키텍트:: AWS Cloud Track 3 Gaming
 
기업 IT 담당자라면 꼭 알아야 할 Enterprise AWS 사례와 특징::김종호, 조영준 BSG Partners::AWS Summit ...
기업 IT 담당자라면 꼭 알아야 할 Enterprise AWS 사례와 특징::김종호, 조영준 BSG Partners::AWS Summit ...기업 IT 담당자라면 꼭 알아야 할 Enterprise AWS 사례와 특징::김종호, 조영준 BSG Partners::AWS Summit ...
기업 IT 담당자라면 꼭 알아야 할 Enterprise AWS 사례와 특징::김종호, 조영준 BSG Partners::AWS Summit ...
 
기업 IT 담당자라면 꼭 알아야 할 Enterprise AWS 사례와 특징::김종호, 조영준 BSG Partners::AWS Summit ...
기업 IT 담당자라면 꼭 알아야 할 Enterprise AWS 사례와 특징::김종호, 조영준 BSG Partners::AWS Summit ...기업 IT 담당자라면 꼭 알아야 할 Enterprise AWS 사례와 특징::김종호, 조영준 BSG Partners::AWS Summit ...
기업 IT 담당자라면 꼭 알아야 할 Enterprise AWS 사례와 특징::김종호, 조영준 BSG Partners::AWS Summit ...
 
GraphQL in Action - REST와 이별할 때 생각해야 하는 것들
GraphQL in Action - REST와 이별할 때 생각해야 하는 것들GraphQL in Action - REST와 이별할 때 생각해야 하는 것들
GraphQL in Action - REST와 이별할 때 생각해야 하는 것들
 
GKAC 2015 Apr. - Battery, 안드로이드를 위한 쉬운 웹 API 호출
GKAC 2015 Apr. - Battery, 안드로이드를 위한 쉬운 웹 API 호출GKAC 2015 Apr. - Battery, 안드로이드를 위한 쉬운 웹 API 호출
GKAC 2015 Apr. - Battery, 안드로이드를 위한 쉬운 웹 API 호출
 
안드로이드 개발자에 필요한 오픈소스이야기
안드로이드 개발자에 필요한 오픈소스이야기안드로이드 개발자에 필요한 오픈소스이야기
안드로이드 개발자에 필요한 오픈소스이야기
 
Cloud-Barista 제5차 오픈 컨퍼런스 : 멀티클라우드 인프라 연동 (CB-Spider)
Cloud-Barista 제5차 오픈 컨퍼런스 : 멀티클라우드 인프라 연동 (CB-Spider)Cloud-Barista 제5차 오픈 컨퍼런스 : 멀티클라우드 인프라 연동 (CB-Spider)
Cloud-Barista 제5차 오픈 컨퍼런스 : 멀티클라우드 인프라 연동 (CB-Spider)
 
엔터프라이즈 클라우드 마이그레이션 준비와 실행. 그리고, 클라우드 운영 모범 사례 공유-최지웅, 오픈소스컨설팅 CTO / 장진환, 스마일샤...
엔터프라이즈 클라우드 마이그레이션 준비와 실행. 그리고, 클라우드 운영 모범 사례 공유-최지웅, 오픈소스컨설팅 CTO / 장진환, 스마일샤...엔터프라이즈 클라우드 마이그레이션 준비와 실행. 그리고, 클라우드 운영 모범 사례 공유-최지웅, 오픈소스컨설팅 CTO / 장진환, 스마일샤...
엔터프라이즈 클라우드 마이그레이션 준비와 실행. 그리고, 클라우드 운영 모범 사례 공유-최지웅, 오픈소스컨설팅 CTO / 장진환, 스마일샤...
 
Aurora MySQL Backtrack을 이용한 빠른 복구 방법 - 진교선 :: AWS Database Modernization Day 온라인
Aurora MySQL Backtrack을 이용한 빠른 복구 방법 - 진교선 :: AWS Database Modernization Day 온라인Aurora MySQL Backtrack을 이용한 빠른 복구 방법 - 진교선 :: AWS Database Modernization Day 온라인
Aurora MySQL Backtrack을 이용한 빠른 복구 방법 - 진교선 :: AWS Database Modernization Day 온라인
 
OpenStack Swift Debugging
OpenStack Swift DebuggingOpenStack Swift Debugging
OpenStack Swift Debugging
 
ksqlDB로 시작하는 스트림 프로세싱
ksqlDB로 시작하는 스트림 프로세싱ksqlDB로 시작하는 스트림 프로세싱
ksqlDB로 시작하는 스트림 프로세싱
 
React native 개발 및 javascript 기본
React native 개발 및 javascript 기본React native 개발 및 javascript 기본
React native 개발 및 javascript 기본
 
기업 IT 담당자라면 꼭 알아야 할 Enterprise AWS 사례와 특징::김종호 상무, 조영준 상무, BSG::AWS Summit Se...
기업 IT 담당자라면 꼭 알아야 할 Enterprise AWS 사례와 특징::김종호 상무, 조영준 상무, BSG::AWS Summit Se...기업 IT 담당자라면 꼭 알아야 할 Enterprise AWS 사례와 특징::김종호 상무, 조영준 상무, BSG::AWS Summit Se...
기업 IT 담당자라면 꼭 알아야 할 Enterprise AWS 사례와 특징::김종호 상무, 조영준 상무, BSG::AWS Summit Se...
 
[2017 AWS Startup Day] AWS 비용 최대 90% 절감하기: 스팟 인스턴스 Deep-Dive
[2017 AWS Startup Day] AWS 비용 최대 90% 절감하기: 스팟 인스턴스 Deep-Dive [2017 AWS Startup Day] AWS 비용 최대 90% 절감하기: 스팟 인스턴스 Deep-Dive
[2017 AWS Startup Day] AWS 비용 최대 90% 절감하기: 스팟 인스턴스 Deep-Dive
 
자바 웹 개발 시작하기 (6주차 : 커뮤니티를 만들어보자!)
자바 웹 개발 시작하기 (6주차 : 커뮤니티를 만들어보자!)자바 웹 개발 시작하기 (6주차 : 커뮤니티를 만들어보자!)
자바 웹 개발 시작하기 (6주차 : 커뮤니티를 만들어보자!)
 

More from beom kyun choi

옛날 웹 개발자가 잠깐 맛본 Vue.js 소개
옛날 웹 개발자가 잠깐 맛본 Vue.js 소개옛날 웹 개발자가 잠깐 맛본 Vue.js 소개
옛날 웹 개발자가 잠깐 맛본 Vue.js 소개beom kyun choi
 
TDD 발담그기 @ 공감세미나
TDD 발담그기 @ 공감세미나TDD 발담그기 @ 공감세미나
TDD 발담그기 @ 공감세미나beom kyun choi
 
keras 빨리 훑어보기(intro)
keras 빨리 훑어보기(intro)keras 빨리 훑어보기(intro)
keras 빨리 훑어보기(intro)beom kyun choi
 
Tensorflow regression 텐서플로우 회귀
Tensorflow regression 텐서플로우 회귀Tensorflow regression 텐서플로우 회귀
Tensorflow regression 텐서플로우 회귀beom kyun choi
 
파이썬 언어 기초
파이썬 언어 기초파이썬 언어 기초
파이썬 언어 기초beom kyun choi
 
ALS WS에 대한 이해 자료
ALS WS에 대한 이해 자료ALS WS에 대한 이해 자료
ALS WS에 대한 이해 자료beom kyun choi
 
Ji 개발 리뷰 (신림프로그래머)
Ji 개발 리뷰 (신림프로그래머)Ji 개발 리뷰 (신림프로그래머)
Ji 개발 리뷰 (신림프로그래머)beom kyun choi
 
리뷰의 기술 소개
리뷰의 기술 소개리뷰의 기술 소개
리뷰의 기술 소개beom kyun choi
 
스프링 시큐리티 구조 이해
스프링 시큐리티 구조 이해스프링 시큐리티 구조 이해
스프링 시큐리티 구조 이해beom kyun choi
 
자바8 스트림 API 소개
자바8 스트림 API 소개자바8 스트림 API 소개
자바8 스트림 API 소개beom kyun choi
 
자바8 람다식 소개
자바8 람다식 소개자바8 람다식 소개
자바8 람다식 소개beom kyun choi
 
하둡2 YARN 짧게 보기
하둡2 YARN 짧게 보기하둡2 YARN 짧게 보기
하둡2 YARN 짧게 보기beom kyun choi
 
차원축소 훑어보기 (PCA, SVD, NMF)
차원축소 훑어보기 (PCA, SVD, NMF)차원축소 훑어보기 (PCA, SVD, NMF)
차원축소 훑어보기 (PCA, SVD, NMF)beom kyun choi
 
Hive 입문 발표 자료
Hive 입문 발표 자료Hive 입문 발표 자료
Hive 입문 발표 자료beom kyun choi
 
하둡 맵리듀스 훑어보기
하둡 맵리듀스 훑어보기하둡 맵리듀스 훑어보기
하둡 맵리듀스 훑어보기beom kyun choi
 

More from beom kyun choi (20)

옛날 웹 개발자가 잠깐 맛본 Vue.js 소개
옛날 웹 개발자가 잠깐 맛본 Vue.js 소개옛날 웹 개발자가 잠깐 맛본 Vue.js 소개
옛날 웹 개발자가 잠깐 맛본 Vue.js 소개
 
TDD 발담그기 @ 공감세미나
TDD 발담그기 @ 공감세미나TDD 발담그기 @ 공감세미나
TDD 발담그기 @ 공감세미나
 
keras 빨리 훑어보기(intro)
keras 빨리 훑어보기(intro)keras 빨리 훑어보기(intro)
keras 빨리 훑어보기(intro)
 
Tensorflow regression 텐서플로우 회귀
Tensorflow regression 텐서플로우 회귀Tensorflow regression 텐서플로우 회귀
Tensorflow regression 텐서플로우 회귀
 
파이썬 언어 기초
파이썬 언어 기초파이썬 언어 기초
파이썬 언어 기초
 
Spring Boot 소개
Spring Boot 소개Spring Boot 소개
Spring Boot 소개
 
ALS WS에 대한 이해 자료
ALS WS에 대한 이해 자료ALS WS에 대한 이해 자료
ALS WS에 대한 이해 자료
 
Ji 개발 리뷰 (신림프로그래머)
Ji 개발 리뷰 (신림프로그래머)Ji 개발 리뷰 (신림프로그래머)
Ji 개발 리뷰 (신림프로그래머)
 
리뷰의 기술 소개
리뷰의 기술 소개리뷰의 기술 소개
리뷰의 기술 소개
 
스프링 시큐리티 구조 이해
스프링 시큐리티 구조 이해스프링 시큐리티 구조 이해
스프링 시큐리티 구조 이해
 
자바8 스트림 API 소개
자바8 스트림 API 소개자바8 스트림 API 소개
자바8 스트림 API 소개
 
자바8 람다식 소개
자바8 람다식 소개자바8 람다식 소개
자바8 람다식 소개
 
Zookeeper 소개
Zookeeper 소개Zookeeper 소개
Zookeeper 소개
 
하둡2 YARN 짧게 보기
하둡2 YARN 짧게 보기하둡2 YARN 짧게 보기
하둡2 YARN 짧게 보기
 
차원축소 훑어보기 (PCA, SVD, NMF)
차원축소 훑어보기 (PCA, SVD, NMF)차원축소 훑어보기 (PCA, SVD, NMF)
차원축소 훑어보기 (PCA, SVD, NMF)
 
Storm 훑어보기
Storm 훑어보기Storm 훑어보기
Storm 훑어보기
 
Hive 입문 발표 자료
Hive 입문 발표 자료Hive 입문 발표 자료
Hive 입문 발표 자료
 
HBase 훑어보기
HBase 훑어보기HBase 훑어보기
HBase 훑어보기
 
Flume 훑어보기
Flume 훑어보기Flume 훑어보기
Flume 훑어보기
 
하둡 맵리듀스 훑어보기
하둡 맵리듀스 훑어보기하둡 맵리듀스 훑어보기
하둡 맵리듀스 훑어보기
 

도메인구현 KSUG 20151128

  • 1. 몇 가지 도메인 구현 이야기 최범균(madvirus@madvirus.net),  2015-­‐11-­‐28
  • 2. 내용 • DIP • AGGREGATE과 참조 • CQRS • 이벤트 2
  • 7. 인프라에 의존할 때의 흔한 단점 • 구현교체의어려움 • 응용서비스나 도메인로직테스트어려움 7
  • 8. 원인 à고수준/저수준이 뒤섞임, 즉, 저수준이 고수준에 영향을 줌 ReserveService: 예약을 위한 응용 로직 à 고수준 Java API로 메일을 발송 à 저수준 도메인: 객체 영속성 à 고수준 JPA로 보관 à 저수준 RDBMS에 보관 à 저저수준 • 고수준모듈:  의미있는단일기능을제공하는 모듈 • 저수준모듈:고수준모듈의기능을구현하기 위해필요한 하위기능의실제구현 8
  • 9. DEPENDENCY INVERSION PRINCIPLE • 뒤섞임을 제거하려면 à 고수준입장에서 저수준 구현을추상화해서 의존을뒤집음 ReserveService <<interface>> EmailNotifier JavaMail EmailNotifier 응용 로직을 구성하는 “이메일 통지하기"를 표현 9 ReserveService JavaMailService
  • 10. DIP 적용 예 “저수준의 상세한 내용 없이 구현하기” 참고, http://javacan.tistory.com 10
  • 13. 올바른 DIP 적용 도메인 SomeDomainService Reservation Repository 13 응용 ReserveService 인프라 스트럭처 Email Notifier Java EmailNotifier JpaReservation Repository
  • 14. DIP 적용 아키텍처 Reserve Service Reservation Reservation Repository JpaReservation Repository Email Notifier JavaMail EmailNotifier Controller Message Listener 14
  • 15. 노력 • 끊임없는 추상화연습 • DIP  à고수준 모듈입장에서 추상화 15
  • 19. 상위 수준에서 묶어서 생각하면 19
  • 20. AGGREGATE = 개념적으로 하나인 객체 군 <<ROOT>> Order OrderLineShippingInfo Orderer 20
  • 21. AGGREGATE • 관련된객체들의 묶음 • 특징 • 데이터변경시 한단위로 처리됨 • 비슷한또는거의유사한 라이프사이클을 갖는객체들 • 특히,  삭제시함께삭제됨 • 경계를가짐 • 기본적으로,  한Aggregate에 속한객체는다른Aggregate에 속하지않음 • 필요성 • 많은도메인모델을 가능한간단하고 이해가능한 수준으 로만들필요 • 연관의개수를 줄임으로써 복잡도 감소 21
  • 22. AGGREGATE = 개념적으로 하나인 객체 군 Order  order  =  orderRepository.findById(orderId); order.changeShippingInfo(newShippingInfo); order.calcel(); 완전체를 로딩 AGG  ROOT가 로직/ 일관성(트랜잭션) 처리  책임 22
  • 23. 도메인 모델에서 AGG 찾기 Showing Reservation Customer Movie DiscountStrategy Rule SeatNo Grade 23
  • 24. 요구 사항에 따라AGG 경계 정의 예매시영화의시간과 좌석을할당한다 회원은등급을갖는다 영화는 상영일정을갖는다? 영화별로가격할인규칙이다르다 (영화별로다른가격할인을갖는다?) 24
  • 25. AGG 경계 : 규칙〮트랜잭션 범위 상영관리자가 영화일정을추가해도 영화정보는바뀌지않음 컨텐츠담당자가 영화출연자정보를변경해도 상영일정은바뀌지않음 동시성 처리를 할 때, Moive를 변경하는 동안 관련 Showing을 잠금 필요가 없음 Showing Movie 25
  • 26. AGG 경계 : 규칙〮트랜잭션 범위 Movie DiscountStrategy Rule • 영화 별로 할인 정책이 고정된다. • 할인 정책 별로 적용 가능 규칙을 갖는다. Movie가 AGG  루트: • movie.updateDescription(desc); • movie.changeDiscountStrategies(discountStrategies); • movie.calculateFee(showing); 26
  • 27. AGG 경계 : SRP Movie DiscountStrategy Rule • Movie는 영화 정보 제공하는 책임만 갖도록 구성 • 할인 계산은 별도 모듈로 분리 FeeCalculator feeCalculator.calculate(movie,  showing) 27
  • 28. 편리한 참조? Showing Reservation Customer Movie reservation.getShowing().getTime() reservation.getShowing().getMovie().getTitle() reservation.getCustomer().getName() 28
  • 29. AGG 간 참조의 잠재적 문제 편한탐색을오용 (불필요한) 고민 showing.getMovie().changeDescription(…); showing.changeDiscountStrategy(disStrategy); //  Showing.java public  void  changeDiscountStrategy(List<DiscountStrategy>   strategies)  { this.movie.changeDiscountStrategy(strategies); } Lazy  Loading  vs  Earger  Loading?  OSIV? 29
  • 30. AGG 간 참조의 잠재적 문제 확장 방해 Oracle MySQL Custom  Rule  Engine 30
  • 31. AGG 간 ID로 참조하기 public  class  Showing  { … private  MovieId movieId; … } public  class  Reservation  { … private  ShowingId showingId; private  CustomerId customerId; … } Showing Reservation Customer 31
  • 32. 연관 객체 조합은 응용 서비스에서 처리 public  class  ReserveService   { public  ReservationId  reserve(ShowingId   showingId,  CustomerId  customerId)  { Showing  showing  =  showingRepository.findById(showingId); checkNotNull(shwoing); Movie  movie  =  movieRepository.findById(showing.getMovie()); checkNotNull(movie); Customer  customer  =  customerRepository.findById(customerId); checkNotNull(customer); Reservation  reservation  =  reservationFactory.create( showing,  customer,  movie.calculateFee(showing) ); return  reservation.getId(); } … } 32
  • 33. ID 참조의 특징 • 복잡도낮춤 • 모델복잡도 • 구현복잡도 • Lazy  Loading효과 • 오용방지 • 응집도강화 • AGG별로 확장가능 • 조회성능영향 • 별도모듈 • 더많은코드 33
  • 34. 노력 • 인내필요 • 당장바꾸기힘든DB  조인중심표준 • 조인에집착하는 개발자 • 기술을떠나구현할 수있는실력쌓기 • 꼭ORM이 있어야AGGREGATE를 구현할수있는것은아님 • 기술중심이아닌도메인 중심으로AGGREGATE를 생각 34
  • 36. 도메인 모델로 뷰 처리 ${resList[0].customer.name}님의 예매 목록: <c:forEach  var='res'  items='${resList}'> 예매번호 : ${res.number} 영화 : <a  href="…?id=${res.showing.movie.id"> ${res.showing.movie.title} </a> 시간 : ${res.showing.time} 금액 : ${res.fee} </c:forEach> 참조로 다 연결한 경우 List<Reservation>  resList    = reservationRepository.findByCustomer(customerId); model.addAttribute("resList",   resList); 36
  • 37. 복잡한 도메인의 조회 기능 특징 • 여러AGG에걸쳐데이터접근 Showing -­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐ id:  ShowingId time:  Time … Reservation -­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐ number:  ReservationNo showing:   ShowingId customer:   CustomerId fee:  Money … Customer -­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐ id:  CustomerId name:  String … Movie -­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐ id:  MovieId title:   String description:   String … ${resList[0].customer.name}님의 예매 목록: <c:forEach9var='res'9items='${resList}'> 예매번호 : ${res.number} 영화 : <a9href="…?id=${res.showing.movie.id"> ${res.showing.movie.title} </a> 시간 : ${res.showing.time} 금액 : ${res.fee} </c:forEach> 37
  • 38. 복잡한 도메인의 조회 기능 특징 • 성능중요 • 최대한빨리사용자에게 화면을제공해야 함 • 고민 • 한방쿼리! • 레프트조인! • DB  전용기능! • … 38
  • 39. 한 모델로 처리하면 한방쿼리! 레프트조인! DB  전용기능! … 같은연관에대해 Lazy  Loading Eager  Loading Batch  Loading … 도메인모델구현복잡도 증가 39
  • 40. 상태 변경 모델과 조회 모델 분리 [출처 :  http://martinfowler.com/bliki/CQRS.html] 40
  • 41. 조회 전용 모델 ReservationList -­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐ customerName:   String reservations:   List<ReservationData> … ReservationData -­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐ number:   String movieId:   String movieTitle:   String showingTime:   Time fee:  Money … ${resList.customerName}님의 예매목록: <c:forEach  var='res'  items='${resList.reservations}'> 예매번호:${res.number} 영화:<a  href="…?id=${res.movieId"> ${res.movieTitle} </a> 시간:${res.showingTime} 금액:${res.fee} </c:forEach> 41
  • 42. 다른 기술, 다른 아키텍처 사용 DAO (MyBatis) 컨트롤러 뷰 모델 컨트롤러 응용 서비스 도메인 인프라(JPA) 42
  • 43. 다른 저장소 사용 DAO 컨트롤러컨트롤러 응용 서비스 도메인 인프라(JPA,  메시징) 43
  • 44. 같은 기술, 뷰 모델 추가 컨트롤러 뷰 데이터 모델 컨트롤러 응용 서비스 도메인 인프라(JPA) 응용 서비스 44
  • 46. CQRS 이점 • 조회성능향상에유리 조회전용DB를사용한처리량 향상 조회에특화된쿼리 조회단위캐시기술적용 46
  • 47. 부담 요인 • 더많은코드,  더많은기술 더 많은 코드 데이터 동기화 처리 더 많은 구현 기술 47
  • 48. 노력 • 장점과단점을 고려해서 CQRS  도입여부결정필요 • 트래픽이 없는데조회전용저장소고집하지 말것 • 트래픽이 증가하면 조회전용저장소도입검토 • 도메인이 복잡하면 효과있음 • 더많은코드à더많은시간:  X • 한모델로 뷰처리비용>>  뷰모델로 처리비용:  O 48
  • 50. 예매 취소시 환급하려면? • 도메인모델에서 처리? 50 public  class  Reservation  { public  void  cancel(RefundService   refundSvc)  { …  //취소처리 refundStatus  =  State.REFUND_STARTED; try  { refundSvc.refund(this.paymentId); refundStatus  =  State.REFUND_COMPLETED; }  catch(SomeException   ex)  { … } } }
  • 51. 예매 취소시 환급하려면? • 응용서비스에서 처리? 51 public  class  CancelReservation   { @Transactional public  void  cancel(ReservationId   resId)  { Reservation  res  =  findById(resId); res.cancel(); res.refundStarted(); try  { refundSvc.refund(res.getPaymentId()); res.refundCompleted(); }  catch(SomeException   ex)  { …   } } }
  • 52. 고민거리 : 트랜잭션? 52 public   class  Reservation   { public   void  cancel(RefundService   refundSvc)   { …  //취소처리 refundStatus   =  State.REFUND_STARTED; try  { refundSvc.refund(this.paymentId); refundStatus   =  State.REFUND_COMPLETED; }  catch(SomeException   ex)  { … } } } public   class  CancelReservation   { @Transactional public   void  cancel(ReservationId   resId)  { Reservation   res  =  findById(resId); res.cancel(); res.refundStarted(); try  { refundSvc.refund(res.getPaymentId()); res.refundCompleted(); }  catch(SomeException   ex)  { …   } } } 외부 서비스가 정상이 아닐 경우, 트랜잭션 처리는?
  • 53. 고민거리 : 성능 53 public   class  Reservation   { public   void  cancel(RefundService   refundSvc)   { …  //취소처리 refundStatus   =  State.REFUND_STARTED; try  { refundSvc.refund(this.paymentId); refundStatus   =  State.REFUND_COMPLETED; }  catch(SomeException   ex)  { … } } } public   class  CancelReservation   { @Transactional public   void  cancel(ReservationId   resId)  { Reservation   res  =  findById(resId); res.cancel(); res.refundStarted(); try  { refundSvc.refund(res.getPaymentId()); res.refundCompleted(); }  catch(SomeException   ex)  { …   } } } 외부 서비스 완료까지 쓰레드 블록킹
  • 54. 고민거리 : 설계 54 public   class  Reservation   { public   void  cancel(RefundService   refundSvc)   { …  //취소처리 refundStatus   =  State.REFUND_STARTED; try  { refundSvc.refund(this.paymentId); refundStatus   =  State.REFUND_COMPLETED; }  catch(SomeException   ex)  { … } } } public   class  CancelReservation   { @Transactional public   void  cancel(ReservationId   resId)  { Reservation   res  =  findById(resId); res.cancel(); res.refundStarted(); try  { refundSvc.refund(res.getPaymentId()); res.refundCompleted(); }  catch(SomeException   ex)  { …   } } } 예매 도메인 모델에 환불 도메인 로직이 섞임
  • 55. 고민거리 : 설계 55 public   class  Reservation   { public   void  cancel(RefundService   refundSvc)  { …  //취소처리 refundStatus   =  State.REFUND_STARTED; try  { refundSvc.refund(this.paymentId); refundStatus   =  State.REFUND_COMPLETED; }  catch(SomeException   ex)  { … } } } public   class  CancelReservation   { @Transactional public   void  cancel(ReservationId   resId)  { Reservation   res  =  findById(resId); res.cancel(); res.refundStarted(); try  { refundSvc.refund(res.getPaymentId()); res.refundCompleted(); }  catch(SomeException   ex)  { …   } } } 기능이 추가되면 필요한 객체 파라미터 추가? DI로 주입 시도?
  • 56. 적용해 볼 만한 것 56 이벤트 + 비동기
  • 57. 이벤트 • 과거에벌어진 어떤것 • 주로상태의변화 • 이벤트예 • 영화추가함(NewMoviedCreated) • 예매함(RevervationCreated) • 영화상영일정추가함(ShowingAdded) • 영화정보변경함(MovieInfoChanged) • 영화가격정책변경함(PricePolicyUpdated) • 예매취소함(ReservationCanceled) 57
  • 58. 이벤트의 구성 • 구성 • 발생주체(주로 식별자),  일렬번호/버전,  타입,  발생시간 • 내용(payload) • 예,  회원암호변경이벤트 • 발생주체:  "회원mad" • 버전:  1 • 타입:  "PasswordChangedEvent" • 발생시간 :  2015-­‐11-­‐27  09:59:59 • 내용:  {id:"mad",  newPwd:  "xxxx"} 58
  • 59. 이벤트 관련 구성 요소 59 이벤트 생성 주체 이벤트 디스패처 (이벤트 퍼블리셔) 이벤트 핸들러 (이벤트 구독자) 이벤트
  • 60. 이벤트 용도 1 • 트리거 • 다른기능을수행하기 위한트리거로 이벤트를 사용 • 예시 • 예매를하면SMS로통지한다. • 예매함이벤트àSMS  통지트리거 • 예매를취소하면환불한다. • 예매취소이벤트à환불트리거 60 예매 취소 이벤트 디스패처 예매취소됨 이벤트 핸들러예매 취소됨 이벤트 예매 취소됨 이벤트 환불 처리
  • 61. 이벤트 용도 2 • 데이터동기화 • 다른시스템간데이터동기화목적으로 이벤트 사용 • 예시 • 상영일정추가이벤트핸들러 à조회전용저장소에 추가데이터반영 61 상영일정 추가 이벤트 디스패처 일정추가됨 이벤트 핸들러일정 추가됨 이벤트 일정 추가됨 이벤트 일정데이터 추가 커맨드 모델 저장소 쿼리 모델 저장소
  • 62. 도메인과 이벤트 • 도메인의 상태변경을이벤트로 표현 • "~할때","~가발생하면", "만약~하면" 등의요구사항이 실 제로상태변경인지 확인 • 예시 • "영화정보를변경할때" àMovieInfoChangedEvent • "예매를취소하면" àReservationCanceledEvent 62
  • 63. (도메인) 이벤트 발생과 처리 63 public  class  Reservation  { public  void  cancel()  { …취소로직 Events.raise(new  ReservationCanceledEvent(getId(),  getPaymentNo(),  …)); } } public  class  CancelReservationService   { @Transactional public  void  cancel(ReservationId   resId)  { Events.register( (ReservationCanceledEvent  evt)  -­‐>  refundSvc.refund(evt.getPaymentNo()) ); Reservation  resv  =  findById(resId); resv.cancel(); } }
  • 64. 이벤트 적용 장점 • 서로다른도메인영역의 로직이섞이는것방지 • 불필요한 결합(coupling)  제거 64 예매! 취소 이벤트! 디스패처 예매!취소됨 이벤트! 핸들러예매!! 취소됨 이벤트 예매!! 취소됨 이벤트 환불! 처리 예매 취소에 더 이상 환불 로직 없음 예매 도메인에서 환불 도메인으로의 의존 제거
  • 65. 이벤트 적용 장점 • 이벤트핸들러 추가로기능확장 65 예매 취소 이벤트 디스패처 예매취소됨 이벤트 핸들러예매 취소됨 이벤트 예매 취소됨 이벤트 환불 처리 예매취소됨 이벤트 핸들러2 이메일 통지 예매 취소됨 이벤트
  • 66. 동기 이벤트 처리의 단점 • 트랜잭션 처리문제,성능(처리량) 문제 66 public  class  ReservationService   { @Transactional public  void  reserve(MovieId   movieId,  ShowingId  showingId,  CustomerId  custId)  { Events.register( (ReservationCreatedEvent   evt)  -­‐>  emailNotifier.notify(…) ); …//  예약도메인로직에서이벤트발생 } } 이메일 발송 중 익셉션이 발생하면? 이메일 서버가 응답 시간이 길면?
  • 67. 비동기 : 이벤트 처리 시간 • "A할 때,  B해라" 요구사항에서 A와B의간격 • 도메인전문가의 '바로'는 '즉시 실행'이 아님 • 수용가능한지연허용범위가있음 • 예시 • 예매취소시, (늦어도 30분 이내에) 환급처리함 • 결제완료후, (늦어도 다음날7시부터) 배송상태를조회 할수있어야함 • 티켓예매시, (최대10분 안에) 분단위티켓판매 통계에반 영함 • 분단위티켓판매통계가10분주기로생성되어도 대세지장없음 67
  • 68. 비동기 : 이벤트와 데이터일관성 • "A할 때,B해라" 요구사항에서 A와B의일관성 • 실제로는 한트랜잭션이 아닌경우많음 • 예시 • 이메일발송실패한다고 회원가입을못하지않음 • 고객이예매취소하면, 운영자가 수동으로환불처리가능 68
  • 69. 응용/인프라 비동기 이벤트 처리 방식 1 • 이벤트디스패처에서 메시지 큐에전송 69 이벤트 디스패처 메시지큐도메인 메시지 리스너 스토리지 도입시 고려사항 • 글로벌 트랜잭션 • 메시지큐가 비정상일 때 이벤트 재전송 방안 이벤트 핸들러
  • 70. 비동기 이벤트 처리 방식 2 • 로컬이벤트핸들러가 DB에 저장 • 포워더가 이벤트를 전달 70 응용/인프라 이벤트 디스패처 로컬 핸들러 도메인 메시지 리스너 스토리지 메시지큐포워더 단일 트랜잭션으로 처리이벤트 저장 이벤트를 주기적으로 읽어와 전달 어디까지 전달했는지 추적
  • 71. DB 저장과 포워더 구현 예 • 쇼핑몰, ERP, 택배사연동 71 쇼핑 도메인 쇼핑+이벤트 DB 포워더 주문/결제시 관련 이벤트를 한 트랜잭션으로 저장 ERP 연동모듈 택배사 연동모듈 1분 주기로 새로 전달할 이벤트를 읽어와 외부 시스템에 전달
  • 72. 비동기 이벤트 처리 방식 3 • 로컬 이벤트핸들러가 DB에 저장 • 이벤트수신측에서 이벤트를 직접가져감(pull) • 이벤트제공API 이용(RESTful  API등) 72 응용/인프라 이벤트 디스패처 로컬 핸들러 도메인 스토리지 이벤트 저장 이벤트 (REST)  API 이벤트 Fetcher 이벤트 핸들러 단일 트랜잭션으로 처리 읽어올 이벤트 범위를 지정해서 가져와 핸들러에 전달 이벤트 데이터 제공함 도메인과 같은 프로세스에서 실행해도 무방
  • 73. 비동기 이벤트의 특징 • 이벤트생성자와 핸들 러의트랜잭션 분리 • 처리량향상 • 고객에게 빠른응답 • 구조가복잡해짐 • 재발송, 재처리등고려 사항증가 73
  • 74. 이벤트 도입시 고려사항 • 이벤트도착순서 • 이벤트발송실패시 재발송 • 이벤트재처리 74
  • 75. 노력 • 사고전환 • 상태의변경==이벤트 • 순차실행à이벤트+핸들러 • 트랜잭션 일관성:비동기처리+Eventually  일관성 • 기술집착버림 • 이벤트, 비동기자체에 대한이해필요 • 메시지큐가있어보이지만, 간단한기술로도 충분히구현 가능 • 이벤트+  CQRS 75
  • 77. 내용 • DIP • AGGREGATE • CQRS • 이벤트 77
  • 78. 78 끝 최범균 |  madvirus@madvirus.net |  http://javacan.tistory.com