작성
·
337
0
의존성 조언 두번째 방법에서 문제점이
UserService.login은 여전히 의존성이 감춰져있다. 위와 마찬가지로 Userservice.login을 테스트할 때 clock에 의존하고 있는지 알 수 없다.
이거였는데 세번 째 방법도 UserService를 사용하는 메서드는 login(user)만 남겨서 user가 Clock에 의존하는지 모르지 않나요?
아까 맥도날드 예제에서는 인터페이스를 사용하면 일을 시킨다고 설명하셨는데 이것도 인터페이스를 사용해서 일을 시키는거니 이렇게 구현하면 내부에서 clockHolder를 사용해도 외부에서 몰라도 되나요?
답변 2
1
안녕하세요. 근래에 책을 집필할 기회가 생겨 그쪽에 힘을 실어주다 보니 다른 일에 신경 쓰지 못했습니다. 답변이 늦어 죄송합니다. 다만 해당 강의는 공식적으로 질의응답을 제공하지 않는 강의였다는 점을 이유로 늦어진 부분에 대해 양해 부탁드립니다.
질문을 남겨준 뒤로 시간이 오래 지나 질문이 어떤 내용이었는지 기억하실지 모르겠습니다.😂 그래서 질문해 준 내용이 어떤 내용인지 한 번 언급하고 답변 달겠습니다.
우선 질문을 요약하면 “UserService를 사용하는 메서드는 login(user)만 남기면 UserService가 Clock에 의존하는 상황인지 모르는 게 아니냐?”인 것 같습니다. 그리고 이 질문은 아래 코드를 기반으로 질문주신 것 같습니다.
@RequiredArgsConstructor
public UserService {
private final ClockHolder clockHolder;
public void login(User user) {
// ...
user.login(clockHolder);
}
}
이에 대해 답을 먼저 하겠습니다. 이는 의존이 감춰진 형태는 아닙니다.
왜냐하면 UserService를 위해선 생성자를 통해 ClockHolder 값을 넣어줘야하기 때문입니다. 그래서 UserService를 사용하는 과정에서 Clock에 대한 의존이 드러납니다.
UserService userService = new UserService(new SystemClockHolder());
userService.login(user);
일반적으로 객체의 사용자는 객체를 사용하기 위해 객체를 필연적으로 생성해야 합니다. 그래서 객체 사용자는 이 과정에서 해당 객체에 필요한 것이 무엇인지 확인할 수 있습니다.
*) 우리가 사용하는 스프링이 이러한 역할을 대신해서 해주고 있기 때문에 이러한 오해가 발생했다 봅니다. 더불어 강의의 흐름상 login 메서드만 집중해 의존도를 평가하고 있으니 충분히 생길 수 있는 오해였다고 보고요.
두 번째 질문은 제가 이해를 잘 못했습니다. 대략적으로 이해하기에 “이러니저러니 해도 결국 login 메서드를 실행하는 시점에는 매개변수로 user만 사용되니 외부에선 clockHolder 사용을 전혀 모르게 되는 거 아니냐? 이래도 괜찮은 것 맞냐?”라고 물어보는 것 같습니다.
그래서 이에 기반해 답변드리면, 제 의견은 “그래도 된다”입니다. 왜냐하면 위의 답변처럼 이 의존은 생성자를 통해 드러나기 때문입니다. 그리고 동시에 “원한다면 login(user, clockHolder) 형태로 메서드를 작성해도 된다”라고 답변하겠습니다. 왜냐하면 실제로 어떤 경우엔 “이 메서드를 실행하는 시점에, 이 정보는 반드시 외부로 드러났으면 좋겠는데?”라는 생각이 들어, 그렇게 개발하는 경우도 있기 때문입니다.
어떤 형태로 개발해도 괜찮습니다. 의존성이 숨겨진 형태로 개발되는 것만 지양하세요.
더불어 혹시나 ‘메서드를 호출하는 시점에 모든 의존은 무조건 바깥으로 노출하는 것이 좋은 것은 아니다’라고 답변하겠습니다. 메서드 호출 시점에 무조건 모든 의존을 나열하도록 개발해야 한다면 메서드의 파라미터가 너무 길어질 것입니다. 그런데 그렇게 개발하는 것은 너무나 비효율적입니다. 그러니 적당히 중간지점에서 타협을 봐야 합니다.
답변이 도움 됐길 바랍니다.
0
안녕하세요, 인프런 AI 인턴이에요.
말씀하신 것처럼 의존성 조언 방법을 사용할 때 UserService의 login 메서드가 Clock에 의존하는지 알 수 없는 문제가 있습니다. 이러한 경우를 해결하기 위해서는 UserService 클래스도 인터페이스를 사용하여 구현해야 합니다.
세번째 방법에서는 UserService를 사용하는 메서드를 login(user)만 남기고 나머지는 제거하여 user가 Clock에 의존하는지 확인할 수 있습니다. 하지만 이는 UserService 클래스 내부에서 clockHolder를 사용하면서 외부에서 알 수 없는 의존성을 만들 수 있습니다. 따라서 clockHolder도 인터페이스를 사용하고, UserService와 구현 클래스는 clockHolder 인터페이스를 의존하도록 설계해야 합니다.
즉, UserService와 clockHolder 간에 인터페이스를 도입하면 UserService 클래스 내부에서 clockHolder를 사용하더라도 외부에서 그 의존성을 쉽게 파악할 수 있게 됩니다. 이를 통해 유연하고 테스트 가능한 코드를 작성할 수 있습니다.
그러므로 인터페이스를 사용하여 UserService와 clockHolder 간의 의존성을 분리하고, 외부에서 쉽게 관리할 수 있도록 설계하는 것이 좋습니다.
더 궁금한 점이 있으시면 언제든지 물어보세요. 감사합니다.