본문 바로가기
Concepts/SW Architecture

프로그래밍 패러다임 - 함수형 프로그래밍

by ocwokocw 2021. 2. 10.

- 이 글은 로버트 C.마틴의 Clean Architecture를 기반으로 작성되었습니다. (가능하면 책을 읽어보는것을 추천한다.)

- 예제

함수형 프로그래밍은 예제를 살펴보는것이 이해하기가 수월하다. 0~24 까지 제곱을 출력하는 프로그램을 작성해보자. Java 1.8 이전까지는 아래처럼 코드를 작성하였다.

 

public static void main(String[] args){

	for(int i = 0; i < 25; i += 1) {
		System.out.println(i*i);
	}
	
}

 

하지만 Java 1.8 부터는 람다(익명함수)를 지원하면서 아래와 같이 코드를 작성할수도 있다.

 

public static void main(String[] args){
	
	IntStream.range(0, 25)
		.map(x -> x*x)
		.forEach(x -> System.out.println(x));
	
}

 

i 를 사용한 반복문에서 for loop 내에 i 에 값을 할당하면 뒤의 for loop가 영향을 받지만, 람다를 이용한 코드에서 map 함수 내의 x에 값을 할당하더라도 뒤의 loop 에서는 영향이 없다. 물론 진정한 함수형 프로그래밍이라면 인자에 대해 값이 변경되면 안되고, 같은 인자에 대해 항상 동일출력을 보장해야 한다. 

 

이런 사실과 아키텍처가 관련이 있는가? 거창한 이유라기 보다는 경합 조건, 교착상태, 동시 업데이트 문제가 가변 변수로 인해 발생하므로 불변성이 보장된다면 해당 문제가 발생되지 않는다. 변할 수 있는 부분에 대한 가변 컴포넌트와 변하지 않는 불변 컴포넌트를 분리 해야 한다.


- 이벤트 소싱

계좌 잔고를 관리하는 은행 어플리케이션이 있다. 입금 및 출금 트랜잭션이 일어나면 잔고가 변한다.  만약에 이렇게 트랜잭션 동작 후 잔고가 변하는 대신 트랜잭션 동작 자체를 저장한다고 가정해보자. 사용자가 잔고를 조회할 때 최초 잔고부터 현재까지 모든 트랜잭션을 반영하여 계산하면 현재 잔고가 된다.

 

당연히 이런 발상은 컴퓨팅 자원을 고려할 때 말도 안되는 발상이지만 매일 특정시점 기준으로 계좌 잔고를 계산하여 일종의 값을 캐싱할수도 있을것이다. 이런 아이디어가 이벤트 소싱의 기본 발상이다. 이런 사상 입각하에서 애플리케이션은 CRUD가 아니라 CR만 수행하며, 변경과 삭제가 없으므로 동시 업데이트 문제가 일어나지 않는다.


- 결론

여태까지 구조적, 객체지향, 함수형 패러다임을 살펴보았다. 각 패러다임은 아래와 같이 규칙을 제한한다.

 

구조적 프로그래밍 - 제어흐름의 직접적인 전환(ex - goto)을 제한한다.

객체 지향 프로그래밍 - 제어흐름의 간접적인 전환을 제한한다.

함수형 프로그래밍 - 변수 할당을 제한한다.

댓글