프로필별로 다르게 동작하는 코드

jinwook han·2020년 3월 8일
0

문제 상황

회사에서 회원 관련 api 서버가 두 개 있다.
베타 서버, prod 서버라고 한다.
두 서버 모두 하는 기능은 동일하다.

하지만 실제 업무에서 차이가 있다.
베타에서 회원 속성 변경을 빈번하게 한다.
그에 반해 실제 prod 환경에서는 회원 속성 변경을 잘 하지 않는다.

예전에 타팀에서 회원 이름 규칙과 어긋나는 이상한 회원을 만든 적이 있었다.
이후 이상한 회원이 만들어지는 것을 방지하기 위해 회원의 특정 속성에 대한 변경을 막았다. (beta, prod 모두)
하지만 아까도 말했듯이, beta에서는 회원 속성 변경을 빈번하게 한다.
게다가 beta에서는 실험적으로 이상한 회원을 만들어야 할 상황이 있을 수도 있다.

팀에서 beta 서버는 예외적으로 상품 변경을 가능하게 하자고 결정했다.
아래와 같은 과정으로 코드를 수정했다.

힌트

배포하는 코드뭉치는 하나인데, 프로필별로 다르게 동작하게 하려면 어떻게 해야할까? (spring 환경이라고 가정한다)
사수가 힌트를 주었다.
beta, prod 별로 bean을 다르게 생성하는 것이다.

@Profile('prod')
@Bean
public class ClassForProd {
...
}
@Profile('beta')
@Bean
public ClassForBeta class {
...
}

위 코드대로 클래스를 만들었다.
또다른 의문이 들었다.
컨트롤러에서 이 두 서비스를 어떻게 활용해야 하지?

컨트롤러

사수에게 위 두 서비스를 어떻게 활용해야 할지 물었다.
먼저 인터페이스를 만든다.

interface ActDifferentByProfile {
	void actDifferently();
...
}

다음 방금 만든 서비스들이 인터페이스를 구현하도록 한다.

@Profile('prod')
@Bean
public class ClassForProd implements ActDifferentByProfile {
...
}
@Profile('beta')
@Bean
public ClassForBeta class implements ActDifferentByProfile {
...
}

그리고 컨트롤러에서는 다음과 같이 사용한다.

@Controller
public SomeController {
	public SomeController(...
    		ActDifferentByProfile actDifferentByProfile,
            	...)

	public void someMethod {
    		...
          	actDifferentByProfile.actDifferently();
    	}

}

이렇게 만들면 끝이다.
굉장히 간단한 코드다.
하지만 위 작업을 하는데 들인 시간은 5시간이다.
왜 이렇게 오래 걸렸을까?

작업했을 때의 상황

먼저 오전 두 시간동안 컨트롤러 이외에 모든 코드는 구현이 끝났다. 테스트코드까지 만들었다.
오후에 코드리뷰를 받고 고치면 한 시간 이내로 작업을 마무리할 것으로 생각했다.

코드리뷰를 받았다.
코드리뷰가 끝나니 두시였다.
다시 작업으로 돌아와서 보니 두 가지 문제점이 보였다.
1. 커밋 메시지가 잘못되었다.
2. 클래스 이름이 잘못되었다.

커밋 메시지를 고쳤다.
클래스 이름을 바꾸었다.
코드리뷰에서 받은 리뷰를 반영하고자 했다.
repository method 내용을 바꾸니 테스트가 다 터지기 시작했다.
생각지도 못한 테스트가 터졌다.
건드리면 안 될 코드를 건드렸다고 판단하고 작업하기 이전 commit으로 reset해서 테스트했다. 그래도 터졌다.

찾아보니 테스트가 터진 이유는, origin 브랜치에서 새로 바뀐 내용을 pull받지 않았기 때문이었다.
테스트를 수정했다.
시간을 보니 세 시 반이었다.

작업을 끝내고 배포를 하고 시계를 보니 네 시 반이었다.

더 잘하려면

  1. 코드리뷰에서 받은 리뷰를 정리한다.
    리뷰를 반영하는 작업을 어떻게 할지 미리 계획하고 작업한다.

  2. 테스트가 불통과한다고 마음이 급해질 필요가 없다. 배포 전 마지막 커밋만 테스트를 통과하면 된다.
    테스트가 불통과한다고 해서 작업하기 이전 commit으로 reset하는 행동은 불필요했다.

    전체 테스트는 작업이 끝날 때 한번만 진행하고, 테스트가 불통과하면 이유를 현재 코드에서 찾는다.

0개의 댓글