전문가를 위한 스프링5라는 책을 읽으며 자바빈 스타일로 작성된 인터페이스 예제를 만났습니다. (p70)
제가 만난 예제는 아래와 같습니다.
public interface MessageProvider {
String getMessage();
}
public interface MessageRenderer {
void render();
void setMessageProvider(MessageProvider provider);
MessageProvider getMessageProvider();
}
위의 코드를 보면서 느낀 점은 각각의 인터페이스에 적절한 책임이 할당되어 있다는 것입니다.
그런데 위의 인터페이스를 통해 빈을 등록한다고 하면 약간의 어색함을 느끼는 사람이 많을 것 같습니다.
우선 저의 경우는 습관적으로 Lombok의 @RequiredArgsConstructor를 사용하다 보니 해당 예제는 조금은 어색하게 느껴졌던 것 같습니다.
아마 setter의 존재가 무의식적으로 저에게 그러한 어색함을 안겨준 게 아닌가 싶습니다.
그리고 위의 코드는 사실 setter가 없이도 문제는 없습니다.
아래와 같이 MessageProvider를 final로 지정하여 생성 시 주입받으면 되기 때문입니다.
public class StandardOutMessageRenderer implements MessageRenderer {
private final MessageProvider messageProvider;
// final로 지정하였기 때문에 생성시 MessageProvider가 할당되어야 함
public StandardOutMessageRenderer(MessageProvider messageProvider) {
this.messageProvider = messageProvider;
}
...
}
그런데 이러면 항상 드는 생각이 있었습니다.
"나는 MessageRenderer에 필요한 것이 MessageProvider라는 것을 알지만 다른 개발자들은 이것을 어떻게 알지?" 하는 생각입니다.
코드를 살펴보면, 문서로 남겨두면 이라는 방법이 있겠지만 이 또한 하나의 비용이 될 수 있다는 생각도 하게 됩니다.
이러한 점에서 자바빈 스타일 인터페이스는 코드 내에서 구현에 필요한 클래스 타입을 알 수 있다는 점에서 저에게 매력적으로 다가왔습니다.
개인적인 생각
그럼 자바빈 스타일 인터페이스는 언제 쓰는 게 좋을까요?
- 해당 컴포넌트에서의 책임을 수행하기 위해 가져야 하는 컴포넌트 타입이 명확한 경우
- 코드가 방대하여 그것을 탐색하거나 문서로 남기는 것 보다 인터페이스를 통해 명시하는 것이 비용이 적다고 판단되는 경우
그럼 단점은 어떨까요?
- 위의 인터페이스 선언에서 볼 수 있듯 클라이언트 입장에서는 알지 않아도 되는 setter와 getter가 노출됩니다.
- 인터페이스의 책임을 수행하는 과정에서 getter에 대한 null check가 필요합니다.
public class StandardOutMessageRenderer implements MessageRenderer {
private MessageProvider messageProvider;
@Override
public void render() {
// null check
if (getMessageProvider() == null) {
throw new RuntimeException(
"You must set the property messageProvider of class:"
+ StandardOutMessageRenderer.class.getName());
}
System.out.println(getMessageProvider().getMessage());
}
// getter, setter 노출
@Override
public void setMessageProvider(MessageProvider provider) {
this.messageProvider = provider;
}
@Override
public MessageProvider getMessageProvider() {
return this.messageProvider;
}
}
마무리
어떠한 코드에도 장점만 있는 코드는 없을 것이라 생각합니다.
다양한 방법에 대해 인지하고 프로젝트와 팀의 상황에 맞추어 적절한 방법을 택할 수 있는 것도 개발자로서 갖추어야 하는 중요한 능력이라는 생각을 요즘 하고 있습니다.
그러한 점에서 이번 정리를 통해 저의 선택지에 자바빈 스타일 인터페이스가 추가되어 의미가 있었던 정리인 것 같습니다.
감사합니다.
'개발' 카테고리의 다른 글
RabbitListener 등록과 동작 (0) | 2024.03.12 |
---|---|
AMQP 0-9-1(RabbitMQ) 문서 정리 (0) | 2024.03.11 |
@Transactional 안에서 일어나는 일을 살펴보며 (0) | 2024.03.03 |
이벤트와 메시지 (0) | 2024.03.01 |
AutoConfiguration 대신 자바 구성을 설정하며 학습하기 (0) | 2024.03.01 |