중복을 왜 해결할까?
들어가며
어플리케이션을 개발하다 보면 꽤 자주 중복된 코드를 작성하게 되고 이미 작성된 로직에서 중복된 코드를 보는 것도 어려운 일이 아니다.
중복된 코드를 보면 클래스를 새로 정의해서 중복된 코드를 모아 새로 정의한 클래스를 사용하도록 하여 중복 로직을 해결하거나 여러 가지 디자인 패턴들을 사용하여 중복된 코드를 한곳으로 모은다.
“중복 해결” 만 놓고 보았을 때에 장점만 있고 항상 옳다고 보여지지만 중복을 해결하는 과정에서 기존의 코드가 가지던 직관성 , 가독성 , 단순성이 떨어지는 경우도 왕왕 보았다.
중복을 해결하는 이유
그렇다면 중복을 왜 해결해야할까?
A,B,C 모듈에서 중복된 로직을 가지고 있다고 가정해보자.
어느날 도메인 규칙이 변경되어 A,B,C 가 가지고 있던 중복된 로직이 변경 되어야하면 모두 찾아가서 동일하게 변경해줘야한다. 만약 A,B 에서는 변경했는데 C 에서는 변경되지 않았다면 장애로 이어질 수 있다. 같이 변경되어야하는데 로직이 흩어져있는 경우 모두 찾아서 변경해줘야하므로 코드 및 시스템 관리에 어려움이 있다.
만약 중복을 해결했었다면 도메인 규칙이 변경되었을 때 A 모듈만 변경하면 되었을 것이다.
이처럼 중복을 해결하는 이유는 변경되었을 때 같이 변경되어야하기 때문이다.
A , B , C 모듈과 의존하고 있는 모듈들이 함께 변경되어야 한다면 A,B,C 에 있던 로직은 응집되어야했음을 의미한다.
만약 도메인 규칙이 변경됨에 따라 C 모듈에 의존하고 있는 C1, C2 모듈은 변경될 필요 없었다면 C 모듈은 A , B 모듈과 응집될 필요가 없으므로 중복을 해결하지 않아도 된다.
이런 경우라면 A,B 는 응집이 필요했던 중복이고 , C 는 A,B 와 우연한 중복이었던 것이다.
예를 들어 발급 방식이 다운로드인 쿠폰 발급과 코드 입력인 쿠폰 발급 기능이 있다고 했을 때
코드 입력과 관련된 도메인 규칙이 변경되면 같이 변경되는 모듈은 B 모듈이고 다운로드와 관련된 도메인 규칙이 변경되면 같이 변경되는 모듈은 A 모듈이다.
하지만 쿠폰 발급이라는 도메인 규칙에 변경이 필요하다면 변경되어야하는 모듈은 A, B 모두이므로
쿠폰 발급과 관련된 로직은 응집이 필요하다고 볼 수 있다. 즉, 다운 로드 쿠폰 발급 , 코드 입력 쿠폰 발급에서 쿠폰 발급 로직이 중복되어있었다고 보는 것이다.
중복 해결이 필요 없는 경우
쿠폰 발급과 쿠폰 사용 기능이 있다고 해보자.
각각 쿠폰 발급 상태 검사 , 쿠폰 사용 상태 검사 로직이 존재한다. 이때 쿠폰을 발급 받기 위해서 쿠폰의 상태가 ACTIVE 해야한다는 정책과 사용하기 위해서 쿠폰의 상태가 ACTIVE 해야한다는 정책이 있다고 해보자.
그러면 쿠폰 발급 검증 로직 쿠폰 사용 검증 로직에서 쿠폰 상태 검증하는 로직이 중복되므로 다음과 같이 중복을 해결할 수 있다.
그런데 어느날 쿠폰 발급 시에 쿠폰 상태가 STOP 이어도 발급할 수 있다는 정책으로 변경된다고 하면 쿠폰의 사용 정책도 같이 변경된다. 쿠폰의 사용 정책은 변경되지 않아야하므로 쿠폰 상태 검사를 다시 분리해야한다.
이런 일이 발생한 이유는 변경의 이유/주기가 다른데 로직이 동일하다는 이유만으로 중복을 해결했기 때문이다.
변경의 이유가 다른데 로직이 동일했다면 우연한 중복이었을 뿐이다. 비단 로직이 완전히 같더라도 쿠폰 발급과 쿠폰 사용 정책이 같이 변경될 필연적인 이유가 없으므로 처음부터 로직을 공유하지 말았어야했다.
마무리
정리하자면 “같이 변경되어야 한다면 응집하여 중복을 해결하고 그렇지 않다면 우연한 중복이었을 뿐 중복을 해결할 필요 없다” 이다.