Functional Interface
Java로 코딩을 하다보면 Functional Interface를 자주 접할 수 있다. 안드로이드 앱개발을 해봤다면 버튼의 클릭 이벤트를 구현하는게 바로 Functional Interaface를 사용한 부분이다. 사실 본인이 개념적으로 Functional Interface를 사용하는지 모르고 사용하는 경우도 많다.(내가 그랬다) Predicate 인터페이스가 가장 대표적인 Functional Interface인데, 하나의 메소드만 가지고 있다는 것이 특징이다. 그러면 예시를 통해 Functional Interacer가 무엇인지 알아보도록 하자.
상황
개발자인 우리가 어부에게 수확량을 관리할 수 있는 프로그램을 만들어 준다고 가정하자. 데이터베이스에 물고기의 크기, 길이, 종류 등이 저장되어 있다. 어부는 올해 복어가 얼마나 잡혔는지, 갈치가 얼마나 잡혔는지, 혹은 길이가 20cm 이상인 물고기를 얼마나 잡았는 지 등 엄청난 경우의 수로 다양한 정보를 확인하고 싶어 한다.
경우의 수가 몇 가지 되지 않을 때는 경우 마다 메소드를 만들어서 filterFishBySpecies, filterFishBylength, ... 등으로 정의할 수 있다.
그런데 경우의 수가 매우 다양하다고 가정하면 filterFishBy@@@이라는 수 많은 메소드를 찍어내야 할 것이다.
어떻게 하면 코드의 중복을 최소화 시켜서 구현할 수 있을까? 이 때 바로 Functional Interface를 사용할 수 있다.
구현 예시
filterFish()라는 메소드를 만들고 파라미터로 필터링 할 리스트와 어떻게 필터링 할지 방법을 전달해준다. 그런데 위의 코드를 보면 메소드가 아니라 객체를 전달해주는 것을 확인할 수가 있다.
자바에서는 메소드를 직접 전달할 수 없기 때문에 메소드를 담기 위한 객체를 만들어서 전달해주게 되었다. 메소드를 담고 있는 객체는 결국 메소드를 전달하기 위해서 존재하기 때문에 1개의 메소드를 가진 인터페이스가 된 것이다. 프로그래밍에서 메소드 = 함수로 볼 수 있고 이 때문에 함수를 전달해주기 위한 인터페이스 -> Functional Interface가 사용된다.
사용 예시를 보면 new 키워드를 사용해서 객체를 생성하고 필터링할 방법(메소드)를 정의한다. 복잡해 보이지만 생각보다 간단하다. 메소드를 파라미터로 넘길 수 없는게 이 모든 문제의 원흉인데, 메소드가 1급 시민이 아니라는게 이렇게 서글플 수가 있을까 싶다.
글을 쓰면서 다시 봐도 헷갈리는데 이런 형태를 처음 접하면 이게 대체 뭐지라는 생각만 들고 공부하지 않으면 전혀 알 수 없는 구조다. 하지만 사실 위의 형태는 Functional Interface의 초기형태이다. 현재는 이렇게 사용하지 않아도 된다. Java에서도 이를 개선하기 위해 계속 변화하고 있다.
Java의 진화
Java 8에서부터는 위와 같이 알아먹기 어려운 구조가 아니라 Lambda나 Method Reference 방식을 지원해준다. 코드량도 훨씬 줄어들고 이해하기도 더 쉽다.
바로 아래 두 예시가 람다와 Method Reference 방식이다. 개인적으로 Lambda가 훨씬 이해하기 쉽다. Method Reference는 :: 이라는 문법을 사용하는데 꽤나 생소하고 저게 뭐지 싶은 생각도 들고 저게 어떻게 전달되는거지라는 의문이 든다.
반면에 Lambda는 다른 언어에서와 비슷하게 콜백함수 느낌으로 넘기기 때문에 이해가 더 쉽다. 약간의 차이는 있지만 어쨌거나 두 개의 경우 모두 기존의 객체를 만들어서 넘기는 방법보다는 훨씬 간결하고 이해하기 쉽다.
@FunctionalInterface의 실전 예시가 궁금하시다면 ->
https://today-devstart.tistory.com/29
'Java' 카테고리의 다른 글
Java - 람다란 무엇인가?(Lambda) (0) | 2022.08.21 |
---|---|
Java - Functional Interface의 예시 (모던 자바 인 액션 참고) (0) | 2022.08.20 |
Spring - @RestController와 @Controller의 차이 (0) | 2022.08.11 |
Java - Stream에 대해서 (0) | 2022.08.09 |
Java - Wrapper Class란 (0) | 2022.08.08 |