본문 바로가기

BackEnd

[KSUG Seminar] Growing Application - 2nd. 애플리케이션 아키텍처와 객체지향

반응형

[KSUG Seminar] Growing Application - 2nd. 애플리케이션 아키텍처와 객체지향 - YouTube

애플리케이션 아키텍처와 객체지향 (slideshare.net)

 

애플리케이션 아키텍처와 객체지향

애플리케이션 아키텍처와 객체지향 Eternity’s Chit-Chat http://aeternum.egloos.com/ Object-Orientated

www.slideshare.net

객체지향 분석/설계는 일반적으로 도메인 레이어 안에 위치하는 객체들의 협력 관계를 구현하는데 초점을 맞추며

이처럼 도메인 레이어를 객체지향적으로 구현하는 아키텍처 패턴을 도메인 모델 패턴이라고 부릅니다.

이와 달리 도메인 레이어를 절차적인 방식으로 구현하는 아키텍처 패턴을 트랜잭션 스크립트 패턴이라고 부릅니다.

본 발표에서는 간단한 요구사항을 트랜잭션 스크립트 패턴과 도메인 모델 패턴 두 가지 방식으로 구현해보고

객체지향적인 애플리케이션이 어떤 형태를 취하는지 살펴보도록 하겠습니다.

 

TLDR 

도메인 레이어를 객체지향적으로 구현하는 것이 도메인 모델 패턴이다.

트랜잭션 스크립트 패턴은  트랜잭션 관리 + 애플리케이션 로직(오케스트레이션) + 도메인 로직을 포함한 도메인 레이어 구현 방식이다.

도메인 레이어를 객체지향적으로 구현하면 도메인 개념(도메인 구성 요소) 모델과 클래스 다이어그램이 유사해진다.

도메인 모델 패턴으로 도메인 레이어를 구현하면 의존성이 줄어들어 유지보수가 쉬워지고, 개념 이해가 쉬워진다.

Part -1 아키텍처

프로젝트에 참여하는 개발자들이 설계에 대해 공유하는 이해를 반영하는 주관적인 개념

중요한것

변경하기 어려운 것

일찍 올바르게 결정하고 싶은 것

아키텍처란
관심사의 분리란 : 서로 다르고 관련이 없는 책임들을 분리
유사한 애들을 한 레이어에 모아두고, 그 레이어만 교채하면 다른 시스템에서 사용 가능. 유연해지고 재사용성이 높아짐

데이터 소스는 네트워킹 포함. 데이터 조작을 위한 계층

가장 중요한 레이어는 도메인. 경쟁력은 도메인의 시스템 반영
주로 절차지향적으로 짜게 됨. 다양한 이유가 있음

도메인 레이어의 구현 방법

  • 트랜잭션 스크립트 패턴 : 절차 지향
  • 도메인 모델 패턴 : 객체지향
  • 테이블 모듈 패턴 : 닷넷에서 많이 쓰고 자바에서 안씀

Part -2 영화 예매 도메인

영화를 예매한다는 시스템을 만든다 하면

시스템 구성 기능, 도메인 구성 요소들이 있을 것임

이것들이 도메인 개념

개념 : 영화
상영 : 예매 대상. 영화는 메타데이터임
할인 정책 : 고정금액 할인, 비율금액 할인
할인 규칙 : 언제 할인을 해줄 것인가
할인이라는 개념은 할인 정책과 규칙의 협력에 의해 적용된다.
조건 중 하나만 만족해도 할인해줌
조건 적용 예시

최종 생성 결과는 예매

상영.예매의 결과는 예매
도메인 개념 요약

중간 정리

관심사의 분리 > 레이어드 아키텍처

도메인 레이어의 설계방법 -> 트랜잭션 스크립트 패턴(절차지향) or 도메인 모델 패턴(객체지향)
도메인 개념 : 도메인 구성 요소

Part -3 트랜잭션 스크립트 패턴

트랜잭션 스크립트 패턴은 데이터와 절차를 분리해서 사고

트랜잭션 스크립트 : 데이터 모델

