본문으로 건너뛰기

02 현실에서의 함수형 사고

이번 장에서 살펴볼 내용
  • 현실적인 문제에 함수형 사고를 적용해 봅시다.
  • 소프트웨어 구조를 잡는 데 계층형 설계가 좋은 이유를 설명합니다.
  • 액션을 타임라인으로 시각화해 봅니다.
  • 타임라인을 사용하면 시간에 관한 문제를 잘 풀 수 있다는 것을 배웁니다.

토니 피자에 오신 것을 환영합니다

피자 가게를 운영하는 토니는 로봇에 함수형 사고를 많이 사용했습니다. 다음은 토니가 적용한 것입니다.

파트 1: 액션과 계산, 데이터

토니는 요리 재료와 기타 필요 자원을 사용하는 코드를 액션으로 구분하고 나머지 코드는 계산으로 구분했습니다.

파트 2: 일급 추상

가게 주방에는 많은 로봇이 함께 피자를 만들고 있습니다. 이것은 분산 시스템이라고 할 수 있습니다.

파트 1: 액션과 계산, 데이터

토니는 함수형 사고 중에 가장 먼저 액션과 계산, 데이터를 구분하는 것부터 시작했습니다. 함수형 프로그래머는 코드에서 가장 먼저 이 세가지를 구분하는데 쉽게 다룰 수 있는 부분과 조심히 다뤄야 할 부분을 명확하게 하기 위함입니다.

1. 액션

액션은 호출 횟수와 시점에 의존하는 것입니다. 오븐이나 배달차 같은 자원과 요리 재료를 사용하는 것은 액션입니다. 액션은 사용할 때 조심해야 합니다.

2. 계산

어떤 것을 결정하거나 계획하는 것은 계산입니다. 계산은 실행해도 다른 곳에 영향을 주지 않습니다. 계산은 아무 때나 사용해도 주방이 엉망진창 될 걱정이 없기 때문에 토니는 계산을 좋아합니다.

3. 데이터

토니는 변경 불가능한 데이터를 가능한 많이 쓰려고 합니다. 결제, 재고, 피자 조리법 같은 것이 데이터입니다.

변경 가능성에 따라 코드 나누기

계층화 설계 맛보기

함수형 사고로 코드를 구성하면 코드를 변경할 때 드는 비용이 줄어듭니다.

먼저 변경 가능성에 따라 코드를 나눠 봅시다. 위쪽으로 갈수록 자주 바뀌는 코드가 있고 아래쪽으로 갈수록 자주 바뀌지 않는 코드가 있는 그림을 그려봅시다.

img

각 계층은 그 아래에 있는 계층을 기반으로 만들어 집니다. 그래서 각 계층에 있는 코드는 더 안정적인 기반 위에 작성할 수 있습니다. 이런 구조로 소프트웨어를 만들면 코드를 쉽게 바꿀 수 있습니다. 아래에 있는 코드들은 위에 있는 코드보다 의존성이 많아 바꾸기 어렵지만 자주 바뀌지 않습니다.

함수형 프로그래머는 이 아키텍처 패턴이 계층을 만들기 때문에 계층형 설계라고 부릅니다. 계층형 설계는 일반적으로 비즈니스 규칙, 도메인 규칙, 기술 스택 계층으로 나눕니다.

계층형 설계로 만든 코드는 테스트, 재사용, 유지보수가 쉽습니다.

파트 2: 일급 추상

주방을 자동화하기

주방에는 로봇이 혼자 일하고 있었기 때문에 얼마 지나지 않아 확장성 문제가 생겼습니다. 토니는 고객이 원하는 속도로 피자를 만들 수 없습니다. 다음 타임라인 다이어그램은 로봇 한 대가 피자를 만들기 위한 액션들을 보여줍니다.

img

타임라인 다이어그램을 사용하면 액션이 시간 순서에 따라 어떻게 실행되는지 볼 수 있습니다. 액션은 실행 시점에 의존하기 때문에 실행 순서가 중요하다는 것을 잊지 마세요.

분산 시스템을 타임라인으로 시각화하기

여러 대의 로봇이 함께 일을 하는 것은 분산 시스템을 의미합니다. 분산 시스템에서 독립된 액션의 실행 순서는 어떻게 될지 모릅니다. 각각의 타임라인에서 처리되는 일은 순서가 섞여 누가 먼저 끝날지 알 수 없습니다.

각각의 타임라인은 다른 순서로 실행됩니다.

기본적으로 타임라인은 서로 순서를 맞출 수 있는 기능이 없습니다. 다른 타임라인 작업이 끝날 때까지 기다리라는 표시가 없어서 순서대로 다음 단계를 그냥 진행합니다. 서로 다른 타임라인에 있는 액션 간 실행 순서는 보장할 수 없습니다.

