MVC로 개발하세요

01

언젠가 회사에서 API를 차세대로 리뉴얼 하는 작업을 진행한 적이 있다. API를 전체적으로 바꾸다보니 서비스 전체를 전수검사를 하게 되었다. 백엔드 개발자, 클라이언트 개발자, 그리고 QA까지 모두 부담이 너무 컸다. 그리고 이 부담을 줄이기 위해 PM이 묘수를 제시했는데…

그것은 바로 MVC 패턴을 이용하면 View의 수정 없이 API에 해당하는 Model만 변경되는 것이므로 검증 영역이 줄어드는 것이 아니냐는 이야기였다.



수정 범위와 QA

어떤 클래스나 함수를 수정했을 때 이것을 의존하는 다른 클래스나 함수는 전부 수정의 영향을 받는다. 이것을 우리는 영향 범위(혹은 scope)라고들 하는데, 이 영향 범위를 최소화 해야 한다는 뜻이다.

QA 입장에선 이 영향범위를 전부 테스트 해보아야 한다. (물론 개발자도) 아주 사소한 수정이라면 영향이 없을 것 같지만 버그는 언제나 예상하지 못한 곳에서 발생하기 마련이므로 영향이 없을 순 없기 때문이다. 가령 예를 들자면 로직 변경 없이 클래스 하나의 이름만 바꾸는 아주 사소한 수정일지라도 난독화 따위에 의한 에러가 발생한다면 이 클래스를 참조하는 모든 클래스에서 에러가 전파될 수 있다. 따라서 아무리 사소한 수정도 영향도나 가능성이 낮을 지언정 영향 범위는 줄어들지 않는다고 보아야 한다.

클린 아키텍처의 목적 중 하나는 이러한 영향범위를 최소화 하는 것이다. 가장 중요한 비즈니스 로직을 가장 안쪽에 숨겨서 변동성이 큰 요소로 인한 영향을 차단한다. 따라서 만약 잘 짜여진 아키텍처라면 비즈니스 로직이 변하지 않는 API수정은 영향범위를 제한할 수 있다. 하지만 비즈니스 로직을 포함하는 코어 로직에 변경이 일어나는 경우라면 어떨까?


비즈니스 로직이 변경 된다는 의미

비즈니스 로직이란 순수하게 사용자에게 무엇을 제공할 것인지를 의미한다.

조금 쉽게 풀어보자면 어떤 기능 혹은 서비스를 통해 사용자에게 무엇을 하고자 하는지가 비즈니스의 로직에 해당한다. 반대로 어떤 UI로 제공할 것인지, 어떤 API를 사용할 것인지, 심지어 어떤 플랫폼으로 제공할 것인지는 부차적인 것에 해당하며 이것은 무엇을 제공할 것인지가 아니라 어떻게 제공할 것인지에 해당한다. 따라서 비즈니스 로직은 그야말로 어플리케이션의 뼈대이자 정의(definition), 존재 목적이라 할 수 있다.

컨퍼런스에서 클린 아키텍처 세션을 듣고 다음과 같은 질문을 한 적 있었다. (아주 정확하게 기억은 나지 않지만..)

Q. 클린 아키텍처 구조에서 외부 인터페이스가 아닌 내부 비즈니스 로직이 자주 바뀌면 어떻게 영향을 줄일 수 있을까요? A. 비즈니스 로직이 바뀐 다는 의미는 앱의 정의가 바뀐다는 의미이므로 클린 아키텍처가 영향을 줄일 수 없습니다.

사실 이 답변이 이 글의 핵심 주제가 될 수 있을 것 같다. 비즈니스 로직이 변하는 것은 앱의 정의가 바뀌는 것이기 때문에 정의가 바뀌면 나머지도 전부 영향을 받을 수 밖에 없다. 설령 View는 바뀌지 않고 내부 UseCase만 바뀌는 경우 일지라도 View역시 영향을 받을 수 밖에 없다는 뜻이다.

클린 아키텍처 관점에서 설명하자면 API의 변경이 Entity의 변경이어서는 안되지만, API의 변경이 Entity 또는 UseCase의 변경과 함께 일어나는 경우라면 어쩔 수 없이 전부다 수정되고 영향범위를 제어할 수 없다는 의미가 된다.




그렇다면 비즈니스 로직이 변경될 때는 어떻게 해야 QA의 부담을 줄일 수 있을까?

총도 살살 쏘면 안아파요

03

기존의 로직에서 최대한 수정을 적게해서 영향도를 낮출 수도 있다. 아마 PM이 MVC 구조를 이야기한 것도 이런 맥락에서 보면 이해가 되지 않는 것은 아니다. 그러나 코드 수정이 적다고해서 영향범위가 줄어드는 것은 아니며 오히려 영향도를 낮추기 위해 기존 로직을 건드리지 않고 최소한의 코드만 수정하려다 보면 마치 누더기를 덕지덕지 덧댄 코드가 될 수 있기 때문에 이 방법은 코드의 품질 저하로 이어질 수 있다.

코드를 살살 고친다고 QA의 일이 줄어들지는 않는다. 절대로.


테스트 코드를 작성하자

테스트 코드가 있다면 영향 범위가 줄어들지는 않을지언정 영향도는 낮출 수 있다. 테스트 코드가 영향 범위를 줄여주지도, QA가 할 일을 줄여주지는 않는다. 비즈니스 로직의 변경이 일어나면 기존 테스트 코드들도 함께 수정해야 할 가능성도 높다. 그걸 감안하더라도 테스트 코드 자체가 가지는 의미가 있다. 테스트 코드를 작성하는 행위 자체가 수정으로 인한 생각지 못한 곳의 영향을 사전에 발견하여 버그 레포트를 줄일 수 있으며 이를 통해 개발자와 QA간의 불필요한 피드백과 부담을 줄여줄 수 있는 것은 확실하다. 테스트 코드로 기존 요구사항이 명확하게 정리되어 있다면 기존 코드들의 의도를 파악하기도 쉽다. 게다가 최소한의 코드 라인만 수정하기 위한 누더기 코드를 짜는 대신 이 테스트 코드를 믿고 필요한 부분을 과감하게 리팩토링 할 수도 있다.

따라서 만약 이미 아키텍처가 잘 잡혀있다면 테스트 코드를 작성하기에도 용이하고 수정범위도 제한할 수 있다. 개발자들이 아키텍처를 중요시 여기는 이유가 여기에 있다. 그럼에도 혹시 테스트 코드를 짜야하는 이유가 납득이 안된다면 이전에 작성한 너, 나, 우리에게 Unit 테스트가 필요한 이유를 읽어보시는걸 추천드린다.


commit과 PR을 쪼개자

커밋과 PR을 쪼개는 것에는 여러가지 효과가 있다. 히스토리 파악하기에 유리하고 필요시에 git revert 등을 사용하기에도 유리하다. 또한 PR 리뷰 시에도 리뷰어의 부담을 줄여서 더 정확하고 좋은 리뷰를 받을 수 있다. 또한 이런식으로 작업단위가 나뉘어 있다면 차선책으로 ‘수정 사항을 버전별로 나누어서 반영’하기에도 용이해진다.