소스 코드의 가독성을 산문과 유사하게 만드는 것이 목적
→ 즉 개발자들이 읽기 편하고, 라인 줄 줄이고, 간단하게 기술할 수 있다는 매력을 갖고 있다.
특히 인터페이스 안에 도메인 특화 언어(DSL)를 작성
var translations = new Dictionary<string, string>
{
{"cat", "chat"},
{"dog", "chien"},
{"fish", "poisson"},
{"bird", "oiseau"}
};
// Find translations for English words containing the letter "a",
// sorted by length and displayed in uppercase
IEnumerable<string> query = translations
.Where (t => t.Key.Contains("a")) // Key 값에 a가 있는지 확인
.OrderBy (t => t.Value.Length) // Value 값의 길이 오름차순
.Select (t => t.Value.ToUpper()); // Value 값을 대문자로
// The same query constructed progressively:
var filtered = translations.Where (t => t.Key.Contains("a"));
var sorted = filtered.OrderBy (t => t.Value.Length);
var finalQuery = sorted.Select (t => t.Value.ToUpper());
같은 객체가 여러 개 존재할 수 있다. 이때 Bounded Context에 따라 객체(Model)의 역할은 완벽히 바뀐다. → 서로 다른 도메인 영역에 영향을 끼치려면 API 호출을 통해서 이루어져야..
EX) 주문 도메인의 옷 == 손님들에게 팔기 위한 객체 정보 ↔ 옷을 관리하는 도메인의 옷 == 점주입장에서 관리하기 위한 객체 정보
각 도메인은 서비스 별로 철저히 분리 → 어플리케이션 또는 그 안의 모듈간의 의존성은 최소화하고, 응집성은 최대화 → 변경과 확장에 용이한 설계
특정 도메인을 적용하는데 특화된 컴퓨터 언어 → 즉 특정용도에서만 사용 가능
특정 영역의 문제 해결에는 그 영역에 맞는 특화된 도구를 사용하자는 취지.
표현 방식은 해당 도메인의 전문가(비 프로그래머)가 이해할 수 있는 형태여야 함 → 코드가 일반 자연어를 읽는 것과 같이 쉽게 이해됨
라이브러리나 프레임워크등을
도메인 Expert 나 우리같은 일반 프로그래머에게 조차도 사용하기 쉽게 (Fluent 하게) 제공해주는것 자체,
제한된 상황 내에서 고민과 노력으로 이루어진 "깔끔한 문장" 으로 우리에게 제공하는 API 자체가 DSL
우리 주변에 있는 DSL
SQL, HTML, CSS , java . ANT, Maven, struts-config.xml, Seasar2 S2DAO, HQL(Hibernate Query Language), JMock- Ruby . Rails Validations, Rails ActiveRecord, Rake, RSpec, Capistrano, Cucumber
DSL은 내부 DSL과 외부 DSL로 구분할 수 있다.
특수한 목적을 위해 제한된 방법으로 호스트 언어를 사용하는 방식, 자체적으로 의존하는 무언가를 만드는 경우에 해당
임베디드 DSL, Fluent Interfaces 라고도 한다.
내부 DSL에서는 API와 DSL의 경계가 모호해 비슷하게 생각하는 경향이 있음 → 좀 더 일반 사용자가 알아보기 쉬운 API가 내부 DSL로 생각해도 될 듯 함
사용하던 도구를 그대로 이용할 수 있음, 처리 결과를 쉽게 예측할 수 있음
EX) Ruby, Smalltalk 등
호스트 언어가 아닌 다른 언어에서 생성된 DSL이다.
대부분 자체적인 문법을 가지지만 기존 언어의 문법을 쓰는 예도 있다.
외부 DSL에서는 DSL과 범용 언어(GPL : General Purpose Language)과의 경계가 모호해지는 경향이 있다. 그 차이는 언어 작성자와 언어 사용자의 목적에 있다. 특정 영역에서 언어의 작성자가 아닌 사용자의 목적에 부합하는, 이해를 할 수 있으면 외부 DSL이다.
→ 만약 이 파서가 내가 쓰는 언어 내에서 그대로 쓸 수 있다면? 내가 쓰는 언어의 파서가 알아서 구문 분석까지 해준다면? == 내부 DSL
애저 펑션의 첫 엔트리 포인트에서 만나는 부분
public static IFunctionFactory Factory { get; set; } = new FunctionFactory(new AppModule());
[FunctionName(nameof(XmlToXmlMapperHttpTrigger))]
public static async Task<HttpResponseMessage> Run(
[HttpTrigger(AuthorizationLevel.Function, "post", Route = "mappers/xml/xml")] HttpRequestMessage req,
ILogger log)
{
return result = await Factory.Create<IXmlToXmlMapperFunction, ILogger>(log)
.InvokeAsync<HttpRequestMessage, HttpResponseMessage>(req)
.ConfigureAwait(false);
}
Create, InvokeAsync
와 같이 상당히 직관적