반디북
쏙쏙 들어오는 함수형 코딩
Ch8
우석

계층형 설계 1

계층형 설계란?

  • 계층형 설계는 소프트웨어를 계층으로 구성하는 기술
  • 각 계층의 함수는 바로 아래 계층의 함수로 구성된다.
  • 다음과 같은 계층들이 생길 수 있다.
    • Layer 1: 비즈니스 규칙
    • Layer 2: 장바구니를 위한 동작들
    • Layer 3: 카피-온-라이트
    • Layer 4: 언어에서 지원하는 배열 관련 기능
  • 단, 각 계층을 나누는 절대적인 기준은 없다.

계층형 설계 패턴

  • 계층형 설계에는 크게 4가지 패턴이 존재한다.
    • 직접 구현: 함수 시그니처가 나타내는 문제를 함수 본문에서 적절한 구체화 수준으로 해결한다.
    • 추상화 벽: 호출 그래프에 특정 계층은 세부 구현은 감추고 인터페이스만 제공하여 고수준의 추상화 단계만 생각해도 되도록 돕는다.
    • 작은 인터페이스: 비즈니스 개념을 나타내는 중요한 인터페이스를 작고 강력하게 구성하려고 노력한다.
    • 편리한 계층: 각 계층은 비즈니스 문제를 잘 풀 수 있도록 구현해야 하고 도움이 될 때 시간을 투자해야 한다.

패턴 1: 직접 구현

  • 직접 구현 패턴은 함수의 구현부가 적절한 계층의 함수를 호출하여 해결할 수 있도록 구성하는 것
  • 상위 계층을 호출해서는 안 되고, 계층을 너무 많이 건너 뛰어 아래 계층을 호출하는 것도 지양해야 한다.
  • 그 이유는 계층을 올라갈 수록 여러 문제가 해결된 함수를 사용하여 해당 계층에서 고민하는 문제를 줄여 개발에 편리한 구조를 만들기 위함이라 이해했다.
  • 이를 위해서 같은 계층에 있는 함수는 같은 목적을 가져야 한다

function isInCart(cart, name) {
  for (var i = 0; i < cart.length; i++) {
    if (cart[i].name === name) {
      return true;
    }
  }
  
  return false;
}
 
function indexOfItem(cart, name) {
  for (var i = 0; i < cart.length; i++) {
    if (cart[i].name === name) {
      return i;
    }
  } 
  
  return null;
}
  • 위 2개의 메서드는 각기 다른 계층에 존재하는 메서드이다.
  • isInCart는 장바구니를 위한 동작들이 정의된 계층이고, indexOfItem은 일종의 배열의 기능을 제공하는 계층으로 isInCart가 더 높은 계층에 위치한다.
  • 하지만 위 구조를 보면 isInCart는 바로 아래 계층을 건너 뛰고 언어에서 지원하는 기능을 직접 호출하고 있다.

function isInCart(cart, name) {
  return indexOfItem(cart, name) !== null
}
  • 위와 같이 정의하면 계층들이 모두 바로 아래 계층을 호출하는 구조가 된다.
  • 또한 장바구니를 위한 동작인 isInCart를 구현하며 배열과 관련된 구현 로직을 고민하지 않아도 되기 때문에 개발 생산성이 더 높아질 것을 기대할 수 있다.

직접 구현 패턴의 장/단점 및 생각

  • 함수를 읽을 때 알아야 할 구체화 로직의 범위가 제한되기 때문에 가독성 측면에서 뛰어나다. (단, 바로 아래 계층의 인터페이스를 기준으로 로직을 파악하면 된다.)
  • 추가적인 도구로 호출 그래프를 활용하여 계층과 함수 관계를 쉽게 파악할 수 있고 계층 기준으로 파악하며 리팩토링의 단서를 찾을 수도 있다.
  • 직접 구현 패턴을 사용하면 더 일반적인 함수를 만들도록 노력하게 되고 이는 함수의 재사용성 측면에서 장점을 가질 수 있다.
  • 단, 계층 자체가 복잡성의 일부가 될 수 있을 것 같다. 업무에 적용해보기 위해서는 계층에 대한 정의와 프로젝트에 적용할 계층에 정의를 모두가 숙지하고 있어야 할 것 같다.
만혁

계층형 설계 1

계층형 설계란 무엇인가?

설계 감각을 키우기

전문가의 저주

전문가는 본인의 전문 분야를 잘 알지만, 설명은 잘 못하는 것으로 악명 높다

계층형 설계 감각을 키우기 위한 입력

계층형 설계 패턴

  1. 직접 구현
  • 너무 구체적이라면 코드에서 나는 냄새
  1. 추상화 벽
  • 인터페이스를 사용해 코드를 만들면 높은 차원으로 생각할 수 있다.
  • 고수준의 추상화 단계만 생각하면 되기 때문에 두뇌 용량의 한계를 극복할 수 있다.
  1. 작은 인터페이스
  • 중요한 인터페이스는 작고 강력한 동작으로 구성하는 것이 좋다.
  1. 편리한 계층
  • 코드와 코드가 속한 추상화 꼐층은 작업할때 편리해야 한다.

패턴 1 : 직접 구현

// as-is
function freeTieClip(cart) {
    // ...
    for(const i=0; i<cart.length; i++) {
        const item = cart[i];
        if (item.name === "tie") {
            hasTie = true;
        }
        if (item.name === "tie clip") {
            hasTieClip = true;
        }
    }
    // ...   
}
 
function isInCart(cart, name) {
    for (const i=0; i<cart.length; i++) {
        if (cart[i].name === name) {
            return true;
        }
    }
    return false;
}
 
// to-be
function freeTieClip(cart) {
    const hasTie = isInCart(cart, "tie");
    const hasTieClip = isInCart(cart, "tie cilp");
}