조건문 코드는 어떻게 작성하나요?

이 게시물 정보



조건 논리에서 if 문을 사용하면 들여쓰기가 깊어져 코드를 읽기가 어렵습니다.
이 게시물에서는 조건부 논리에 대한 다른 구현 유형을 소개합니다.
모든 개발자가 조건에 대한 if 문과 다른 아이디어를 얻고 유지 관리하기 쉬운 코드를 작성하기를 바랍니다.

대상 독자


  • 이제 막 개발을 시작한 초보자들
  • 복잡한 조건문 처리 방법을 알고 싶은 분
  • 개발팀에서 코드를 검토하는 사람들

  • 조건문



    이번 포스팅에서는 조건문 구현의 4가지 유형을 소개합니다.
  • if/if-else
  • 스위치 케이스
  • 사전
  • 전략패턴

  • 이 게시물에서 소개한 방법 외에 다른 구현 방법을 알고 있다면 댓글로 공유해 드리겠습니다.

    만약 / 만약 - 그렇지 않으면



    조건에 if/if-else , <= 또는 >= 와 같은 표현이 포함되어 있고 ! 문 내부의 논리가 그다지 크지 않은 경우 if 가 선호됩니다.

    const examinationScore = doExamination();
    if (examinationScore >= 80) {
      // not so big logic
      console.log('good job :)');
    } else if (examinationScore >= 60) {
      // not so big logic
      console.log('so so :()');
    } else {
      // not so big logic
      console.log('do more hardwork ;(');
    }
    

    if 문 내부의 논리가 큰 경우 나중에 언급되는 전략 패턴을 사용할 수 있습니다. 왜냐하면...
  • if 문 내부의 논리 조건이 무엇인지 기억하기 어렵습니다 (코드를 읽기 어렵습니다)
  • 코드를 유지하기 어렵다

  • 스위치 케이스



    조건 수를 늘리면 switch case 문을 선택할 수 있습니다.

    const gpaScore = getGPA();
    switch (gpaScore) {
      case 2:
        // do some small logic
        break;
      case 3:
        // do some small logic
        break;
      case 4:
        // do some small logic
        break;
      case 5:
        // do some small logic
        break;
      default:
        // do some small logic
        break;
    }
    


    특정 조건 하에서 어떤 값이 반환될 때 아래에 언급된 사전을 사용할 수 있습니다.

    사전



    아래와 같이 switch case를 쓰고 싶다면 대신 사전을 사용하는 것을 고려할 수 있습니다.
    특정 조건 하에서 어떤 값이 반환될 때 사전을 사용하는 것이 적합합니다.

    (스위치)

    const weekdayName = getWeekday();
    switch (weekdayName) {
      case 'monday':
        console.log('Let\'s start a new week!');
        break;
      case 'tuesday':
        console.log('This is second day of this week. Do your best!');
        break;
      case 'wednesday':
        console.log('If you need, let\'s take break');
        break;
      case 'thursday':
        console.log('The half of the week done!');
        break;
      case 'friday':
        console.log('If you do your best today, tomorrow is holiday!');
        break;
    }
    


    새로운 조건을 추가할 때 break를 잊어버릴 수 있으며, switch case를 사용하면 논리가 커지는 경향이 있습니다.

    const weekdayName = getWeekday();
    switch (weekdayName) {
      case 'sunday':
        console.log('Hoo! Today is holiday!'); // oops! if you forget "break", it makes some bugs!
      case 'monday':
        console.log('Let\'s start a new week!');
        break;
      case 'tuesday':
        console.log('This is second day of this week. Do your best!');
        break;
      case 'wednesday':
        console.log('If you need, let\'s take break');
        break;
      case 'thursday':
        console.log('The half of the week done!');
        break;
      case 'friday':
        console.log('If you do your best today, tomorrow is holiday!');
        break;
    }
    


    (사전)

    const weekdayMessages = {
      monday: 'Let\'s start a new week!',
      tuesday: 'This is second day of this week. Do your best!',
      wednesday: 'If you need, let\'s take break',
      thursday: 'The half of the week done!',
      friday: 'If you do your best today, tomorrow is holiday!'
    };
    const weekdayName = getWeekday();
    const message = weekdayMessages[weekdayName];
    console.log(message);
    


    새로운 요일을 추가해야 할 경우 추가가 용이하고 유지 보수성이 유지됩니다.

    const weekdayMessages = {
      // just add elements if you wanna add new weekday
      sunday: 'Hoo! Today is holiday!',
      monday: 'Let\'s start a new week!',
      tuesday: 'This is second day of this week. Do your best!',
      wednesday: 'If you need, let\'s take break',
      thursday: 'The half of the week done!',
      friday: 'If you do your best today, tomorrow is holiday!'
    };
    const weekdayName = getWeekday();
    const message = weekdayMessages[weekdayName];
    console.log(message);
    


    전략 패턴



    객체 지향 언어(예: Java, C# 또는 Ruby)를 사용하는 경우 if / if-else 문 대신 전략 패턴을 선택할 수 있습니다.
    if / if-else 문을 사용하면 논리는 다음과 같습니다.
    이것은 코드를 읽고 유지하는 것이 쉽지 않습니다.

    public class FooHandler {
        public void doSomeLogic() {
          if (/*condition A*/) {
            // logic A (big logic)
          } else if (/*condition B*/) {
            // logic B (big logic)
          } else if (/*condition C*/) {
            // logic C (big logic)
          }
        }
    }
    


    논리 D를 새로 추가하거나 논리 B를 변경하려면 FooHandler의 논리를 변경해야 합니다.
    결과적으로 FooHandler의 전체 클래스를 반복해서 테스트해야 합니다.

    public class FooHandler {
        public void doSomeLogic() {
          if (/*condition A*/) {
            // logic A (big logic)
          } else if (/*condition B*/) {
            // you need to edit FooHandler if you wanna modify logic B
            // logic B (big logic)
          } else if (/*condition C*/) {
            // logic C (big logic)
          } else if (/*condition D*/) {
            // you need to edit FooHandler if you wanna add logic D
            // logic D (big logic)
          }
        }
    }
    


    그러나 전략 패턴을 사용하면 읽기 쉽고 유지 관리 가능한 코드를 작성할 수 있습니다.
    전략 패턴에서는 interface가 사용됩니다.

    public class Program {
        public static void main () {
            FooHandler handler = new FooHandler();
            // choose the class which you wanna execute
            handler.doSomeLogic('Bbb');
        }
    }
    
    public class FooHandler {
        public void doSomeLogic(String className) {
            // if statement is not need here
            IFoo hogeInstance = (IFoo) Class.forName(className).newInstance();
            String result = hogeInstance.execute();
        }
    }
    
    public interface IFoo {
        execute();
    }
    
    // if you wanna add / change / delete the logic, you just edit the individual class Aaa, Bbb or Ccc
    public class Aaa implements IFoo {
        public void execute() {
            // logic A
        }
    }
    
    public class Bbb implements IFoo {
        public void execute() {
            // logic B
        }
    }
    
    public class Ccc implements IFoo {
        public void execute() {
            // logic C
        }
    }
    


    클래스 다이어그램


    스트래티지 패턴의 좋은 점은...
  • 논리 추가 또는 변경 용이
    (개별 클래스의 로직 추가 및 변경 용이 Aaa , Bbb , Ccc , Ddd ).
  • if / if-else 를 작성할 필요가 없으므로 논리가 복잡하지 않습니다.

  • public class Program {
        FooHandler handler = new FooHandler();
        // choose the class which you wanna execute
        handler.doSomeLogic('Bbb');
    }
    
    public class FooHandler {
        public void doSomeLogic(String className) {
          // if statement is not need here
          IFoo hogeInstance = (IFoo) Class.forName(className).newInstance();
          String result = hogeInstance.execute();
        }
    }
    
    public interface IFoo {
        execute();
    }
    
    // if you wanna add / change / delete the logic, you just edit the individual class Aaa, Bbb or Ccc
    public class Aaa implements IFoo {
        public void execute() {
            // logic A
        }
    }
    
    // if you wanna modify logic B, you just edit class BBb (no need to test again for other classes)
    public class Bbb implements IFoo {
        public void execute() {
            // logic B
        }
    }
    
    public class Ccc implements IFoo {
        public void execute() {
            // logic C
        }
    }
    
    // if you wanna add new logic, you just add new class (no need to test again for other classes)
    public class Ddd implements IFoo {
        public void execute() {
            // logic D
        }
    }
    


    조건문으로 좋은 삶을 즐기시기 바랍니다!

    참조


  • Strategy pattern - Wikipedia
  • 좋은 웹페이지 즐겨찾기