들어가며
사이드 프로젝트에서 푸시 알림을 활용한 서비스를 개발하고 있습니다. 그 과정에서 생각하고 배웠던 점들을 하나씩 작성하고자 합니다. 프로젝트 개발을 하면서, 비즈니스 로직을 계속 추가해야 하는 상황이었습니다. 그 과정에서, if-else 문이 계속해서 늘어났고, 하나의 기능을 추가하려고 했을 때, 전에 작성했던 로직들을 계속해서 살펴봐야 하는 문제가 발생했습니다. 앞으로 더욱 로직은 복잡해질 텐데, if-else 문이 계속해서 늘어난다면, 기존 로직을 분석하고 해석하는데 더 많은 시간이 사용될 것이라 생각했습니다. 더 늦기 전에, 이런 로직들을 리팩터링 해야겠다고 생각했습니다. 이번 시간에는 if-else 문을 리팩터링 한 내용에 대해 조금 더 자세히 알아보겠습니다.
If-else 고치기
보통 코드를 작성할 때, 특정 조건일 경우 특정 코드를 실행시키는 if 코드를 작성하곤 합니다. 보통 개발을 하다 보면, 기능 추가에 맞게 점점 if 문에 해당하는 조건이 추가됩니다. 그렇게 if 블록이 길어지면, 코드를 분석할 때 조건들을 모두 기억해야 하는 문제가 있습니다. 그렇기에 코드 분석이 힘들어지는 문제가 있습니다.
const findFavoriteSummonerId =
await this.findFavoriteSummonerIdWithSoftDelete(
userDto.userId,
favoriteSummonerDto.summonerId,
);
if (!findFavoriteSummonerId) {
await this.favoriteSummonerRepository.save(
await favoriteSummonerDto.toFavoriteSummonerEntity(userDto.userId),
);
} else {
await this.favoriteSummonerRepository.restore(findFavoriteSummonerId.id);
}
프로젝트를 개발하다 보니, 제 코드에도 이런 if-else 코드가 존재했습니다. 코드에서 나는 악취를 제거하기 위해서는 if-else문을 제거하고, 조건이 아닌 경우 빠르게 return 하는 코드를 작성해야겠다고 생각했습니다. 저는 이 코드를 다음과 같이 고쳐봤습니다.
export class FavoriteSummonerApiService {
... 생략
const favoriteSummonerId = await this.findFavoriteSummonerIdWithSoftDelete(
userDto.userId,
favoriteSummonerDto.summonerId,
);
await this.saveFavoriteSummoner(favoriteSummonerId, favoriteSummonerDto, userDto);
await this.restoreFavoriteSummoner(favoriteSummonerId, favoriteSummonerDto, userDto);
... 생략
private async saveFavoriteSummoner(
favoriteSummonerId: FavoriteSummonerId,
favoriteSummonerDto: FavoriteSummonerReq,
userDto: UserReq,
) {
if (!favoriteSummonerId)
await this.favoriteSummonerRepository.save(
await favoriteSummonerDto.toFavoriteSummonerEntity(userDto.userId),
);
}
private async restoreFavoriteSummoner(
favoriteSummonerId: FavoriteSummonerId,
favoriteSummonerDto: FavoriteSummonerReq,
userDto: UserReq,
) {
if (favoriteSummonerId)
await this.favoriteSummonerRepository.restore(favoriteSummonerId.id);
}
}
saveFavoriteSummoner, restoreFavoriteSummoner 로직을 만들어서, if-else 로직을 분리시켰습니다. 이를 통해 비즈니스 로직에서 코드의 역할과 책임을 분리할 수 있었습니다. 또한 캡슐화한 로직 안에 if 문을 확인해서, 만약 조건이 맞다면 조건에 맞는 로직을 실행시키고, 조건이 맞지 않다면 로직을 실행시키지 않도록 구성했습니다. 이를 통해 if-else 코드를 없앨 수 있었고, 복잡한 코드를 이해하기 쉽게 설계할 수 있었습니다.
마치며
앞으로도 팀의 발전을 돕는 개발자가 되기 위해 노력하려 합니다. 팀에 필요한 부분이 무엇일지 고민하면서, 팀에 도움이 된다면, 열심히 공부해서 실무에 적용할 수 있는 개발자가 되기 위해 노력하고 싶습니다. 팀의 성장에 기여할 수 있는 개발자가 되겠습니다.
참고 및 출처
'Project > 서버 개발' 카테고리의 다른 글
[Project] 프로젝트 삽질기21 (feat 모노레포) (0) | 2022.04.19 |
---|---|
[Project] 프로젝트 삽질기20 (feat Node 버전 관리) (0) | 2022.04.18 |
[Project] 프로젝트 삽질기18 (feat 쿼리 튜닝, 인덱스) (0) | 2022.04.11 |
[Project] 프로젝트 삽질기17 (feat Table Scan 실행계획) (0) | 2022.04.09 |
[Project] 프로젝트 삽질기16 (feat Connection Pool) (0) | 2022.04.08 |