우테코 6기 프리코스 활동 중...
입력 시 예외가 발생하면 에러 메시지 출력 후 재입력해야 했다.
입력을 여러 번 받으니 동일한 구조의 while-try-catch
문도 여러 개였다.
개발자는 반복된 작업을 싫어하는 법.
함수형 인터페이스에 대해 알아야 이해할 수 있다.
당첨 번호를 입력해 주세요.
1,2,3,4,5,100
[ERROR] 로또 번호는 1부터 45 사이의 숫자여야 합니다.
당첨 번호를 입력해 주세요.
public class LottoController {
private final InputView inputView;
// 생성자, 비즈니스 로직 생략
private LottoPurchaseMoney askPurchaseMoney() {
while (true) {
try {
int money = inputView.askPurchaseMoney();
return new LottoPurchaseMoney(money);
} catch (IllegalArgumentException exception) {
System.out.printf("[Error] " + exception.getMessage());
}
}
}
private Lotto askWinningNumbers() {
while (true) {
try {
List<Integer> lottoNumbers = inputView.askWinningNumbers();
return new Lotto(lottoNumbers);
} catch (IllegalArgumentException exception) {
System.out.printf("[ERROR] " + exception.getMessage());
}
}
}
private LottoWinningNumbers createWinningNumbers(Lotto lottoNumbers) {
while (true) {
try {
int bonusNumber = inputView.askBonusNumber();
return new LottoWinningNumbers(lottoNumbers, bonusnumber);
} catch (IllegalArgumentException exception) {
System.out.printf("[ERROR] " + exception.getMessage());
}
}
}
}
public class ExceptionHandler {
private static final String ERROR = "[ERROR] ";
public <T> T run(Supplier<T> callback) {
while (true) {
try {
return callback.get();
} catch (IllegalArgumentException exception) {
System.out.println(ERROR + exception.getMessage());
}
}
}
}
public class LottoController {
private final InputView inputView;
private final ExceptionHanlder exceptionHanlder;
// 생성자, 비즈니스 로직 생략
private LottoPurchaseMoney askPurchaseMoney() {
return exceptionHandler.run(() -> {
int money = inputView.askPurchaseMoney();
return new LottoPurcahseMoney(money);
});
}
private Lotto askWinningNumbers() {
return exceptionHandler.run(() -> {
List<Integer> lottoNumbers = inputView.askWinningNumbers();
return new Lotto(winningNumbers);
});
}
private LottoWinningNumbers createWinningNumbers(Lotto lottoNumbers) {
return exceptionHandler.run(() -> {
int bonusNumber = inputView.askBonusNumber();
return new LottoWinningNumbers(lottoNumbers, bonusNumber);
});
}
}
null을 반환하는 메서드를 작성하면 된다.
public class ExceptionHandler {
private static final String ERROR = "[ERROR] ";
public <T> void runWithNoReturnValue(Supplier<T> callback) {
run(() -> {
callback.get();
return null;
}, message);
}
public <T> T run(Supplier<T> callback) {
while (true) {
try {
return callback.get();
} catch (IllegalArgumentException exception) {
System.out.println(ERROR + exception.getMessage());
}
}
}
}
본 블로그에서는 함수형 인터페이스 중 Supplier
를 사용했으나, 필요에 따라 다른 인터페이스로 응용할 수 있다.
ExceptionHandler
의 Supplier
와 run
메서드는 어떤 타입이든 반환할 수 있도록 제네릭 문법을 사용하고 있다.
공통 로직이 있고, 일부 행동만 바뀐다는 점에서 전략 패턴을 적용했다고 할 수 있다.