레거시 리팩터링

많은 기업들이 ‘서비스를 안정적으로 운영하면서 레거시 코드를 리팩터링 할 수 있는 역량을 갖춘 개발자’를 요구한다.
이번 미션에서는 리팩터링과 관련한 많은 프로세스와 내용들을 학습했다.

개인적으로는 이번 미션에 임하면서 실제 임의의 회사에 새로 이직을 했다는 생각으로,
레거시 코드를 바라보고 ‘어디서부터 어떻게 리팩터링 할 것 인가?’라는 생각을 가지고 임하게 되었다.

많은 레거시 프로젝트들은 데이터 종속적인 애플리케이션 개발에 초점이 맞춰져 있다.

데이터 종속적인 애플리케이션은 DB의 스키마가 설계되면 모든 애플리케이션의 VO가 동시에 정해지며,
사실상 백엔드 서버에서는 DAO 나 Service layer에 비즈니스 로직을 집중시키게 된다.

따라서 빈약한 도메인 모델(Anemic Domain Model)을 가지게 되므로,
이에 대비하여 서비스 레이어는 거대해지기 마련이다.
거대한 서비스 레이어(Big Service Layer) 형태는 객체지향 설계 원칙에 맞지 않을 뿐더러,
객체의 행동(Behavior)를 담당하는 도메인 로직을 여러 곳에 산재하게 만든다.
또한, 코드의 중복과 오브젝트의 재활용성을 현저히 떨어뜨리는 원인이 된다.

위의 문제는 다음과 같이 정리할 수 있다.

  1. 데이터 중심 설계(DB 스키마만 설계한다)
  2. 도메인 모델이 빈약해진다.
  3. 모든 도메인 로직 (or 비즈니스 로직)이 서비스 레이어에 집중된다.

이런 불일치에 대한 해결책으로 DDD(Domain Driven Design)을 사용할 수 있다.

도메인 주도 설계(Domain Driven Design)

  • Eric Evans의 동명의 책에서 유래
  • 도메인 모델의 적용 범위를 구현까지 확장하여 도메인 지식을 구현 코드에 반영
  • 공통의 언어(유비쿼터스 언어)를 사용하여 도메인과 구현을 충분히 만족하는 모델을 만든다.
  • 실제 코드로 구현 가능한 현실성 있는 도메인 모델 분석과 그것을 추상화하는 설계
  • “설계를 하라, 그 다음에 구축하라” 가 아니다
  • 다양한 원칙과 패턴
  • 도메인, 도메인 모델, 유비쿼터스 언어
  • UML, Bounded Context ; Context Map

회고

이번 미션에서 잘 한 점

도메인 주도 설계 이해

도메인 주도 설계에 대한 설명을 듣고 맨처음 생각이 난 단어는 바로 ‘객체지향’ 이었다.
왜냐하면, ‘DDD가 성공할 수 있는 전제조건, DDD 도입이 어려운 이유’를 듣고 보니,
내가 이제까지 했던 SI or 레거시 프로젝트 들이 모두 그 이유에 부합했기 때문이었다.

내가 경험했던 대부분의 프로젝트에선 객체지향을 도입해 보려고 하면
이론과 실제의 괴리가 있었고 결국 데이터 중심 설계로 진행하게 되었다.

SI or 레거시 프로젝트에서 ‘객체지향’을 도입하기 어려웠던 이유

  • 대부분의 화면은 표(Table 혹은 Grid)이니까 DB 설계만 화면마다 잘 하면 된다.
  • 그러니까 테이블 설계 잘하고, 클래스는 테이블이랑 똑같이 만들면 된다.
  • 고객은 어떤 클래스로 설계했는지가 중요한게 아니라, 화면에 올바른 데이터가 나오는 지 중요하다.

DDD가 성공할 수 있는 전제 조건

  • DDD는 개발자만을 위한 것이 아니다.
  • 이해관계자(stakeholder)의 스폰서십이 적극적으로 필요하다

DDD 도입이 어려운 이유

  • 사일로 내부에서만 전문가인 도메인 전문가
  • 도메인에 거의 또는 전혀 관심이 없는 동료 개발자
  • 모든 사람이 동일한 개념에 대해 다른 용어를 사용하거나, 다른 개념에 대해 동일한 용어를 사용한다.

