프로그래밍 초식 : 섞여있는 계산, 반영 로직 분리

Donghun Seol·2023년 4월 25일
0

프로그래밍 초식

목록 보기
8/13

레퍼런스

계산과 결과반영이 섞여 있는 코드

계산로직을 이해하는데 결과를 반영하는 코드가 노이즈로 작용한다. 특히 계산로직과 중첩된 조건문이 크고 아름다울 경우 더욱 이해가 힘들다. 또한 계산로직만 따로 테스트하기 어렵다.

아래의 코드에서 updatePeriod()함수는 결과를 반영하는 부분인데, 다른 계산부분과 중첩되어 있음을 확인할 수 있다.

function provideServicePeriod(ordNo:number, loginDate:LocalDate) {
  // ... period, order 구하고 검사하는 코드
  edate: Date = null;
  currDate: Date = order.getDate();
  nextDate: Date = currDate + 1;
  if (order.getGubun() === "AA") {
    if (order.getPayType() === "A" || 
        (order.getPayType() === "W" && order.getIncludePay() === "1") ) {
      if (order.getPayMonth() === "T") {
        edate = nextDate + 7;
      } else if (order.getPayMonth() === "N") {
        edate = nextDate + 30;
      }
      updatePeriod(period, currDate, edate); // 결과반영
    } else if (order.getPayType() === "D") {
      ...
    }
   else {
     if (order.getUnit() === "D") {
       edate = nextDate + 3;
     } else if (order.getUint === "Z") {
       edate = nextDate - 7;
     }
     updatePeriod(period, loginDate, edate) // 결과반영
   }
        
}

개선 방법

계산 코드와 계산결과를 사용하는 코드를 분리하여 개선한다. 이를 위해선 계산로직의 입출력을 분석해야 한다. 복잡한 계산의 경우 직관적으로 파악하기 어려운데 변수의 관계를 시각적으로 표현하면 보다 손쉽게 파악가능하다.

입출력이 파악되면 계산로직을 분리해나간다. 계산 분리는 함수를 생성하거나 계산을 위한 클래스를 만들어서 할 수 있다. 계산로직의 응집도를 높이고, 테스터빌리티 향상을 위해선 클래스를 정의하는 것이 바람직하다.

복잡한 if-else로 구성된 계산로직을 ServicePeriodCalculator 클래스 안에 캡슐화 한다.
계산기 클래스는 생성자에 입력값을 전달하면 클래스 내부에서 자동으로 필요한 값을 계산해서 메서드를 통해 필요한 값만 꺼내 쓸 수 있는 형태로 구현되어 있다.
호출하는 쪽에서는 간단한 메서드만 활용해서 필요한 값만 직관적으로 뽑아 쓸 수 있다.

function provideServicePeriod(ordNo:number, loginDate:LocalDate) {
  // 복잡한 if-else 계산 로직은 클래스 안으로 캡슐화 했다.
  const period = new ServicePeriodCalculator(order, loginDate).calculate();
  updatePeriod(period, period,getSdate(), period.getEdate());
}

분리 결과

다음과 같은 장점이 생긴다.

  1. 전체 코드를 이해하기 쉬워짐
  2. 계산로직만 테스트 가능
  3. 계산 로직 리팩토링 수월해짐
profile
I'm going from failure to failure without losing enthusiasm

1개의 댓글

comment-user-thumbnail
2023년 5월 13일

sample mocking comment for api test

답글 달기