본문 바로가기

Reading Record/이펙티브 코틀린

[이펙티브 코틀린] Item 26. 함수 내부의 추상화 레벨을 통일하라

컴퓨터 과학에서의 추상화

  • 복잡한 자료, 모듈, 시스템 등으로부터 핵심적인 개념 또는 기능을 간추려 내는 것

추상화가 필요한 이유

  • 복잡성을 숨기고 사용되는 단순한 형식만 노출해 코드를 체계화하고 만드는 사람에게 변화의 자유를 주기 위해 추상화를 사용
  • 자동차의 경우 내부적으로는 매우 복잡한 요소들이 많지만 추상화된 핸들과 변속기 가속페달만으로 자동차를 운전할 수 있음 → 굉장히 추상화가 잘된 예시

추상화 레벨

  • 높은 레벨로 갈수록 물리 장치에서 멀어지고 프로그래밍에서는 일반적으로 높을 레벨일수록 프로세스와 멀어지고 관리해야하는 세부적인 내용이 적음
    • ex) C언어는 직접 메모리를 제어할 수 있지만 비교적 JVM 언어에 비해 복잡도가 높음

추상화 레벨 통일

  • 코드도 추상화를 계층처럼 만들어서 사용할 수 있는데, 이를 위한 기본적인 도구가 바로 함수
  • 함수도 높은 레벨과 낮은 레벨을 구분해서 사용해야 한다는 원칙이 있는데 이를 추상화 레벨 통일 (Single Level of Abstraction, SLA) 원칙 이라고 부름

CoffeeMachine 예시

Before

class CoffeeMachine {

    fun makeCoffee() {
        // 수백 개의 변수 선언
        // 복잡한 로직 처리
        // 낮은 수준의 최적화도 여기서 진행
    }
}
  • 하나의 메소드에 수많은 로직을 다 넣는 경우

After

class CoffeeMachine {

    fun makeCoffee() {
      boilWater()
      brewCoffee()
      pourCoffee()
      pourMilk()  
    }

    private fun boilWater() {
        //
    }
    
    private fun brewCoffee() {
        //
    }
    
    private fun pourCoffee() {
        //
    }
    
    private fun pourMilk() {}
    //
}
  • 위 코드에 비해 makeCoffee 동작하는 흐름을 빠르게 이해할 수 있음
  • 낮은 레벨을 이해해야하는 경우 해당 부분의 코드만 보면됨
  • 즉 함수는 작아야하고 최소한의 책임을 가져야만함

프로그램 아키텍처의 추상 레벨

  • 추상화 계층이라는 개념은 함수보다 높은 레벨에서도 적용할 수 있음
    • 높은 레벨 문제 중심
    • 낮은 레벨 문제 중심
    • 낮은 레벨 구현 구조
    • 프로그래밍 언어 구조와 도구
    • 운영 체제 연산과 머신 명령
  • 추상화를 구분하는 이유는 서브 시스템의 세부 사항을 숨김으로써 상호 운영성과 플랫폼 독립성을 얻기 위함이기 때문에 함수 뿐만이 아니라 모듈 시스템 설계할 때도 중요
    • ex) 입출력 모듈은 비즈니스 로직을 나타내는 모듈보다 낮은 레벨의 모듈

정리

  • 추상화 계층을 만듬으로써 서브 시스템의 세부 사항을 숨겨 상호 운영성과 플랫폼 독립성을 얻게 됨
  • 함수, 클래스, 모듈 등의 다양항 방식을 통해 추상화를 분리
  • 이때 각각의 레이어가 커지는 것은 좋지 않고 작고 최소한의 책임만 갖도록 하는 것이 좋음