본문 바로가기

디자인패턴/내 코드가 그렇게 이상한가요?

for문 내 if문 중첩 없애기 - 내 코드가 그렇게 이상한가요? 7장 요약 (1)

 

 

이미 있는 컬렉션 전용 메서드를 활용하기

`List<Item>`인 `items`를 탐색하여 "key"라는 아이템이 있는지 확인하는 로직을 다음과 같이 for문과 if문을 사용해서 구현할 수도 있지만, 자바에는 이미 해당 로직을 구현할 수 있는 `anyMatch`라는 메서드가 존재한다.

boolean hasKey = false;
for (Item item : items) {
    if (item.name.equals("key")) {
        hasKey = ture;
        break;
    }
}
boolean hasKey = items.stream().anyMatch(
    item -> item.name.equals("key")
);

 

 

`continue`를 활용해서 반복문 내 if문 중첩 제거

다음과 같이 반복문 내에 조건 분기문은 자주 볼 수 있는 로직이다. if문이 중첩되어 이해하기 상당히 불편하다. 

// 멤버들을 하나씩 탐색
for (Member member:members) {
	// 어떤 멤버의 hp가 남아있으면서
    if (0 < member.hp) {
    	// 중독에 빠졌을 때
        if(member.containsState(StateType.poisoned)) {
            // hp를 감소시키고
            member.hp -= 10;
            // 만약 hp가 0이하로 떨어지면
            if (member.hp <= 0) {
            	// hp를 0으로 보정하고
                member.hp = 0;
                // 사망처리
                member.addState(StateType.dead);
                // 중독 상태 제거
                member.removeState(StateType.poisoned);
            }
        }
    }

}

 

`continue`를 적용하여 if문 중첩을 제거하면 다음과 같다.

for (Member member : members) {
    if (member.hp == 0) continue;
    if (!member.containsState(StateType.poisoned)) continue;
    
    member.hp -= 10;
    
    if (0 < member.hp) continue;
    
    member.hp = 0;
    member.addState(StateType.dead);
    member.removeState(StateType.poisoned);
}

 

 

`break`를 활용해서 반복문 내 if문 중첩 제거

다음은 한 명이라도 실패하거나 조건에 맞지 않으면 반복문을 탈출하는 로직이다. 

int totalDamage = 0;

// 팀 멤버들을 차례대로 탐색
for(Member member : members) {
	// 한 명이라도 공격에 실패하면 그 뒤 공격은 모두 실패로 간주
    if (member.attackSucceed()) {
        // 성공시 원래 멤버 공격력의 1.1배로 계산
        int damage = (int)(member.attack() * 1.1);
        // 한 멤버의 데미지가 30 이상인 경우에만 총 데미지에 합산
        if (30 <= damage) {
            totalDamage += damage;
        } else {
            break;
        }
    } else {
        break;
    }
}

 

`break`를 적절히 사용해 중첩을 제거해보자.

int totalDamage = 0;
for (Member member : members()) {
    if (!member.attackSucceed)) break;
    int damage = (int)(member.attack() * 1.1);
    if (damage < 30) break;
    totalDamage += damage;
}