본문 바로가기
공부 기록

[리팩토링 1판] Chapter 12. 복합 리팩토링

by 매트(Mat) 2024. 4. 11.

Chapter 12. 복합 리팩토링

리팩토링은 개발 작업을 지연시키려고 하는 게 아니라 어떤 목적이 있어서 하는 것이다.

시스템이 제품화 단계에 들어간 상태에서 기능을 추가해야 할 때, 2개월간 코드를 정리해야 해서 작업을 중단해야 한다고 팀장을 설득하기란 무리다.

따라서 리팩토링은 주변 정리부터 매일 조금씩 해나가야 한다.

  • 리팩토링은 기능을 추가할 때나 버그를 수정할 때 실시하자.
  • 리팩포링은 시작했을 때 끝을 봐야하는건 아니다.
  • 실제 작업을 수행하는데 필요한 만큼 하자. 필요하다면 나중에 언제든지 되돌릴 수 있다.
  • 복잡 리팩토링은 단순 리팩토링 기법과 달리 개발팀 전원의 합의 하에 실시해야 한다.
  • 팀 전원은 복합 리팩토링 중 하나가 현재 진행 중임을 알고 그에 따라 움직여야 한다.
    • 이는 사공이 많아 배가 산으로 가면 안되기 때문이다.

이제 복합 리팩토링에는 어떤 것들이 있는지 하나씩 알아보자.

상속 구조 정리

하나의 상속 계층이 두 작업을 동시에 수행할 땐

  • 상속 계층을 하나 더 만들어서 위임을 통해 다른 계층을 호출하자.

chapter-12-1

  • 상속 계층이 엉키면 코드 중복이 생겨서 문제다.
  • 또한 코드를 수정하기도 더 어려워진다.
  • 코드를 알아보기도 힘들어진다.
  • 하지만 두 기능을 수행하는 하나의 상속 계층은 쉽게 찾을 수 있다.
  • 계층구조의 특정 계층에 있는 모든 클래스의 하위클래스들이 이름 앞에 같은 형용사가 붙어 있다면 한 계층으로 두 기능을 수행하는 것이다.

리팩토링 후

chapter-12-2

  • 어느 기능이 더 중요한지 결정하자.
  • 물건 거래가 표현 스타일보다 훨씬 중요하므로 Deal만 남겨두고 표현 스타일을 별도의 상속 계층으로 빼내자.
  • 두 기능을 분리함으로써 더 단순화할 수 있었다.

절차 코드를 객체로 전환

코드가 절차식으로 작성되어 있을 땐

  • 데이터 레코드를 객체로 바꾸고, 기능을 쪼개서 각각의 객체로 옮기자.

  • 절차식 코드를 비교적 객체지향적으로 만들어야 할 때가 많다.
  • 보통은 클래스에 몇 가지 데이터, 읽기/쓰기 메서드만으로 구성된 덤 데이터 객체, 절차식 메서드가 들어있다.
  • 모든 절차 코드를 하나의 클래스에 넣자.

도메인 로직을 표현과 분리

도메인 로직 들어 있는 GUI 클래스가 있을 땐

  • 도메인 로직을 별도의 도메인 클래스로 떼어내자.

MVC 패턴의 핵심은 사용자 인터페이스 코드(뷰, 표현)와 도메인 로직(모델)을 분리하는 것이다. 표현 클래스에는 사용자 인터페이스 처리에 필요한 로직만 들어간다.

도메인 객체에는 표현이나 시각적 코드는 전혀 들어가지 않고 비즈니스 로직만 들어간다. 하나의 비즈니스 로직에 여러 개의 표현을 구현할 수도 있다.

알다시피 이렇게 분리해놓으면 기능을 더욱 단순화할 수 있고, 유지보수에도 좋기 때문이다.

스프링 프레임워크를 사용하면 이러한 패턴의 분리 로직은 본능적으로 아니 당연하게 작성하게 된다. 그렇게 작성하도록 도와주는 프레임워크니까!

계층구조 추출

한 클래스에 기능이 너무 많고 일부분에라도 조건문이 많을 땐

  • 각 조건에 해당하는 하위클래스를 작성해서 계층구조를 만들자.

chapter-12-3

처음엔 한 클래스에 하나의 기능만 구현하자고 생각하지만 나중엔 기능을 10가지나 넣어버렸음을 깨달을 때가 있다.

이렇게 1년이 지나면 플래그와 조건문이 여기저기 도배되어 그 클래스는 뒤죽박죽된다.

따라서 더 늦기전에 클래스 추출을 통해 각 기능을 분리해야 한다.

느낀 점

복합 리팩토링에 대해서도 알아보았다. 리팩토링은 따로 시간내서 하는 것이 아니다. 나의 업무 시간에 틈틈이 수행하면 된다. 리팩토링은 프로젝트가 아니다. 기능을 개발하면서, 수정하면서, 버그를 만나면서 고쳐가면 된다. (단, 테스트는 필수!)

리팩토링 기법들을 보면서 중요한 공통점이 있다. 바로 기능을 분리하는 것이다.

  • 상속 구조 정리 역시 클래스를 분리한다.
  • 절차 코드를 객체로 전환 역시 객체를 만들어서 분리시킨다.
  • 우리가 스프링 MVC로 개발하듯이 도메인 로직을 표현과 분리 역시 기능을 분리시켜서 더 편하게, 단순하게 개발할 수 있었다.
  • 계층구조 역시 마찬가지다.

이처럼 복잡한 기능을 한 곳에 집중시키지 말고, 분산시키면 더욱 보기가 깔끔해지고, 유지보수하는데 큰 어려움이 없을 것이다.

References

댓글