개념적 데이터 모델을 구현한다.
getter, setter만 있는, 로직 없는 anemic domain model 구현. 마치 구조체
각 테이블마다 DAO 객체 생성해서 매핑

트랜잭션 스크립트 : 프로세스(로직)

실무에선 보통 ReservationScript가 아니라, ReservationService로 구현
로직들을 절차적으로 구현

이제 코드로 대체해보자.

DAO통해 DB 접근해서 데이터 가져옴
시간룰인지 순서룰인지 판단
널체크로 룰의 여부 판단.

판단은 전부 if then else

모든 판단이 ReservationScript(Service)에 모여 있음

그림으로 보기엔 깔끔하지만, 코드 까보면 지옥임

Part4 - 도메인 모델

객체 지향 도메인 모델 패턴 : 프로세스와 데이터를 하나로 묶어서 생각

기능과 데이터의 캡슐화
객체지향 개념 책들은 도메인 레이어 설계를 주로 주제로 한다!

도메인 레이어를 도메인 모델 패턴으로 객체지향적으로 설계!

역할, 책임, 협력
객체들은 데이터(속성)와 프로세스(메세지)를 같이 갖고 있는 덩어리. 각 덩어리는 메세지를 통해 협력함

객체를 설계하는 좋은 도구 CRC 카드

가장 많이 알고 있는 애를 찾아라!

책임 할당의 1원칙 : 가장 많이 알고 있는 애에게 넘겨라. (creator pattern)

후보 책임 협력 카드
책임은 정보 전문가에게 할당! 상태를 조작하는, 가장 상태와 밀접하게 동작(조작)하는 행동이 같이 그 객체에 배치해야 함
영화는 메타정보다. 가격을 알고 있다.
할인울을 알고 있는 Discount Strategy에게 책임을 맞겨라
명세 객체 추가
책임을 위임. 자기 자신을 넘기는 걸 지켜보자.
할인 규칙 - 할인 여부를 판단한다.
할인 정책 - 할인 규칙을 이용하여 할인 금액을 계산한다.
클래스 다이어그램
도메인 개념과 클래스 다이어그램이 유사하다!
책임이 분산된 모습을 볼 수 있다.
도메인 레이어를 객체지향적으로 구현하는 것이 도메인 모델 패턴이다.

Part-5 도메인 레이어와 아키텍처

도메인 레이어를 어떻게 짜느냐에 따라 아키텍처가 달라짐
순수한 도메인 로직들. 이 객체들 만으로 시스템을 짤 수는 없음, 오케스트레이팅이 필요함 (crud, push, flow 등)

애플리케이션 로직(플로우)는 순수한 객체 안에 넣지 않음. 디펜던시가 높아짐. 결합도가 높아지고 응집도가 낮아짐.

도메인 레이어는 다른 레이어에 절대 의존하지 않도록 해야 함
도메인 모델 패턴으로 도메인 레이어를 구현하면 서비스 레이어가 하나 들어온다.

도메인 레이어는 건드리지 않고, 도메인 레이어의 모델, 도메인 서비스를 가져와 애플리케이션 서비스 구현

도메인과 무관한 기술적인 내용. 도메인 로직은 냅두고 도메인을 이용해 애플리케이션 로직을 구현하여, 도메인 레이어는 내버려둠
서비스 레이어는 트랜잭션 단위(uow)가 된다.

가상 이상적인 서비스 레이어의 모습

DB에서 필요한걸 읽고, 도메인 로직을 도메인 레이어에 위임. DB에 데이터 영속

트랜잭션 스크립트의 문제점

3가지 로직이 섞여있어 어디에서 어느 코드를 수정해야 할지 찾아가기 힘듬
트랜잭션 스크립트의 위치는 사실 서비스 레이어가 아니라 도메인 레이어임.

트랜잭션 스크립트 패턴 =  트랜잭션 관리 + 애플리케이션 로직(오케스트레이션) + 도메인 로직을 포함한 도메인 레이어 구현 방식

아직까지는 주로 RDB를 많이 씀
도메인 모델 패턴으로 도메인 레이어를 구현하면 DB스키마에 매핑하기 어려움

