Post
EN

Java 함수형 프로그래밍 기초

Java 8부터 함수형 인터페이스 (Functional Interface)를 제공하면서, 함수형 프로그래밍을 지원하게 되었다.

​

함수형 프로그래밍을 사용하면 확장성에 좋고, 함수로서 단일 기능을 강조, 함수를 조합 할 수 있다.

​

개인적인 함수형 프로그래밍의 기초는 다음과 같다.

​

1. 함수는 입력과 출력을 가지고 있다.

간단하게 input이 있으면 output이 있다는 것이다.

y = f(x)

​

2. 함수는 합성이 가능하다.

두개의 함수를 합성하여, 위에서 말했던 입력과 출력을 표현할 수 있다.

y = g(f(x))

​

3. 확장성에 용이하다. (변화에 영향을 크게 받지 않는다.)

작성된 함수형 프로그래밍에 추가적인 계산이 필요하면, 함수를 추가 하면 된다.

​

단순하게 생각하면 함수란 입력이 있으면 출력이 있다.

어떤 연산을 할 경우 일정한 순서가 존재한다.

​

예를 들어보자.

  1. 1줄의 텍스트 데이터를 받는다.

  2. 라인 데이터를 Tab으로 구분하여 나눈다.

  3. 나눠진 텍스트들을 원하는 객체에 맵핑 시킨다.

​

3가지 작업을 하기 위하여 위에서 말했던 함수로 작성하면 아래처럼 정리된다.

1. 1줄의 텍스트 데이터를 받아 tab으로 구분하여 나눈다. Input -> String Output -> String[] 2. 나눠진 택스트를 내가 원하는 객체에 맵핑 시킨다. Input -> String[] Output -> Object

정리된 함수를 가지고 클래스를 작성하면 단순하게 우리가 나타낼 수 있는 함수 형태가 된다.

​

class SplitFunction implements Function { @Override public String[] apply(String text) { if (text == null) return null; return text.split('\\t'); } } class MappingFunction implements Function { @Override public Object apply(String[] values) { return new Object(values); } }

이 두개의 인터페이스를 사용하는 클래스를 작성한다.

class Parser { private SplitFunction splitFunction; private MappingFunction mappingFunction; // 생성자로 각 함수 주입 public Object createObject(String text) { return mappingFunction.apply(splitFunction.apply(text)); } }

Parser 라는 클래스는 2개의 함수를 이용하여 1줄의 텍스트 데이터를 받아 tab으로 구분하여 나누고, 나눠진 택스트를 내가 원하는 객체에 맵핑 시킬 수 있다.

​

​

이런 상황에서 객체 안의 데이터들 중 다음과 같이 추가적인 계산을 하는 식이 추가되었다고 하면 어떻게 될까?

3. 생성된 객체의 가격 정보를 가져와서 계산식으로 값을 계산한다. Input -> Object Output -> Object (or void) 환율 계산식 Input -> Float Output -> Integer

Parser Class에 추가적으로 계산하는 공식을 추가하여 합성하면 문제는 해결된다.

// 환율 계산 적용 식 class CalculateFunction, Object> implements Function, Object> { @Override public Object apply(Object object, Function exchangeFunction) { object.setPrice(fnc.apply(object.getPrice())); return object; } } // 환율 계산 식 class ExchangeFunction implements Function { @Override public Integer apply(Float float) { return (int) float * 1174; // 당일 환율 계산 } }

(CalculateFunction은 인자가 3개를 받는 TriFuntion 이다. 가운데 들어오는 함수는 계산 하는 식에 대한 확장성을 생각하여 추가한 것이다.)

​

위와 같이 CalculateFunction을 만들어졌다. 이것을 가지고 기존에 있던 계산식에 넣어보자.

class Parser { private SplitFunction splitFunction; private MappingFunction mappingFunction; private CalculateFunction calculateFunction; private ExchangeFunction exchangeFunction; // 생성자로 각 함수 주입 public Object createObject(String text) { return calculateFunction.apply(mappingFunction.apply(splitFunction.apply(text)), exchangeFunction); } }

(apply 외에도 compose 사용할 수 있다.)

Parser class에 1개의 펑션이 더 추가되었고, 추가된 함수는 기존 함수에 합성하여 수정된 결과를 얻어온다.

작성된 코드를 확인 했을 때 변화가 크지 않다.

그리고 함수 계산식들은 상황에 따라 변경할 수 있다.

​

위에서 이야기 했던 1,2,3에 해당되는 내용대로 코드가 작성이 가능해졌고, 앞에서 설명한 내용 처럼 일정한 순서대로 작성되는 코드로 만들었다.

​

특정 복잡한 로직에 변화가 많이 발생되는 곳이 있다면, 이러한 장점을 이용하여 코드를 작성하면 변경에도 효율적일 것 같다.

​

This article is licensed under CC BY 4.0 by the author.