#10장 람다를 이용한 도메인 전용 언어
Raoul-Gabriel Urma 저, 우정은 역 「Modern Java in Action, 2019」를 읽고 정리하였습니다.
10장 요약
DSL은 개발자와 도메인 전문가 사이의 간격을 좁힌다.
DSL은 외부적 또는 내부적 DSL 나눠진다.
JVM에서 이용가능한 스칼라, 그루비 언어도 다중 DSL 을 개발할 수 있다. 이 언어들은 자바보다 유연하지만, 자바와 통합하려면 빌드과정이 복잡해진다.
자바의 장황함과 문법적 엄격함으로 DSL을 개발하는 언어로 보통 적합하지 않지만, (자바 8) 람다식 메서드 참조와 같은 도입덕분에 개선되었다.
자바는 자체 API에 작은 DSL을 제공한다. 이는 특히 컬렉션 데이터의 정렬, 필터링, 변환, 그룹화에 유용하다.
자바로 DSL 구현시, 3가지 패턴 (메서드체인, 중첨함수, 함수시퀀싱)이 사용된다.
많은 자바 프레임워크와 라이브러리를 DSL을 통해 이용할 수 있다. jOOQ (SQL 매핑 도구), BDD 프레임워크 Cucumber, 엔터프라이즈 통합 패턴을 구현한 Spring Integration을 살펴봤다.
다룰 내용
DSL (도메인 전용 언어)란?
DSL을 API에 추가시 장단점
JVM에서 활용할 수 있는 자바 기반 DSL을 깔끔하게 만드는 대안
최신 자바 interface와 class에 적용된 DSL에 대한 배움
효과적인 자바 기반 DSL을 구현하는 패턴과 기법
이들 패턴을 자바 라이브러리와 도구에서 얼마나 자주 사용되는지 확인
10.1 도메인 전용 언어
DSL의 장점
간결함 : API는 비즈니스 로직을 간편하게 캡슐화하므로 반복을 피할 수 있고 코드를 간결하게 만들 수 있다.
가독성 : 도메인 영역의 용어를 사용하므로 비 도메인 전문가도 코드를 쉽게 이해할 수 있다. 결과적으로 다양한 조직 구성원 간에 코드와 도메인 영역이 공유될 수 있다.
유지보수 : 잘 설계된 DSL로 구현한 코드는 쉽게 유지 보수하고 바꿀 수 있다.
높은 수준의 추상화 : DSL은 도메인과 같은 추상화 수준에서 동작하므로 도메인의 문제와 직접적으로 관련되지 않은 세부 사항을 숨긴다.
집중 : 비즈니스 도메인의 규칙을 표현할 목적으로 설계된 언어이므로 프로그래머가 특정 코드에 집중할 수 있다. 결과적으로 생산성이 좋아진다.
관심사 분리 : 지정된 언어로 비즈니스 로직을 표현함으로 애플리케이션의 인프라구조와 관련된 문제와 독립적으로 비즈니스 관련된 코드에서 집중하기가 용이하다.
DSL의 단점
DSL 설계의 어려움 : 간결하게 제한적인 언어에 도메인 지식을 담는 것이 쉬운 작업은 아니다.
개발 비용 : 코드에 DSL을 추가하는 작업은 초기 프로젝트에 많은 비용과 시간이 소모된다. 또한 DSL 유지보수와 변경은 프로젝트에 부담을 주는 요소다.
추가 우회 계층 : DSL은 추가적인 계층으로 도메인 모델을 감싸며 이때 계층을 최대한 작게 만들어 성능 문제를 회피한다.
새로 배워야 하는 언어 : DSL을 프로젝트에 추가하면서 팀이 배워야 하는 언어가 한 개 더 늘어난다는 부담이 있다.
호스팅 언어 한계 : 일부 자바 같은 범용 프로그래밍 언어는 장황하고 엄격한 문법을 가졌다. 이런 언어로는 사용자 친화적 DSL을 만들기가 힘들다.
DSL의 카테고리: 내부 DSL, 외부 DSL, 다중 DSL
내부는 순수 자바 코드 같은 기존 호스팅 언어를 기반하고 외부는 독립적으로 자체의 문법을 가진다.
다중 DSL는 JVM 특성에 의해 생겨났다.
내부 DSL
다중 DSL
장점
같은 자바 바이트코드를 사용하는 JVM 기반 프로그래밍 언어를 이용하여 DSL을 만들 수 있다.
문법적 잡음이 없으며 개발자가 아닌 사람도 코드를 쉽게 이해할 수 있다.
자바 언어가 가지는 한계를 넘을 수 있다 (스칼라 - 커링, 임의 변환 등 DSL 개발에 필요한 여러 특성을 갖춤)
단점
누군가가 해당 언어에 대해 고급 기술을 사용할 수 있을 정도의 충분한 지식을 가지고 있어야 한다.
두 개 이상의 언어가 혼재하므로 여러 컴파일러로 소스를 빌드하도록 빌드 과정을 개선해야 한다.
호환성 문제를 고려해야한다
외부 DSL
자신만의 문법과 구문으로 새로운 언어를 설계해야 한다는 단점
우리에게 필요한 특성을 완벽하게 제공하는 언어를 설계할 수 있다는 장
JVM에서 실행되는 언어는 100개가 넘는다. (스칼라, 그루비 포함)
10.2 최신 자바 API의 작은 DSL
자바의 새로운 기능의 장점을 적용한 첫 API는 네이티브 자바 API 자신이다.
람다 표현식과 메소드 참조를 이용해 DSL의 가독성, 재사용성, 결합성이 높아졌다.
스트림 API는 컬렉션을 조작하는 DSL
Stream 인터페이스는 네이티브 자바 API에 작은 내부 DSL을 적용한 좋은 예시
스트림 API의 fluent style인 메서드 체인은 잘 설계된 DSL의 또 다른 특징
데이터를 수집하는 DSL인 Collectors
10.3 자바로 DSL을 만드는 패턴과 기법
메서드 체인: 플루언트 스타일의 메서드 체인을 이용하여 DSL을 만든다.
DSL 가독성을 개선. 노이즈 최소화.
중첩된 함수 이용: 다른 함수 안에 함수를 이용해 도메인 모델을 만든다.
메서드 체인에 비해 함수의 중첩 방식이 도메인 객체 계층 구조에 그대로 반영된다.
람다 표현식을 이용한 함수 시퀀싱
위 3개 조합하기
DSL에 메서드 참조 사용하기
10.4 실생활의 자바8 DSL
jOOQ(java Object Oriented Querying): SQL을 구현하는 내부적 DSL, 자바에 직접 내장된 형식 안전 언어
Cucumber: 동작 주도 개발(BDD, Behavior-driven development) 프레임워크
Spring Integration: 엔터프라이즈 통합패턴을 지원할 수 있도록 의존성 주입에 기반한 스프링 프로그래밍 모델을 확장
Last updated