객체 관계 임피던스 불일치

  • 애플리케이션의 관심사는 행위(기능)의 확장성(유연성, 수정용이성)
    • 행위 관점
  • 데이터베이스의 관심사는 중복제거(정규화)
    • 데이터 관점

임피던스 미스매치
도메인 객체와 DB 간 결합도를 매퍼 통해 끊음.
ORM 구현이 어려워 JPA를 씀

단순히 CRUD 대체를 위해 쓰는게 아님.

객체와 데이터 모델의 간격이 너무 크기 때문에, 둘을 연결하기 위해 사용.

트랜잭션 스크립트를 쓰면 데이터와 로직이 나뉘어짐. 자바 빈 규약(데이터 객체)에 따르면 순수 데이터 객체는 필드를 public으로 노출해도 됨

객체지향이냐 아니냐는 상태를 어디서 조작하느냐임. 객체지향은 데이터를 알고있는 객체가 자신의 데이터를 이용해 결과를 돌려준다.

테이블 데이터 게이트웨이
J2EE 에서는 DAO라고 함
지금까지 내용 정리

그래서 무엇을 쓸 것인가 - 변화의 관점에서

이전의 요구사항
요구사항이 바뀌었다 생각해보자
할인 정책이 2개 동시 적용 가능하다.

기존의 트랜잭션 스크립트

원래 할인 정책은 하나였는데...
정책이 여러개가 되어 코드가 변경되었다.
가장 무서운 일. 큰 메소드는 테스트하기도 어렵다.
도메인 모델에 드러나지 않는 개념. 중복 할인
단지 n개의 할인이라는 개념. 절차에 숨어있음
얘네를 묶어 하나의 단위로 - 컴포지트 디자인 패턴
새로운 요구사항 추가를 위해 기존 코드는 변경되지 않았음. 새로운 서브클래스 하나만 추가. 명시적 개념
\
이것이 바로 개방 폐쇄 원칙
추상클래스,인터페이스 / 구체클래스가 나뉨

의존성 역전의 법칙

의존성 역전의 법칙. 사용하는 쪽은 하위모듈에 대한 의존성이 전혀 없음. 상에서 하로, 디펜던시의 방향이 추상화!

사용하는 쪽이 상위모듈. 상위모듈은 하위모듈(사용대상)에 대해 의존성 없음

개념을 명사로 바운더리 잡고(명시적으로), 그 다음 동사를 위치시킴
추상화를 통해 중요한 것만 남길 수 있음
도메인 추상화를 통해 도메인 레이어 아키텍처를 도출할 수 있음
다형성!

거짓말 : 초기에 요구사항이 어떻게 변할 지 알줄 아는 사람은 없다.

최대한 단순하게 짜자
객체지향 패러다임을 통해 변화를 수용할수 있는 설계를 만들자

 

Q & A 

레거시 협업에서 트랜잭션 스크립트 패턴 => 도메인 모델 패턴 가능한가?

도메인 모델은 페어 프로그래밍이나 코드리뷰가 활성화되어야함.

커뮤니케이션이 안되면 어려움.

그 사람이 짠걸 리팩토링 하는 식으로 코드를 보여주는 방법밖엔 없을 듯.

객체지향은 처음에 다른사람이 짠걸 이해하는게 어려움.

익히면 훨씬 쉬워짐.

 

절차적 구현이 좋은 경우?

알고리즘

전략 패턴

 

도메인 모델이 커지게 되면?

커다란 클래스 하나보다

작은 클래스 여러개가 좋음

도메인 로직이 복잡할수록 클래스 수를 늘리고 클래스를 슬림하게 유지해라

작은메소드, 작은클래스

작은 것들의 유사성을 찾기가 쉬움. 

추상화 도출하여 클래스를 줄일 수 있음.

 

설계가 좋지 않으면 새로 개발하는게 낫나요?

요구사항 변경이 거의 없는 시스템은 새로 만드는게 나을 수 있음.

요구사항이 너무 많으면 어려울 듯.

점진적 리팩토링.

 

 

반응형