함수형 인터페이스란?
함수형 인터페이스란, 단 하나의 추상 메서드를 포함하고 있는 인터페이스를 의미한다.
때문에 Single Abstract Method (SAM) 이라고 불리기도 한다.
추가적으로 static 메서드나 default 메서드가 포함되어 있어도 단 하나의 추상 메서드만 가지고 있다면 함수형 인터페이스라고 할 수 있다.
함수형 인터페이스와 람다표현식
자바8 이전에는 익명 내부클래스를 활용해 함수형 인터페이스를 사용했다.
자바8 이후 람다식을 활용해 위와 같이 보다 간결하게 작성할 수 있다.
@FunctionalInterface 애너테이션
@FunctionalInterface
애너테이션을 통해 해당 인터페이스가 함수형 인터페이스가 아닌 경우 컴파일 에러를 통해 함수형 인터페이스인지 확인할 수 있다.
전략 패턴이란?
전략 패턴 또는 정책 패턴은 프로그램 실행 중 알고리즘을 선택할 수 있게 하는 행위의 소프트웨어 디자인 패턴이다.
간단히 말해서 특정 컨텍스트에서 알고리즘을 별도로 분리하여 설계하는 방법을 의미한다.
전략 패턴의 적용
전략 패턴 적용 전
랜덤한 숫자를 반환하는 RandomGenerator
를 통해 4 이상의 숫자가 나온다면 이동하는 Car
클래스를 만든다고 가정해보자.
위와 같은 형식으로 코드를 작성한다면 Car
객체는 본인의 이름, 위치, 이동 전략 까지 모두 알고 있어야 한다.
뿐만 아니라 Car
객체의 move()
메서드를 테스트하기도 상당히 어렵다는 부분을 알 수 있다.
전략 패턴 적용 후
이번엔 전략 패턴을 적용하여 Car
객체의 이동 전략
을 작성해보자.
위와 같이 함수형 인터페이스를 통해 이동 전략
을 구현한다면 아래와 같은 이점들을 가질 수 있다.
- 새로운
이동 전략
에 대한 유연한 대처가 가능해진다. Car
객체가이동 조건
에 대한 책임을 갖지 않아도 된다.Car
의 이동 여부를 테스트하기 편해진다.
예를 들어 랜덤하게 생성된 숫자를 기반으로 한 이동이 아니라 “MOVE” 라는 문자열을 입력받고 이동해야 한다는 요구 사항이 추가된다면 기존 설계의 경우 상당히 많은 부분을 고쳐야 한다.
하지만 전략 패턴을 채용함으로써 StringMovingStrategy
와 같은 새로운 전략 패턴을 추가하여 컨텍스트인 Car
객체 내부의 코드는 수정하지 않고 클라이언트인 GameController
에서 주입하는 전략 패턴을 변경하여 보다 유연하게 변경에 대해 대처할 수 있다.
테스트 코드도 마찬가지로 Car
객체 내부에 변경이 없으니 테스트 코드 역시 변경하지 않아도 컨텍스트인 Car
객체를 정상적으로 테스트할 수 있고 보다 간단한 테스트를 작성할 수 있다.
여기서 짚고 넘어가야 하는 부분은 기존 방식으로 Car
객체를 설계 했다면 새로운 요구 사항이 주어졌을 때 Car
객체의 내부의 수정이 불가피했겠지만 전략 패턴을 채택함으로써 컨텍스트인 Car
객체의 내부를 수정할 필요 없이 전략 패턴을 구현한 새로운 클래스를 추가함으로써 변경된 요구 사항에 유연하게 대처할 수 있다는 점에 있다.
전략 패턴 적용 시점
if-else
문을 사용하고 조건이 추가될 수 있는 로직이라면 전략 패턴을 활용해 컨텍스트의 변경을 방지할 수 있다.
또한, 비슷한 계열의 알고리즘을 상호 교체해야 하는 경우에도 전략 패턴을 활용해 때에 따라 같은 계열의 다른 알고리즘을 적용할 수 있다.