2018/10/15 사내세미나로 조영호님이 '애플리케이션 아키텍처와 객체지향’이라는 주제로 다음과 같은 주제로 발표하셨다.
-
제목: 애플리케이션 아키텍처와 객체지향
-
발표자: 조영호
-
참고자료: 객체지향적인 도메인 레이어 구축하기
-
설명예제: 영화 예매 시스템 만들기
Note
|
|
-
시스템을 만들기 위해 도메인 분석
Important
|
발표를 위해 잘 맞춰진 데이터모델과 도메인모델을 사용했다. 현실은 그렇게 호락호락하지 않아! |
-
영화(Movie)
-
제목
-
상영시간
-
-
상영(Showing): 영화가 재생되는 시간
-
영화
-
상영일시
-
회차
-
상영관
-
-
할인정핵(DiscountStrategy)
-
금액 할인(AmountDiscountStrategy): ex) 8,000 - 800 = 7,200
-
비율 할인(PercentDiscountStrategy) ex) 8,000 - (8,000 * 0.1) = 7,200
-
-
할인규칙(Rule)
-
회차규칙(SequenceRule): 1회차(조조), 10회차
-
시간규칙(TimeRule): 시간대
-
-
예매(Reservation)
-
상영
-
인원
-
-
데이터와 프로세스를 서로 다른 모듈에 구분짓는다.
-
기능분할을 우선한다.
-
프로세스를 분리하고 필요한 도메인을 도출한다.
-
실무에서 사용하는 경우에는 운영데이터를 기준으로 한다.
-
업무에 필요한 데이터 모델을 만드는 것을 우선한다. → 나쁜점: 이렇게 만들어진 데이터 모델이 설계를 주도한다.
-
데이터 모델 1:1 대응 객체를 작성
-
클래스를 데이터에 등록
-
1 domain - 1 DAO
-
-
-
예매처리 알고리즘
@Transactional public Reservation reserveShowing(int customerId, int showingId, int audienceCount) { // 1. 데이터베이스로부터 Movie, Showing, Rule 조회 // 2. Showing 에 적용할 수 있는 Rule 판단 // 3. if(Rule 존재) { // Discount를 읽어 할인금액 계산 // } else { // 영화상영금액 계산 // } // // 4. Reservation 생성 후 데이터베이스 저장 }
시퀀스 다이어그램을 그려보면 중앙집중식 제어(관련된 모델에 대한 제어가 한 곳에서 처리) 스타일이 나타나게된다.
-
절차지향과 차이점
-
프로세스와 데이터를 하나의 객체(도메인) 안에 넣는다.
-
객체는 행위와 데이터의 조합
-
-
책임과 협력을 표현하기 위한 객체지향 설계 도구
-
Candidate(Role or Object): 후보
-
Responsibility: 후보가 수행할 역할
-
Collaborator: 후보와 협력할 객체
Important
|
기능에 대한 고민이 우선한다. |
-
어떤 기능을 개발해야하는지에 대해서는 정보 전문가에게 책임 할동
-
Reservation ← Movie
-
-
영화상영 정보를 알고 있는 전문가에게 할당(Creator)
-
영화가격 정보를 알고 있는 전문가에게 할당(Information Expert)
-
영화가격정보를 가장 잘 알고 있는 것은 영화다.
-
-
할인율을 적용할 책임을 가진 객체 추가
-
할인정책을 판단하는 책임을 가진 Specification 객체 추가
-
책임을 할당할 때는 결합도와 응집도를 따져야 한다. tradeOff 비용
public class Showing {
public Reservation reserve(Custom custom, int audienceCount) {}
pubic Money calculate() {
return movie.calculateFee(this).time(audienceCount);
}
}
public Reservation {
}
public abstract class DiscountStrategy {
public Money calculateDiscountFee(Showing showing) {
return Money.ZERO;
}
}
public interface Rule {
}
-
도메인 모델을 사용할 때
-
객체를 기반으로 작성한 경우
Note도메인 모델이 애플리케이션 아키텍처에 영향을 받아 뒤틀릴 수밖에 없다.
-
-
트랜잭션과 DB 영향을 받음
-
트랜잭션을 잡기 위해 서비스 레이어를 구분짓는다.
-
애플리케이션 경계
-
애플리케이션 경계 조합
-
서비스 레이어
@Transactional public ReservationService { public Reservation reserveShowing(int customerId, int showingId, int audienceCount) { Customer customer = customerRepository.findById(customerId); Showing showing = showingRepository.findById(showingId); Reservation reservation = showing.reserve(customer, audienceCount); return reservationRepository.save(reservation); } }
-
트랜잭션 스크립트를 사용할 떄
-
비즈니스 로직이 서비스에 녹아있음
-
별도의 서비스 레이어 불필요
-
-
도메인 모델 단점
-
도메인 모델을 사용할 때 DB매핑하는 것은 쉽지 않음
-
DB모델을 만드는 기준(중복제거)와 도메인모델을 만드는 기준이 서로 다름
-
우리가 짜는 프로그램은 두 가지 요구사항을 만족시켜야 한다. 우리는 오늘 완성해야 하는 기능을 구현하는 코드를 짜야하는 동시에 내일 쉽게 변경할 수 있는 코드를 짜야 한다.
어떤 변경이 발생할 지 알아야 잘 설계됐는지 여부를 알 수 있다.
Note
|
객체지향의 장점은 명사를 사용하여 개념을 유추할 수 있다는 것이다. |
-
OCP(Open-Closed principal): 확장에는 열려있고 변경에는 닫혀있는 정책
-
여러 영화할인규칙을 가지는 할인정보를 만든다.
-
요구사항이 어떻게 변경될지 모른다면…
-
코드를 간단하게 작성하고 변경에 대한 대응하도록 작성하기
-
변경이 발생할 때마다 리팩토링하여 변경하기 쉬운 코드
-
행위에 집중되어 있기에 빈번한 변경이 발생할 수 있다.
-
객체지향설계인 경우 변경에 대해서 코드를 변경하지 않고 확장가능한 코드를 작성할 수 있다.
-
도메인 모델은 복잡성을 알고리즘에서 분리하고 객체 간의 관계로 만들 수 있다.
유효성 검사, 계산, 파생 등이 포함된 복잡하고 끊임없이 변하는 비즈니스 규칙을 구현해야 한다면 객체모델을 사용해 규칙을 처리하는 것이 현명하다.
'Programming' 카테고리의 다른 글
201603 구매예정 도서 (0) | 2016.03.22 |
---|---|
켄트 백의 구현패턴 (0) | 2016.01.29 |
[잠들기 전 한구절] 4장, 도메인의 격리 (0) | 2016.01.27 |
[잠들기전 한구절] 3장, 모델과 구현의 연계 (0) | 2016.01.26 |
올해 목표 중 하나, DDD 개념을 체득하는 것 (0) | 2016.01.21 |