허니몬의 IT 이야기/프로그래머, '코드 엔지니어'


2주에 한번씩 스터디가 진행되고 있는 SLiPP.net 2기의 스터디가 잠시 무료해지는 틈을 줄이고자, eclipse4j라는 이름으로 활동하시는 현기형이 이터니티님의 강의를 제안하셨다. 다음은 손권남님!

이날은 생각보다 사람들의 참석이 저조했다. 덕분에 회사에서 참석하고 싶어하던 개발자 3명을 이끌고 참석할 수 있었다. 혹시나 스터디를 함께하는 사람들이 불편해할까봐 꽤 조심스러웠다.



시작시간 전에 일찍오신 조용호님(Eternity's Chit-Chat : http://aeternum.egloos.com 운영)은 꽤 쑥쓰러워하셨다. 처음 뵙는 날이라서 나 역시 앞자리에 앉아서 쑥쓰럽게 말을 건넸다. ^^; 제대로 인사를 드리지 못한 점은 많이 아쉽다. 발표가 끝나자마자 바람같이 사라지시더라능!!

위의 주제를 가지고 진행하셨다. 본인께서도 꽤 오래전에 작성한 문서라고 하시면서 쑥쓰러워하신다. 평소에도 쑥쓰러움이 많으실 것 같은 느낌!


발표내용 정리

목차

  1. 영화 예매 시스템 도메인
  2. 데이터-지향 설계
  3. 책임-주도 설계
  4. 아키텍처 & 프레임워크
  5. 결론

영화 예매 시스템 도메인

  • 도메인 컨셉
    • 영화
      • 할인정책 + 할인규칙
    • 상영(예매)
    • 할인정책
      • 일정액 할인
      • 일정비율 할인
        • 한개만 적용
    • 할인규칙Rule
      • 특정 조건
      • 한개 혹은 해당하는 조건 적용
    • 할인적용 예제
      • 영화(8000원) - 일정금액 할인(800원) - (조조, 10회, 월요일 오전, 목요일 오후 상영)
      • 조건을 가운데 두면 더 이해하기 쉽겠다.
    • 예매


데이터-지향 설계DDD(Data Driven Design)

  • 흔하게 사용하는 방법
  • 포커스
    • 데이터 : 무엇을 저장할 것인가
      • DB Schema 와 크게 관련된다
      • 클래스에 매핑되는 객체를 선언, Anemic Domain Model
    • 프로세스 : 어떻게 처리할 것인가?
      • 예매 처리 서비스
  • 데이터를 사용한 예매 프로세스 구현
    • Dao를 이용해서 데이터를 가져온다.
    • 가져온 데이터를 가지고서 로직적용
    • 데이터를 저장
  • 중앙집중식 제어 스타일
    • Transaction Script
      • 데이터를 불러오기 비즈니스 로직을 처리하고 저장하는 과정까지가 하나의 트랜잭션에서 처리하기 때문이다.
    • 데이터와 프로세스를 나누기 때문에 절차지향적이다.


책임-주도 설계(패러다임 쉬프트!!)

  • 객체지향적으로 짠다.
  • 객체지향에 초점은 책임, 데이터나 프로세스는 아니다.
  • 책임
    • 스스로 뭔가를 할 수 있다.
    • 이름이 뭐에요~?
      • 이름이 궁금한 사람의 지갑을 털어서 신분증을 보고 확인하는 방법
      • 궁금한 사람에게 다가가 물어보는 방법
      • 이름을 묻는 것에 대해 요청하면 거기에 대답할 책임
    • 캡슐화의 원리
      • 내가 그 사람의 모든 것을 꺼내어 보고
      • 어떻게 하는지는 몰라도 어떻게든 답을 얻는다.
    • 다형성
    • 자바의 객체는 ’책임의 관점’에서 보지 않으면 이해하기 어렵다.
  • 도메인 책임
    • 시스템이 해야하는 일
    • 예매 생성 책임
    • 가격 계산 책임
    • CRC 카드 : Canidate, Responsibility, Circulation
      • 클래스, 네임, 책임, 협력
    • 실제적인 구현은 뒤로 미룬다.
  • Rich Domain Model
    • 상속inheritance과 다형성의 활용
    • 정책에 대한 판단을 하는 책임, 규칙에 대한 판단을 하는 책임이 서로 다르다.
  • 데이터에 대한 걱정은 잠시 꺼두라!
  • 책임 기반 구현
    • 시퀀스 다이어그램으로 확인
  • 위임식delegated, 분산식dispersed 제어 스타일
  • 이런걸 Domain Model
    • 객체지향적인 설꼐를 시도
  • 모든 코드의 오류사항은 수정을 가하면서 나타난다.
  • 도메인적인 설계만으로는 잘 안된다.
    • 변경에 대한 예측을 잘 해야한다.
    • 개발자의 능력이 가장 큰 변화를 가져오는구나.
    • 요구! 분석! 능력!
  • 객체지향적인 코드는 어렵다.
    • 유연성을 요구하기 때문에…
    • 객체의 생성된 이유를 따라서 들어가야 이해할 수 있다.
    • 구조를 이해하고나면 편안해진다.
      • 패턴을 이해하고 나면 쉽다.
    • 수정시 찾아들어가기 쉬워진다.
    • 유지보수는 쉽다.
    • 요구사항 변경을 수용하기 쉬운 녀석을 만들어야한다.
    • 객체지향 프로그래밍에서 패턴이 유행하게 된 것은 이해하기 어렵기 때문이다!


아키텍처 & 프레임워크

  • 계층적 아키텍처
    • 도메인 계층이 두터워진다.
    • 도메인 레이어 캡슐화
      • 도메인에 대한 개념적인 부분들 포진
      • 기술적인 부분은 밖으로 뽑아내야 한다.
    • 관심사의 분리
    • 도메인 계층 위에 서비스 계층을 두는 것에 대한 논의가 있다.
      • 서비스 레이어
    • 도메인 레이어 의존성 관리
  • 순수한 객체POJO
    • 자바 언어책을 펼쳤을 때 나오는 자바코드
    • AOP, Annotation, DI
      • 객체의 관심도를 떨어뜨려주는 거지
      • AOP에 대해서 공부할 수 있으면 좋겠다. ^^
  • 비침투적인 프레임워크
    • POJO 개발을 위한 전제조건
    • 가벼운 프레임워크, 도메인에 대한 침투를 피한다.
      • Spring, Hibernate
  • Dependency Injection - Spring
  • Impedance Mismatch
    • 객체 모델과 DB 스키마의 불일치
    • 객체 모델과 DB 스키마 간의 변환 계층 필요
    • DB구조와 객체 구조가 닮아가는 이유
      • 이렇게 해야 그나마 편하니까!
  • Data Mapper
    • 테이블과 객체 사이의 의존성을 끊어준다.
  • ORM - Hibernate
    • 객체와 DB 구조의 일치…
  • Spring AOP & Annotation, 관심사의 분리


결론

  • Rich Domain Model
    • 설계 관점이지 기술 관점이 아님
    • 훌륭한 객체 지향 설계 지침을 따를 것
  • 기술적인 제약 사항 역시 중요
    • 비침투적인 프레임워크 사용
    • 프레임워크의 제약 사항을 파악하라
    • 프레임워크의 제약 사항에 따라 구현 가능하도록 아키텍처를 수정하라.
    • 도구에 아키텍처를 맞추어야 한다
  • Rich Domain Model을 자제해야 하는 경우
    • 비즈니스 로직이 단순하고 개발 기간이 짧은 경우
    • 비침투적인 프레임워크를 사용할 수 없는 경우
    • 비침투적인 프레임워크에 대한 경험이 부족한 경우
    • ORM을 사용할 수 없는 경우
    • 객체지향 분석/설계 경험이 부족한 경우
  • 실용적인 관점에서 접근하라!


기타

  • Patterns of enterprise Application Architecture
  • ODB(Object DB)
    • RDB를 포기하지 않음
  • Rich Domain Model 설계를 할 수 있는 절차적인 접근방법이 있을까?
    • 도메인에 대한 많은 이해
  • 아키텍처에 대한 고려
    • Case by Case


도메인Domain을 제대로 이용하기 위해서는 객체지향과 디자인 패턴에 대한 충분한 이해가 있어야 한다. 이런 충분한 이해와 경험이 없다면 도메인을 제대로 구현하지 못할 가능성이 높다.

이전 회사에서 만들었던 솔루션에서 처음으로 DDD(Domain Driven-Design)의 맛을 보았다. 개인정보보호법이라는 도메인을 가지고서 개인정보 프로세스와 법규에 대한 복잡한 로직을 구현하기 위한 선택이었다. 위에서 말했던 비침투적인 프레임워크로 Spring, Hibernate, Spring Data JPA를 활용했으며, 도메인에 비즈니스로직을 담아 사용하게 되면서 서비스 계층이 굉장히 얇아지는 것을 경험할 수 있었다. 도메인간의 연계, 협력이 필요한 경우에만 서비스를 사용하고 그렇지 않은 경우에는 대부분 컨트롤러 계층에서 도메인을 불러와 도메인을 통해 비즈니스 로직을 처리하고 그것을 저장하는 형태로 구현이 되었다. 이 때문에 컨트롤러 계층의 코드가 복잡해지는 단점을 경험하기도 했다.

하지만, 기획자와 도메인에 대한 공유를 바탕으로 도메인에 대한 비즈니스 로직 설계와 기능들을 구현할 수 있었던 것은 좋은 경험이었다고 생각한다.

존재하지 않던 개념들을 도메인으로 추상화 하고 이 도메인을 가지고서 기획자와 협의하고 도메인을 변경하는 작업은 비교적 용이했다. 그러나 도메인에 대한 충분한 이해가 있지 않고 도메인의 크기가 거대해지면 개발자가 그 도메인을 컨트롤하기가 쉽지 않다. 이런 경우에는 도메인을 분리시켜야 하는데, 그걸 개발자가 혼자 진행하기는 버거운 작업일 것이다.