불법 상태와 원치 않는 상태, 시스템 설계의 핵심 딜레마!

by DD
1개월 전
조회수 0

불법 상태(Illegal State)는 시스템에서 절대 발생해서는 안 되는 상태를 의미하며, 원치 않는 상태(Unwanted State)는 시스템이 벗어나야 하는 상태를 지칭함.

파싱(Parsing) 시 잘못된 입력 처리와 컴파일러(Compiler)의 오류 메시지 생성 과정에서 이러한 상태 구분이 중요하게 작용함.

Postel의 법칙Hyrum의 법칙을 통해 유연한 입력 처리와 엄격한 출력 보장의 트레이드오프(Trade-off)를 설명하며, Liskov의 하위 유형화 원칙과의 연관성을 제시함.

사용자 입력 오류, 외부 서비스의 결함, 네트워크 분할(Network Partition) 등 다양한 원인으로 인해 원치 않는 상태가 발생하며, 이를 적절히 처리하는 것이 중요함.

파싱(Parsing) 시나리오에서의 불법/원치 않는 상태

논의에서는 파싱 시 정수(Integer)를 부호 없는(Unsigned) 형태로 처리하는 경우, 음수 입력에 대한 오류를 적절히 처리하기 어렵다는 점을 지적한다. 컴파일러(Compiler)는 오류 메시지 생성을 위해 불법적인 구문을 표현해야 하며, 이는 시스템 설계의 복잡성을 증가시킨다. 특히, 프로토타입(Prototype)에서 실제 제품으로 전환하는 과정에서 상태 표현(State Representation)의 문제로 인해 어려움이 발생할 수 있다. 따라서, 처음부터 더 완벽한 상태 머신(State Machine)을 고려하는 것이 더 효율적일 수 있다.

Postel의 법칙, Hyrum의 법칙, Liskov의 하위 유형화

토론에서는 Postel의 법칙Hyrum의 법칙이 시스템 설계에 미치는 영향을 분석한다. Postel의 법칙은 입력에 관대하고 출력에 엄격해야 함을 강조하며, Liskov의 하위 유형화(Liskov Subtyping) 원칙을 통해 이를 설명한다. 하지만, Hyrum의 법칙은 출력의 엄격함이 예상치 못한 부작용을 초래할 수 있음을 지적한다. 즉, 사전 조건(Precondition)을 완화하고 사후 조건(Postcondition)을 강화하는 과정에서, 우연히 참인 조건이 깨질 수 있다.

원치 않는 상태의 다양한 원인과 처리

커뮤니티에서는 원치 않는 상태(Unwanted State)가 내부 버그, 외부 서비스의 결함, 사용자 오류 등 다양한 원인으로 발생한다고 언급한다. 특히, RPC(Remote Procedure Call)를 처리하는 과정에서 발생하는 문제점을 예시로 들며, 내부 버그와 사용자 오류를 구분하여 처리하는 전략을 제시한다. 예를 들어, 내부 버그는 요청의 일부를 무효화하고 계속 진행하며, 사용자 오류는 요청을 완전히 실패시킬 수 있다. 또한, 데이터 미저장 정책(Zero-Retention Policy)을 통해 이러한 문제를 해결할 수 있다.

UI 디자인에서의 불법/원치 않는 상태

UI 디자인 관점에서, 합계 타입(Sum Type)을 사용하는 API에 대한 폼(Form)은 제품 타입(Product Type)을 사용하여 UI 상태를 관리해야 한다고 주장한다. 예를 들어, API는 엄격한 구조를 가질 수 있지만, UI는 텍스트 박스(Textbox)의 상태를 유지하기 위해 제품 타입을 사용해야 한다. 이는 엘름(Elm)Evan Czaplicki의 강연에서 영감을 얻은 것으로, UI의 유연성을 확보하면서도 API의 안정성을 유지하는 방법을 제시한다.

기능적 코어, 명령형 쉘 아키텍처

토론에서는 기능적 코어, 명령형 쉘(Functional Core, Imperative Shell) 아키텍처를 통해 불법 상태를 처리하는 방법을 제시한다. 이 아키텍처는 원치 않는 상태를 표현할 수 있는 유연한 타입을, 불법 상태를 표현하는 엄격한 타입으로 변환한다. 만약 두 타입 간의 구조적 차이가 없다면, 팬텀 타입(Phantom Types)을 사용하여 유효성 검사를 수행할 수 있다. 또한, 예외(Exception)는 불법 상태를 표현하는 또 다른 방법으로, 오류가 발생할 수 있는 지점에서 명시적으로 처리할 수 있다.

Illegal vs Unwanted States