Static Variable과 Static Method
정적인 변수와 메서드는 한 번 선언 해놓으면 이곳 저곳에서 모두 사용할 수 있기 때문에 매우 편리하게 사용될 수 있다. 하지만, 시스템적으로 보았을 때 정적인 변수와 메서드는 최대한 지양하는 것이 좋다. 정적인 변수와 메서드를 참조 하는 클래스가 늘어난다는 것은 정적 변수와 메서드에 의존성이 생긴다는 것을 뜻한다.
이는 프로그램이 작을 때는 문제가 없지만 프로그램이 커지면 커질 수록 큰 문제로 번진다. 특히 정적 변수는 해당 변수가 여러 클래스에서 공유되게 될 경우 해당 클래스들이 서로가 서로에게 의존성이 생기는 것을 의미한다. 정적 메서드의 경우 정적 변수를 참조하지 않으면 그나마 낫지만, 정적 변수를 참조하지 않더라도 테스트 시에 문제가 생길 가능성이 크다.
정적 메서드 사용 시 문제 상황 알아보기
예를 들어 인터넷에 연결해 유저 이름을 검증해야 하는데, 해당 유저 이름을 검증하기 위한 메서드를 정적 메서드로 만든 경우를 생각해보자.
class UserNameValidator() {
fun validateUserName(userName: String) : Boolean {
return validateUserNameFromServer(userName)
}
}
fun validateUserNameFromServer(userName: String) : Boolean {
//Server Call
return false
}
UserNameValidator 클래스를 테스트 하기 위해서는 validateUserName() 메서드가 무조건 실행되어야 하는데 정적 메서드 이기 때문에 이를 바꿀 방법이 없다. Test Double을 사용하기 위해서는 객체가 있어야 한다. 따라서 validateUserName 클래스는 테스트를 할 수가 없게 된다.
문제 상황 수정하기
위 문제를 해결하기 위해서는 다음과 같이 수정해야 한다. 그러면 ServerValidator을 Stub 같은 Test Double로 바꿔치기가 가능하기 때문에 테스트가 가능해진다.
class UserNameValidator(private val serverValidator: ServerValidator) {
fun validateUserName(userName: String) : Boolean {
return serverValidator.validateUserNameFromServer(userName)
}
}
class ServerValidator() {
fun validateUserNameFromServer(userName: String): Boolean {
//Server Call
return false
}
}
정리
정적 메서드와 변수를 코드 상에서 최대한 줄이자. 어쩔 수 없이 사용하는 경우도 있을 수 있지만 최대한 줄이는 것이 좋다.