타임라인을 서로 맞추지 않은 분산 시스템은 예측 불가능한 순서로 실행됩니다. 로봇들이 반죽, 치즈, 소스 준비가 끝나면 피자를 만들도록 해야 합니다.

어려운 경험을 통해 분산 시스템에 대해 배운 것

순차적인 프로그램을 분산 시스템으로 바꾸는 것은 어렵다는 것을 알았습니다.

올바른 순서로 동작하는 프로그램을 만들려면 액션(시간에 의존적인)에 집중할 필요가 있다는 것도 알았습니다.

1. 기본적으로 타임라인은 서로 순서를 맞추지 않습니다.

반죽이 준비되지 않았는데도 다른 타임라인은 그냥 진행되었습니다. 타임라인은 순서를 맞춰야 합니다.

2. 액션이 실행되는 시간은 중요하지 않습니다.

일반적으로 소스 만드는 것이 제일 오래 걸리는 작업이지만 항상 그렇지는 않습니다. 그래서 각각의 타임라인의 순서와 관계없이 만들어야 합니다.

3. 드물지만 타이밍이 어긋나는 경우는 실제 일어납니다.

테스트할 때는 문제가 없었지만 실제 서비스에서는 문제가 생겼습니다. 저녁에 주문이 많이 들어오자 가끔 발생하는 오류는 더 많이 발생했습니다. 타임라인은 항상 올바른 결과를 보장해야 합니다.

4. 타임라인 다이어그램으로 시스템의 문제를 알 수 있습니다.

다이어그램을 보고 치즈가 제시간에 준비되지 않을 수 있다는 것을 알았습니다.

타임라인 커팅: 로봇이 서로를 기다릴 수 있게 하기

타임라인 커팅은 여러 타임라인이 동시에 진행될 때 서로 순서를 맞추는 방법입니다.

타임라인 커팅은 고차 동작으로 구현합니다. 각 타임라인은 독립적으로 동작하고 작업이 완료되면 다른 타임라인 끝나기를 기다리기 때문에 어떤 타임라인이 먼저 끝나도 괜찮습니다.

img

이렇게 타임라인의 시간을 맞추는 작업을 커팅(cutting) 이라고 부릅니다.

좋은 경험을 통해 타임라인에 대해 배운 것

  • 컷이 있으면 점선 아래에 있는 것은 점선 위에 있는 것이 끝나야 실행할 수 있습니다.
  • 컷이 있기 때문에 재료 준비하는 작업들의 실행 순서를 신경 쓰지 않고 피자 만드는 나머지 작업을 할 수 있습니다.

1. 타임라인 커팅으로 서로 다른 작업들을 쉽게 이해할 수 있습니다.

타임라인 컷을 그려 동시에 할 수 있는 재료 준비와 순서대로 해야 하는 피자 만들기를 분리했습니다. 타임라인 커팅으로 더 짧아진 타임라인을 실행 순서에 상관없이 이해할 수 있습니다.

2. 타임라인 다이어그램을 사용하면 시간에 따라 진행하는 작업을 쉽게 이해할 수 있습니다.

토니는 타임라인 다이어그램을 이해했기 때문에 동작 방법에 대해 확신할 수 있었습니다.

타임라인은 동시에 실행되는 분산 시스템을 시각화하기 좋습니다.

3. 타임라인 다이어그램은 유연합니다.

타임라인을 보고 쉽게 코드로 옮길 수 있었습니다. 그리고 타임라인 다이어그램으로 동시에 진행되는 작업을 쉽게 모델링할 수 있습니다.

결론

토니는 유지보수 비용을 줄이기 위해 액션과 계산에 계층화 설계를 사용했습니다. 토니는 로봇 여러 대로 주방 효율을 높이고 시간에 따라 발생하는 어려운 버그도 고쳤습니다.

요점 정리

  • 액션과 계산 데이터를 구분하는 일은 함수형 프로그래머에게 가장 중요하고 첫 번째로 해야 하는 일입니다. 우리도 코드를 이런 식으로 구분하는 법을 배워야 합니다.
  • 함수형 프로그래머는 유지보수를 잘 하기 위해 계층형 설계를 사용합니다. 각 계층은 코드의 변경 가능성에 따라 나눕니다.
  • 타임라인 다이어그램은 시간에 따라 변하는 액션을 시각화하는 방법입니다.타임라인 다이어그램으로 액션이 다른 액션과 어떻게 연결되는지 볼 수 있습니다.
  • 액션 간 협력을 위해 타임라인 커팅이라는 기술을 살펴봤습니다. 타임라인 커팅은 액션이 올바른 순서로 실행할 수 있도록 보장해 줍니다.