Vintage appMaker의 Tech Blog

[dart] if else 최소화를 위한 함수테이블 활용 본문

Source code or Tip/Flutter & Dart

[dart] if else 최소화를 위한 함수테이블 활용

VintageappMaker 2022. 8. 25. 14:43

 

일반적으로 대부분의 프로그래밍 언어에서는  if else 문이 길어지면 최소화하는 방법을 고민하게 된다. 고전적인 방법으로는 함수테이블을 만들어 상태에 따라 호출하는 방식을 사용하는데 FSM(Finate State Machine)이라고 불리기도 했다. FSM은 하드웨어의 논리구조처럼 상태표로 관리하는 방법인데 조건-상태-함수를 데이터화 하여 함수를 호출하는 방법이다.

요즘의 언어들(파이썬, 코틀린, 스위프트, ..)은 비교분기 기능이 함수형 프로그래밍과 어울리게 유연하고 편리하게 제공되고 있는 반면 dart는 기능이 약한 편이다. 그래서 고전적인 방법(C like)으로 

 

1. 조건함수 테이블 만들기

2. 상태관리자로 함수처리하기

를 구현했다. 

(*) FSM이나 상태관리자는 간단한 조건처리에서는 사용하지 않는 것이 현명하다.  if 문을 관리하기 버겨울 정도로 복잡해질 경우, 사용하는 방법이다.

 

[전체소스]


void main(List<String> arguments) {
  
  ifElseExample(3);
  fnTableExample(80);
  fnTableExample2(100);
  
  print('종료');
}

// 1. if else 처리 
void ifElseExample(int n) {
  if(n < 10){
    print("10 이하"); 
  
  } else if (n >=  10 && n < 50){
    print("10이상 50이하");

  } else if (n >= 50 && n < 80){
    print("50이상 80이하");
  
  } else if ( n >= 80 && n < 100){
    print("80이상 100 이하");
  
  } else if ( n == 100){
    print("100");
  }

}

// 2. 함수테이블을 이용한 조건처리 
void fnTableExample(int n) {
  // 코드가 커지면 분리하여 관리
  var fnAction1 = (){ print("10 이하");         };
  var fnAction2 = (){ print("10이상 50이하");   };
  var fnAction3 = (){ print("50이상 80 이하");  };
  var fnAction4 = (){ print("80이상 100 이하"); };
  var fnAction5 = (){ print("100"); return;};
  
  // 상태테이블
  var fnProcess = [ 
    [(){return (n < 10); },             fnAction1],
    [(){return (n >=  10 && n < 50); }, fnAction2],
    [(){return (n >= 50 && n < 80); },  fnAction3], 
    [(){return (n >= 80 && n < 100 ); },fnAction4],
    [(){return (n == 100 ); },          fnAction5],
     
  ].forEach((element) {
    if(element[0]() == true){
      element[1]();
      return;
    }  
  });
}

// 3. 상태관리자를 통한 조건처리
void fnTableExample2(int n) {

  // 코드가 커지면 분리하여 관리
  var fnAction1 = (){ print("10 이하");         };
  var fnAction2 = (){ print("10이상 50이하");   };
  var fnAction3 = (){ print("50이상 80 이하");  };
  var fnAction4 = (){ print("80이상 100 이하"); };
  var fnAction5 = (){ print("100"); return;};

  // 상태정의
  var state = stateProcess();
  state.addIf(condition : (){return (n < 10); },             onAction: fnAction1);
  state.addIf(condition : (){return (n >=  10 && n < 50); }, onAction: fnAction2);
  state.addIf(condition : (){return (n >= 50 && n < 80); },  onAction: fnAction3);
  state.addIf(condition : (){return (n >= 80 && n < 100 ); },onAction: fnAction4);
  state.addIf(condition : (){return (n == 100 ); },          onAction: fnAction5);

  state.process();
}

// 상태관리 클래스
class stateProcess{
  late List fnProcess;
  stateProcess(){
    // 비교문에 무시(false)되는 초기값
    fnProcess =[[(){return false;}, (){}]];
  }

  void addIf({required Function condition, required Function onAction}){
    fnProcess.add([condition, onAction]);
  }
  void process (){
    fnProcess.forEach((element) {
      if ( element[0]() == true) {
        element[1]();
        return; 
      }
    });
  }
}

 

 

 

Comments