Search
Duplicate
📒

[Java Study] 11-x. 람다를 이용한 도메인 전용 언어(DSL)

상태
미진행
수업
Java Study
주제
기본개념
4 more properties
참고

DSL(Domain-specific-Language, 도메인 전용 언어)

NOTE
DSL은 특정 비즈니스 도메인의 문제를 해결하려고 만든, 작은, 범용이 아닌 특정 도메인을 대상으로 만들어진 프로그래밍 언어다!
비즈니스 도메인
ex) 쇼핑몰 플랫폼을 개발한다 ⇒ 상품결제, 배송처리
DSL
특정 비즈니스 도메인을 인터페이스로 만든 API
대표적으로 SQL ⇒ DB에 데이터를 참조하기 위한 목적으로 만든언어!
자바8에서는 Stream, Collector등 여러 DSL이 추가되었다.

DSL 개발 필요성

1.
코드의 의도가 명확히 전달되어야 하며, 개발자가 아닌사람도 이해할 수 있어야하고, 요구사항에 부합하는지 확인해야 한다.
2.
가독성은 유지보수의 핵심이다.

DSL의 장점과 단점

NOTE
DSL은 만병통치약이 아니다, 잘못사용하면 독이 될 수 있다!

장점

간결함
도메인 영역의 용어를 사용하므로, 비 도메인 전문가도 쉽게 이해한다.
다양한 조직 구성원 간에 코드와 도메인 영역이 공유될 수 있다.
가독성
도메인 영역의 용어를 사용하므로 비 도메인 전문가도 코드를 쉽게 이해할 수 있다.
결과적으로 다양한 조직 구성원 간에 코드와 도메인 영역이 공유될 수 있다.
유지보수
잘 설계된 DSL로 구현한 코드는 쉽게 유지보수 할 수 있다.
높은 수준의 추상화
DSL은 도메인과 같은 추상화 수준에서 동작하므로 도메인의 문제와 직접적으로 관련되지 않은 세부사항을 숨긴다.

단점

DSL설계의 어려움
간결하게 제한적인 언어에 도메인 지식을 담는건 어렵다.
개발 비용
코드에 DSL을 추가하는 작업은 초기 프로젝트에 많은 비용과 시간을 소모한다.
새로배워야 하는 언어
DSL을 프로젝트에 추가함으로서, 언어가 1개 늘어나는 부담이 있다.

자바로 DSL을 만드는 패턴법

NOTE
쇼핑몰에서 주문을 하는 간단한 예제로 DSL을 만드는 패턴을 알아보자!
대표적인 구현방법 3가지
Product product1 = new Product("청소기", 200_000); Product product2 = new Product("냉장고", 1_200_000); Coupon coupon = new Coupon("100,000원 할인 쿠폰", 100_000); Order order = new Order(); // 청소기 1개 선택 OrderBasket orderBasket1 = new OrderBasket(product1, 1); // 장바구니 추가 order.addOrderBasket(orderBasket1); // 냉장고 1개 선택 OrderBasket orderBasket2 = new OrderBasket(product2, 1); // 냉장고 2개 선택 orderBasket2.countUp(); // 냉장고 3개 선택 orderBasket2.countUp(); // 장바구니 추가 order.addOrderBasket(orderBasket2); // 쿠폰 적용 order.applyCoupon(coupon); // 주문 완료 order.completed();
Java
복사
특정 상품들을 장바구니에 담는 주문을 만드는 로직을 구현한다.
쇼핑몰 참고코드
지금은 그래도 볼만하지만, 필드와 메서드가 더 많아진다면 가독성이 더욱 떨어져 직관적인 코드를 이해하고, 검증 할 수 없어진다.
조금 더 직접적이고, 직관적으로 도메인 모델을 반영할 수 있는 DSL이 필요하다

1. 메서드 체인(플루언트 스타일)을 이용한 DSL

NOTE
DSL을 구현하는 가장 흔한 방식이며, 인스턴스의 생성단계를 Builder 클래스에 구현해서 지정된 절차에따라 API를 호출하도록 할 수 있다!
Order order = MethodChainingOrderBuilder.builder() .choice() .product(product1).count(1) .and() .product(product2).count(1).countUp().countUp() .end() .applyCoupon(coupon) .completed();
Java
복사
가독성이 훨씬 좋아졌다.
Builder 구현코드 참고

장점/단점

메서드의 이름이 인수의 이름을 대신하도록 만듦으로 가독성 개선, 문법적 잡음이 최소화된다!
빌더를 구현해야 한다는 단점이 있다.

2. 중첩된 함수 이용

NOTE
다른 함수안에 함수를 이용해서 도메인을 만든다.
Product product1 = new Product("청소기", 200_000); Product product2 = new Product("냉장고", 1_200_000); Coupon coupon = new Coupon("100,000원 할인 쿠폰", 100_000); Order order = order( coupon, choice( product(product1), orderCount(1) ), choice( product(product2), orderCount(1) ) ).completed();
Java
복사
좋은건가? 난 잘모르겠다
중첩된 함수 구현

장점/단점

메서드 체인에 비해 함수의 중첩 방식이 도메인 계층 구조에 그대로 반영된다.
DSL에 더 많은 괄호를 사용해야하고, 인수 목록을 정적 메서드에 넘겨줘야 한다.

3. 람다 표현식을 이용한 시퀀싱

NOTE
Product product1 = new Product("청소기", 200_000); Product product2 = new Product("냉장고", 1_200_000); Coupon coupon = new Coupon("100,000원 할인 쿠폰", 100_000); Order order = order(b -> { b.choice(b2 -> { b2.product(product1); b2.orderCount(1); }); b.choice(b2 -> { b2.product(product2); b2.orderCount(1); }); b.applyCoupon(coupon); });
Java
복사
람다 표현식 구현

장점/단점

메서드 체인, 중첩 함수의 장점을 가져왔다.
많은 설정 코드가 필요하며, DSL 자체가 Java8 람다표현식 문법에 의한 잡음의 영향을 받는다.