Programming/기타

코드 품질올리기, 코드 설계 - 2 분기중접 줄이기 (3/3)

armyost 2023. 8. 28. 23:57
728x90

이미 존재하는 기능을 다른 방법으로 구현할 필요는 없습니다.

 

1) 조건을 만족하는 요소가 컬렉션 내부에 하나라도 포함되어 있는 경우

 

잘못된 예

boolean hasPrisonKey = false;
// items List<Item> 자료형
for (Item each : items){
	if (each.name.equals("감옥열쇠")){
		hasPrisonKey = true;
	    break;
	}
}

이 기능을 간단하게 아래와 같이 구현할 수 있습니다.

 

올바른 예

boolean hasPrisonKey = items.stream().anyMatch(
	item -> item.name.quals("감옥열쇠")
);

이렇게 anyMatch를 사용하면 for 반복문과 if 조건문을 사용할 필요도 없이 한 줄로 처리를 완료할 수 있습니다.

 

2) 컬랙션 내부에서 특정 조건을 만족시키는 요소에 대해서만 어떤 작업을 수행하고 싶은 경우

 

잘못된 예

for (Member member:members){
	if(0 < member.hitPoint) {
    	if (member.containsState(StateType.poison)){
       		member.hitPoint -= 10;
            if (member.hitPoint <= 0) {
            	member.hitPoint = 0;
                member.addState(StateType.dead);
                member.removeState(StateType.poison);
            }
        }
    }
}

조기 continue로 분기 중첩 제거할 수 있습니다.

 

올바른 예

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

 

그리고 다른 경우를 예를 들어보겠습니다.

 

잘못된 예

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

조기 break를 통해 가독성을 향상시키 겠습니다.

 

올바른 예

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