[JAVA / 자바] 함수형 프로그래밍
함수란,
어떠한 input(입력)을 받아서 output(출력)을 하는 것이라고 쉽게 표현해 볼 수 있다. 따라서 함수는 동사와 같은 역할을 하기 때문에 함수의 이름을 정할 때에도 동사의 형태로 네이밍 하는 것을 알 수 있다.
반면에 객체는,
어떠한 것에 대한 상태 및 관련된 동작에 대한 것을 표현한 것이다. 따라서, 객체의 이름을 정할 때는 명사 형태로 네이밍을 한다는 것을 확인해 볼 수 있을 것이다.
함수와 객체에 대한 차이를 서두에서 다룬 이유는 바로 우리가 흔히 알고 있는 객체지향 프로그래밍(OOP, Objected Oriented Programming)과의 비교를 통해서 함수형 프로그래밍(Functional Programming)을 설명하기 위해서이다.
객체지향 프로그래밍(이후 OOP)에서는 명령형 프로그래밍(Imperative Programming)의 일종으로, 문제를 어떻게(How to do?) 해결해야 하는지에 초점을 맞추고 있는 반면에,
함수형 프로그래밍(이후 FP)은 선언형 프로그래밍(Declarative Programming)의 일종으로 문제를 해결하기 위해 무엇을(What to do?) 해야 하는지에 대해 초점을 맞추고 있다.
따라서, 다음과 같은 문제 예시가 주어졌을 때 OOP와 FP는 각각 다음과 같은 과정을 통해 문제를 해결하려 할 것이다.
[ 문제 상황 ]
유저 리스트가 주어졌을 때, 검증되지 않은 유저들의 이메일을 리스트로 반환하여라.
[ 해결 과정 ]
OOP | FP |
1. 검증되지 않은 이메일을 담을 리스트 선언 2. 유저 리스트 순회 3. 유저 객체 선언 4. 이메일 검증 여부 확인 5. 검증되지 않은 이메일 추출 6. 검증되지 않은 이메일 리스트에 추가 |
1. 유저 리스트에서 1. 검증되지 않은 유저 선별 2. 선별된 유저의 이메일 추출 2. 1-2결과를 리스트로 받기 |
지금까지 OOP와 비교해서 FP를 설명해 보았다. 이제는 OOP와 비교하지 않고 FP의 특징에 대해서 설명을 해보려 한다.
FP에서 함수를 '1급 시민'으로 취급하고 있다. 이때 말하는 '1급 시민'이란 다음과 같은 조건을 만족하는 것을 의미한다.
- 함수/메서드의 매개변수(parameter)로서 전달할 수 있는가?
- 함수/메서드의 반환값(return)이 될 수 있는가?
- 변수에 담을 수 있는가?
평소 OOP에만 익숙한 사람들에게 함수를 매개변수로 전달하고 반환하고 변수에 담는다는 표현이 낯설게 또는 불가능하다고 느껴질 것이다. 그러나, 함수를 오브젝트의 형태로 나타낼 수 있다면 위 조건을 만족시키는 1급 시민의 자격을 갖출 수 있다.
자바에서는 Java 8 이후부터 함수/메서드를 오브젝트 형태로 표현할 수 있도록 지원하고 있다.
[ 이 공간에 함수/메서드를 오브젝트 형태로 표현하는 방법에 관한 게시글을 첨부할 예정입니다. ]
(Lambda Expression)
(Functional Interface)
(Method Reference)
(Stream)
(Optional)
etc...
우리가 FP를 할 수 있게 된다면,
1. 역할에 충실한 코드를 작성할 수 있게 된다.
코드가 각 역할을 수행하는 함수들로 구성된다면 가독성이 향상되고, 유지/보수에 용이해지며, 버그로부터 안전해진다. 이후 코드 확장 시에도 역할에 따라 함수만 수정 및 추가해 주면 되기 때문에 확장성이 좋아지게 된다.
2. 패러다임의 전환을 맞게 된다.
Java에서 FP를 이용한 여러 툴들(Stream, Optional, etc..)을 사용해서 굉장히 깔끔하고 간결한 코드를 작성할 수 있게 된다.
Java는 OOP에 특화된 언어임에는 틀림없다. 그렇기 때문에 FP가 Java에 어울리지 않다고 생각하는 사람도 있을 것이라 생각이 된다. 그러나, 문제를 해결하는 측면에서 바라봤을 때 분명 FP가 OOP로 작성한 코드보다 훨씬 간결하고 깔끔할 때가 더러 있을 것이다. 이 말은 무조건 OOP 또는 FP하나만 고집하기보다는 상황에 따라 알맞게 사용한다면 OOP만 고집했을 때 보다 더 품질이 좋은 코드를 작성할 수 있게 될 것이다.