DDD 는 객체지향을 제대로 하기 위한 개발 방법론이나, 개발 문화에 가깝다고 이해했다.
이렇게 이해하고 나니, 아래와 같은 기술적인 설계나 구현방법

  • 엔티티와 밸류
  • Aggregate
  • 도메인 서비스에 대한 이해
  • 비즈니스 로직이 도메인에 있어야 하는 이유
    등등 많은 부분들을 이해할 수 있었다.

어려웠던 점

의존성 측면에서 객체지향의 제대로 된 이해

조영호님 - 우아한객체지향(우아한테크세미나)

위 링크에선 ‘객체지향의 사실과 오해’, ‘오브텍트’ 의 저자로도 유명하신
우아한형제들의 조영호 개발실장님께서 의존성 차원에서의 설계의 중요성과 방법에 대해 세미나 한 영상이 있다.

이번 미션은 4단계로 진행되었다.

  1. 테스트를 통한 코드 보호(TDD / ATDD를 통해 레거시 코드 보호)
  2. 서비스 리팩터링(비즈니스 로직을 도메인 모델로)
  3. 의존성 리팩터링
  4. 멀티 모듈 적용

의존성 리팩터링 미션을 진행하기 전 위 영상을 시청 하는 것을 권장했다.
영상을 다 보고 나니, 왜 의존성 리팩터링 전에 해당 영상을 보라고 권장했는 지 알게 되었다.

좋은 설계는 의존성을 최대한 낮추고, 의존성 사이클을 없애는 것이다.
맨처음 객체지향을 배우면, 응집도가 높고 의존성을 낮추라는 말을 한번즈음 들어봤을 것이다.

위 영상에서는 왜 의존성을 낮추는 것이 좋은 설계인지 직접적인 예시와 코드로 보여주고 있다.

또 하나 충격이었던 것은 ‘때로는 절차지향이 객체지향보다 좋다’ 라는 말을 하셨는데,
객체지향의 대명사급인 조영호님이 이런 말을 한다는 것이 뭔가 자기부정같은 느낌이라 영 불편했다.
하지만, 해당 부분을 5번 정도 돌려봤는데, 어떤 차원에서 하는 말인지 이해하게 되었다.

‘때로는 절차지향이 객체지향보다 좋다’ 라는 말에 대해 내가 이해한 바는 다음과 같다.

  1. 객체지향은 여러 객체를 오가며 로직을 파악해야 한다.
  2. 따라서, Validation 같은 핵심 비즈니스와는 조금 연관성이 낮은 로직은 별도 ‘Util’로 구현한다.
  3. 이 과정에서 Util은 절차지향적인 모습을 보이게 된다.

따라서, ‘때로는 절차지향이 객체지향보다 좋다’라는 말은
‘절차지향 vs 객체지향’ 을 다루는 말이 아니다.

객체지향을 좀 더 객체지향 답게 다루는 법에 관한 이야기었다.

이 부분을 이해하는 데 있어, 객체지향을 제대로 적용해 본 경험이 부족했기 때문에
강의자료와 해당 영상을 여러번 살펴보았다.
또한 세미나 참고 코드의 링크를 찾아서 실제 의존성을 많이 제거한 코드를 분석해보기도 했다.

느낀점

우테캠Pro 오리엔테이션 시간에 레거시 리팩터링 미션이 전체 미션을 통틀어 가장 어렵다고 으름장을 내놓으셨던 터라,
많이 긴장하고 이번 미션을 임하게 되었다.

항상 미션을 진행하기 전에 일정을 짜놓고 구현을 시작했는데,
이번 미션에서는 그 일정을 매번 Over 하게 되었다…

이번 미션에서는 아래와 같은 목표가 설정되어 있었다.

  • 서비스를 안정적으로 운영하면서 레거시 코드를 리팩터링 할 수 있는 역량을 키운다
  • 프로젝트를 완료한 후 일정 기간 유지보수를 함으로써 레거시 코드를 리팩터링 하는 경험

우선 두 가지 목표를 인식하고 잘 수행 한 것 같다.

많은 기업들이 최근 MSA, 도메인 주도 설계 등을 키워드로 지원 공고를 올리고 있다.
이번 미션에서는 MSA, 도메인 주도 설계‘왜 탄생하게 되었는가?’ 잘 알 수 있는 기회였다.

어려웠던 미션인 것 만큼 많은 것을 새로 알게되는 좋은 경험이었다.

이번 미션회고 에서는 DDD 에 대해 간략하게만 정리해봤지만, 깊게 파고들 필요가 있다고 생각했다.
따라서 Eric Evans - 도메인 주도 설계 책을 읽어보고 이에 대해 별도의 포스트로 정리해 볼 계획이다.