자바프로그램은 가변변수를 사용하는데,
가변 변수는 프로그램 실행중에 상태가 변할 수 있다.
반복문을 제어하는 변수인 i가 가변변수다.
하지만 클로저와 같은 함수형 프로그래밍 언어는
변수가 한번 초기화 되면 절대로 변하지 않는다.
불변성과 아키텍처
아키텍처를 고려할 때 이러한 내용이 왜 중요한가?
아키텍트는 왜 변수의 가변성을 염려하는가?
대답은 단순하다.
경합조건, 교착상태 조건, 동시업데이트 문제가 모두 가변변수로 인해 발생하기 때문이다.
어떠한 변수도 갱신되지 않는다면 경합조건이나 동시 업데이트 문제가 일어나지 않는다.
락이 가변적이지 않다면 교착상태도 일어나지 않는다.
다시말해 동시성 어플리케이션에서 마주치는 모든 문제,
즉 다수의 스레드와 프로세스를 사용하는 애플리케이션에서 마주치는 모든 문제는
가변 변수가 없다면 절대로 생기지 않는다.
아키텍트라면 동시성 문제에 지대한 관심을 가져야만 한다.
우리는 스레드와 프로세스가 여러개인 상황에서도 설계한 시스템이 여전히 강건하기를 바란다.
그러면 이제 불변성이 정말 실현가능한가?
저장공간이 무한하고 프로세서의 속도가 무한히 빠르다고 전제한다면,
이 질문에 대답은 대체로 긍정적으로 대답할 수 있다.
자원이 무한대가 아니라면 대답은 조금 미묘하다. 실형가능하지만 타협을 해야한다.
어떤 타협이 필요한가?
가변성의 분리
가장 주요한 타협중 하나는 애플리케이션, 또는 어플리케이션 내부의 서비스를
가변 컴포넌트와 불변 컴포넌트로 분리하는 일이다.
불변 컴포넌트에서는 순수하게 함수형 방식으로만 작업이 처리되며,
어떤 가변 변수도 사용되지 않는다.
불변 컴포넌트는 변수의 상태를 변경할 수 있는,
즉 순수 함수형 컴포넌트가 아닌 하나 이상의 다른 컴포넌트와 서로 통신한다.
상태변경은 컴포넌트를 갖가지 동시성 문제에 노출하는 꼴이므로,
흔히 트랜잭션 메모리와 같은 실천법을 사용하여 동시 업데이트와 경합조건 문제로 부터 가변 변수를 보호한다.
트랜젝션 메모리는 데이터 베이스가 디스크의 레코드를 다르는 방식과 동일한 방식으로 메모리의 변수를 처리한다.
즉 트랜잭션을 사용하거나 또는 재시도 기법을 통해..
말하려는 요지는, 애플리케이션을 제대로 구조화 하려면 변수를 변경하는 컴포넌트와 변경하지 않는 컴포넌트를 분리해야 한다는 것이다.
그리고 이렇게 분리하려면 가변 변수들을 보호하는 적절한 수단을 동원해 뒷받침 해야 한다.
현명한 아키텍트라면 가능한 많은 처리를 불변 컴포넌트로 옮겨야 하고,
가변 컴포넌트에서는 가능한 많은 코드를 빼야 한다.
이벤트 소싱
결과적으로 애플리 케이션은 CRUD가 아니라 그저 CR만 수행한다.
데이터 저장소에서 변경과 삭제가 전혀 발생하지 않으므로 동시 업데이트 문제 또한 일어나지 않는다.
저장공간과 처리 능력이 충분하면 애플리케이션이 완전한 불변성을 갖도록 만들 수 있고,
따라서 완전한 함수형으로 만들 수 있다.
소스코드 버전 관리 시스템이 정확히 이 방식으로 동작한다..