2022-02-13-TIL
Today I Learned
Helper Class
Wikipedia의 정의에 따르면 헬퍼 클래스는 애플리케이션이나 그 클래스의 주목적은 아니지만 필요한 기능을 도와주기 위해 만드는 클래스다. 모든 메서드가 static이면 유틸리티 클래스라고 부르고, 이는 헬퍼 클래스의 특수한 경우다. 헬퍼 클래스는 인스턴스 변수를 가질 수 있고 여러 인스턴스가 있어도 된다. 위임(delegation) 패턴에서 일을 넘겨받는 객체가 헬퍼 객체의 예다.
헬퍼 클래스는 편하지만 이름이 XxxHelper, XxxUtils가 되는 순간 책임이 흐려지기 쉽다. “도와주는” 기능이라는 이름 아래 관련 없는 메서드가 계속 쌓이기 때문이다. 헬퍼에 모인 메서드가 특정 도메인 객체의 데이터만 다룬다면, 그 객체의 메서드로 옮기는 편이 응집도가 높다.
- https://en.wikipedia.org/wiki/Helper_class#:~:text=In%20object%2Doriented%20programming%2C%20a,%2C%20in%20the%20delegation%20pattern).
Private Method
private 메서드를 너무 많이 만들면 객체 간의 분리가 잘 되어 있는지, 하나의 클래스가 너무 많은 기능을 담당하는 것은 아닌지 점검해 봐야 한다. 하지만 적절한 상황에서 분리한 private 메서드는 테스트 코드 작성 및 리팩토링에 유리하다는 장점이 있다.
private 메서드는 그 자체로 테스트하기 어렵다. 그래서 자주 나오는 질문이 “private 메서드를 어떻게 테스트하느냐”인데, 일반적인 답은 private 메서드를 직접 테스트하지 않고 그것을 호출하는 public 메서드를 통해 검증하라는 것이다. private 메서드는 구현 세부 사항이므로, 테스트가 여기에 직접 묶이면 리팩토링할 때마다 테스트가 깨진다.
그런데 public 메서드만으로 검증하기 어려울 만큼 private 메서드의 로직이 크다면, 그 자체가 신호다. 그 로직은 별도 책임일 가능성이 높고, 새 클래스로 떼어 내면(Extract Class) public 메서드로 직접 테스트할 수 있다. Extract Class는 한 클래스가 하던 일 일부를 새 클래스로 옮기고 원래 클래스는 그 클래스에 위임하게 만드는 리팩토링이다.
1
2
3
4
5
6
7
8
9
10
11
12
// 리팩토링 전: 할인 계산이 OrderService의 private 메서드에 숨어 있다
class OrderService {
public long checkout(Order order) {
return order.totalPrice() - discount(order);
}
private long discount(Order order) { /* 복잡한 규칙 */ }
}
// 리팩토링 후: 할인 정책을 별도 클래스로 떼어 직접 테스트한다
class DiscountPolicy {
public long discount(Order order) { /* 복잡한 규칙 */ }
}
정리하면 private 메서드가 늘어나는 것은 나쁘지 않지만, 테스트하고 싶은 private 메서드가 생겼다면 클래스를 나눌 때가 되었는지 먼저 본다.
- https://stackoverflow.com/questions/7446994/what-are-the-pros-and-cons-of-having-private-methods-return-string-instead-of-pa
- https://www.caroli.org/en/testing-private-methods-tdd-and-test-driven-refactoring/
- https://stackoverflow.com/questions/9485536/unit-testing-private-methods-and-how-to-refactor
댓글
아직 댓글이 없습니다