예시를 하나 들어볼게요. 처음 즐겨찾기를 하면 등록을 하지만 이미 즐겨찾기를 해놨다면 아무것도 안하고 싶어요.
사실 로직을 작성하는 것은 별로 어렵지 않을겁니다.
DB를 조회해서 데이터가 있으면 저장하고 없으면 바로 return 해서 끝내버리는 if문을 써서 분기처리를 하면 됩니다.
Optional<Object> object = respository.id로_데이터가_있는지_조회();
if (object가 null이 아님) {
return;
}
respository.저장();
당연히 작성한 슈도코드가 나쁘다는 것은 아닙니다.
하지만 데이터가 NULL 일 때 뭘 하려고 하는지 좀 더 직관적으로 볼 수 있도록 리팩토링을 할 수 있죠.
바로 리팩토링한 코드를 보시죠.
@Slf4j
@RequiredArgsConstructor
@Service
public class PickService {
private static final Consumer<Object> NOOP = whatever -> {
};
private final PickRepository pickRepository;
@Transactional
public void addPick(String playerId) {
log.info("즐겨찾기 등록");
pickRepository.findByplayerId(playerId) //...1
.ifPresentOrElse( //...2
ifAlreadyClicked(),
ifFirstClick(playerId)
);
}
private Consumer<? super Pick> ifAlreadyClicked() {
return NOOP; //...3
}
private Runnable ifFirstClick(String playerId) {
return () -> pickRepository.save(Pick.of(playerId));
}
}
이 코드를 보면 findByplayerId 했는데 뭔가 데이터가 있다면 ifAlreadyClicked 이라면서 아무것도 안 하고, ifFirstClick 이라면서 저장한다는 게 직관적으로 보입니다.