CHAP10 - Modern-Java-in-Action/Online-Study GitHub Wiki
- ๋๋ฉ์ธ ์ ์ฉ ์ธ์ด(Domain-Specific Languages, DSL)๋ ๋ฌด์์ด๋ฉฐ ์ด๋ค ํ์์ผ๋ก ๊ตฌ์ฑ๋๋๊ฐ?
- DSL์ API์ ์ถ๊ฐํ ๋์ ์ฅ๋จ์
- JVM์์ ํ์ฉํ ์ ์๋ ์๋ฐ ๊ธฐ๋ฐ DSL์ ๊น๋ํ๊ฒ ๋ง๋๋ ๋์
- ์ต์ ์๋ฐ ์ธํฐํ์ด์ค์ ํด๋์ค์ ์ ์ฉ๋ DSL์์ ๋ฐฐ์
- ํจ๊ณผ์ ์ธ ์๋ฐ ๊ธฐ๋ฐ DSL์ ๊ตฌํํ๋ ํจํด๊ณผ ๊ธฐ๋ฒ
- ์ด๋ค ํจํด์ ์๋ฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋๊ตฌ์์ ์ผ๋ง๋ ํํ ์ฌ์ฉํ๋๊ฐ?
ํ๋ก๊ทธ๋จ์ ์ฌ๋๋ค์ด ์ดํดํ ์ ์๋๋ก ์์ฑ๋์ด์ผ ํ๋ ๊ฒ์ด ์ค์ํ๋ฉฐ ๊ธฐ๊ธฐ๊ฐ ์คํํ๋ ๋ถ๋ถ์ ๋ถ์ฐจ์ ์ผ ๋ฟ - ํ๋กค๋ ์๋ฒจ์จ
- ํ๋ก๊ทธ๋๋ฐ ์ธ์ด๋ ๊ฒฐ๊ตญ ์ธ์ด์ด๋ฉฐ ์ธ์ด์ ์ฃผ์ ๋ชฉํ๋ ๋ฉ์์ง๋ฅผ ๋ช ํํ๊ณ ์์ ์ ์ธ ๋ฐฉ์์ผ๋ก ์ ๋ฌํ๋ ๊ฒ
- ์๋๊ฐ ๋ช ํํ๊ฒ ์ ๋ฌ๋์ด์ผ ํ๋ค.
- DSL
- ํน์ ๋๋ฉ์ธ์ ๋์์ผ๋ก ๋ง๋ค์ด์ง ํน์ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด
- ์ ํ๋ฆฌ์ผ์ด์ ์ ๋น์ฆ๋์ค ๋ก์ง์ ํํ
- ๋๋ฉ์ธ ์ ๋ฌธ๊ฐ๊ฐ ๋น์ฆ๋์ค ๊ด์ ์์ ์ํํธ์จ์ด๊ฐ ์ ๋๋ก ๋์๋์ง ํ์ธํ ์ ์์
- ๋ฉ์ด๋ธ, ์คํธ๋ ๋น๋ ๊ณผ์ ์ ํํํ๋ DSL, HTML์ ์นํ์ด์ง์ ๊ตฌ์กฐ๋ฅผ ์ ์ํ๋๋ก ํนํ๋ ์ธ์ด
- ํน์ ๋น์ฆ๋์ค ๋๋ฉ์ธ์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ค๊ณ ๋ง๋ ์ธ์ด
- ex) ํ๊ณ์ ์ฉ ์ํํธ์จ์ด ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฐ๋ฐ -> ๋น์ฆ๋์ค ๋๋ฉ์ธ์๋ ํต์ฅ ์ ์ถ๊ธ ๋ด์ญ, ๊ณ์ข ์ ๊ฐ์ ๊ฐ๋ ์ด ํฌํจ
- ํน์ ๋น์ฆ๋์ค ๋๋ฉ์ธ์ ์ธํฐํ์ด์ค๋ก ๋ง๋ API
- ๊ฐ๊ฒฐํจ : API๋ ๋น์ฆ๋์ค ๋ก์ง์ ๊ฐํธํ๊ฒ ์บก์ํํ๋ฏ๋ก ๋ฐ๋ณต์ ํผํ ์ ์๊ณ ์ฝ๋๋ฅผ ๊ฐ๊ฒฐํ๊ฒ ๋ง๋ค ์ ์๋ค.
- ๊ฐ๋ ์ฑ : ๋๋ฉ์ธ ์์ญ์ ์ฉ์ด๋ฅผ ์ฌ์ฉํ๋ฏ๋ก ๋น ๋๋ฉ์ธ ์ ๋ฌธ๊ฐ๋ ์ฝ๋๋ฅผ ์ฝ๊ฒ ์ดํดํ ์ ์๋ค. ๊ฒฐ๊ณผ์ ์ผ๋ก ๋ค์ํ ์กฐ์ง ๊ตฌ์ฑ์ ๊ฐ์ ์ฝ๋์ ๋๋ฉ์ธ ์์ญ์ด ๊ณต์ ๋ ์ ์๋ค.
- ์ ์ง๋ณด์ : ์ ์ค๊ณ๋ DSL๋ก ๊ตฌํํ ์ฝ๋๋ ์ฝ๊ฒ ์ ์ง ๋ณด์ํ๊ณ ๋ฐ๊ฟ ์ ์๋ค.
- ๋์ ์์ค์ ์ถ์ํ : DSL์ ๋๋ฉ์ธ๊ณผ ๊ฐ์ ์ถ์ํ ์์ค์์ ๋์ํ๋ฏ๋ก ๋๋ฉ์ธ์ ๋ฌธ์ ์ ์ง์ ์ ์ผ๋ก ๊ด๋ จ๋์ง ์์ ์ธ๋ถ ์ฌํญ์ ์จ๊ธด๋ค.
- ์ง์ค : ๋น์ฆ๋์ค ๋๋ฉ์ธ์ ๊ท์น์ ํํํ ๋ชฉ์ ์ผ๋ก ์ค๊ณ๋ ์ธ์ด์ด๋ฏ๋ก ํ๋ก๊ทธ๋๋จธ๊ฐ ํน์ ์ฝ๋์ ์ง์คํ ์ ์๋ค. ๊ฒฐ๊ณผ์ ์ผ๋ก ์์ฐ์ฑ์ด ์ข์์ง๋ค.
- ๊ด์ฌ์ฌ ๋ถ๋ฆฌ : ์ง์ ๋ ์ธ์ด๋ก ๋น์ฆ๋์ค ๋ก์ง์ ํํํจ์ผ๋ก ์ ํ๋ฆฌ์ผ์ด์ ์ ์ธํ๋ผ๊ตฌ์กฐ์ ๊ด๋ จ๋ ๋ฌธ์ ์ ๋ ๋ฆฝ์ ์ผ๋ก ๋น์ฆ๋์ค ๊ด๋ จ๋ ์ฝ๋์์ ์ง์คํ๊ธฐ๊ฐ ์ฉ์ดํ๋ค.
- DSL ์ค๊ณ์ ์ด๋ ค์ : ๊ฐ๊ฒฐํ๊ฒ ์ ํ์ ์ธ ์ธ์ด์ ๋๋ฉ์ธ ์ง์์ ๋ด๋ ๊ฒ์ด ์ฌ์ด ์์ ์ ์๋๋ค.
- ๊ฐ๋ฐ ๋น์ฉ : ์ฝ๋์ DSL์ ์ถ๊ฐํ๋ ์์ ์ ์ด๊ธฐ ํ๋ก์ ํธ์ ๋ง์ ๋น์ฉ๊ณผ ์๊ฐ์ด ์๋ชจ๋๋ค. ๋ํ DSL ์ ์ง๋ณด์์ ๋ณ๊ฒฝ์ ํ๋ก์ ํธ์ ๋ถ๋ด์ ์ฃผ๋ ์์๋ค.
- ์ถ๊ฐ ์ฐํ ๊ณ์ธต : DSL์ ์ถ๊ฐ์ ์ธ ๊ณ์ธต์ผ๋ก ๋๋ฉ์ธ ๋ชจ๋ธ์ ๊ฐ์ธ๋ฉฐ ์ด๋ ๊ณ์ธต์ ์ต๋ํ ์๊ฒ ๋ง๋ค์ด ์ฑ๋ฅ ๋ฌธ์ ๋ฅผ ํํผํ๋ค.
- ์๋ก ๋ฐฐ์์ผ ํ๋ ์ธ์ด : DSL์ ํ๋ก์ ํธ์ ์ถ๊ฐํ๋ฉด์ ํ์ด ๋ฐฐ์์ผ ํ๋ ์ธ์ด๊ฐ ํ ๊ฐ ๋ ๋์ด๋๋ค๋ ๋ถ๋ด์ด ์๋ค.
- ํธ์คํ ์ธ์ด ํ๊ณ : ์ผ๋ถ ์๋ฐ ๊ฐ์ ๋ฒ์ฉ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด๋ ์ฅํฉํ๊ณ ์๊ฒฉํ ๋ฌธ๋ฒ์ ๊ฐ์ก๋ค. ์ด๋ฐ ์ธ์ด๋ก๋ ์ฌ์ฉ์ ์นํ์ DSL์ ๋ง๋ค๊ธฐ๊ฐ ํ๋ค๋ค.
- DSL์ ์นดํ ๊ณ ๋ฆฌ๋ฅผ ๊ตฌ๋ถํ๋ ๋ฐฉ๋ฒ -> ๋ด๋ถ DSL, ์ธ๋ถ DSL, ๋ค์ค DSL
- ์๋ฐ๋ก ๊ตฌํํ DSL์ ์๋ฏธ
- ๋๋ค ํํ์์ ๋ฑ์ฅ์ผ๋ก ์ฝ๊ธฐ ์ฝ๊ณ , ๊ฐ๋จํ๋ฉฐ ํํ๋ ฅ ์๋ DSL์ ๋ง๋ค ์ ์๊ฒ ๋จ
- ์ต๋ช ๋ด๋ถ ํด๋์ค ๋์ ๋๋ค๋ฅผ ์ฌ์ฉํ๋ฉด ์ฅํฉํจ์ ํฌ๊ฒ ์ค์ฌ ์ ํธ ๋๋น ์ก์ ๋น์จ์ ์ ์ ์์ค์ผ๋ก ์ ์งํ๋ DSL์ ๋ง๋ค ์ ์๋ค.
// forEach๋ฅผ ์ด์ฉํ์ฌ ๋ฌธ์์ด ๋ชฉ๋ก ์ถ๋ ฅํ๊ธฐ
List<String> numbers = Arrays.asList("one", "two", "three");
// 1. ์ต๋ช
๋ด๋ถ ํด๋์ค
numbers.forEach(new Consumer<String>() { -> ์ฝ๋์ ์ก์1
@Override
public void accept(String s) { -> ์ฝ๋์ ์ก์2
System.out.println(s); -> ์ฝ๋์ ์ก์3
}
});
// 2. ๋๋ค ํํ์
numbers.forEach(s -> System.out.println(s));
// 3. ๋ฉ์๋ ์ฐธ์กฐ
numbers.forEach(System.out::println);
- ์ธ๋ถ DSL์ ๋นํด ์๋ก์ด ํจํด๊ณผ ๊ธฐ์ ์ ๋ฐฐ์ DSL์ ๊ตฌํํ๋ ๋ ธ๋ ฅ์ด ์ค์ด๋ ๋ค
- ์์ ์๋ฐ๋ก DSL์ ๊ตฌํํ๋ฉด ๋๋จธ์ง ์ฝ๋์ ํจ๊ป DSL์ ์ปดํ์ผํ ์ ์๋ค
- ๊ฐ๋ฐํ์ด ์๋ก์ด ์ธ์ด๋ฅผ ๋ฐฐ์ธ ํ์๊ฐ ์๋ค.
- ๊ธฐ์กด ์๋ฐ IDE๋ฅผ ํตํด ์๋ ์์ฑ, ์๋ ๋ฆฌํฉํฐ๋ง ๊ฐ์ ๊ธฐ๋ฅ์ ๊ทธ๋๋ก ์ฌ์ฉํ ์ ์๋ค.
- ํ ๊ฐ์ ์ธ์ด๋ก ํ๋ ๋๋ ์ฌ๋ฌ ๋๋ฉ์ธ์ ๋์ํ์ง ๋ชปํด ์ถ๊ฐ DSL์ ๊ฐ๋ฐํด์ผ ํ๋ ์ํฉ์์ ์๋ฐ๋ฅผ ์ด์ฉํ์ฌ ์ถ๊ฐ DSL์ ์ฝ๊ฒ ํฉ์น ์ ์๋ค.
์ฅ์
- ๊ฐ์ ์๋ฐ ๋ฐ์ดํธ์ฝ๋๋ฅผ ์ฌ์ฉํ๋ JVM ๊ธฐ๋ฐ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด๋ฅผ ์ด์ฉํ์ฌ DSL์ ๋ง๋ค ์ ์๋ค.
- ๋ฌธ๋ฒ์ ์ก์์ด ์์ผ๋ฉฐ ๊ฐ๋ฐ์๊ฐ ์๋ ์ฌ๋๋ ์ฝ๋๋ฅผ ์ฝ๊ฒ ์ดํดํ ์ ์๋ค.
- ์๋ฐ ์ธ์ด๊ฐ ๊ฐ์ง๋ ํ๊ณ๋ฅผ ๋์ ์ ์๋ค (์ค์นผ๋ผ - ์ปค๋ง, ์์ ๋ณํ ๋ฑ DSL ๊ฐ๋ฐ์ ํ์ํ ์ฌ๋ฌ ํน์ฑ์ ๊ฐ์ถค)
๋จ์
- ๋๊ตฐ๊ฐ๊ฐ ํด๋น ์ธ์ด์ ๋ํด ๊ณ ๊ธ ๊ธฐ์ ์ ์ฌ์ฉํ ์ ์์ ์ ๋์ ์ถฉ๋ถํ ์ง์์ ๊ฐ์ง๊ณ ์์ด์ผ ํ๋ค.
- ๋ ๊ฐ ์ด์์ ์ธ์ด๊ฐ ํผ์ฌํ๋ฏ๋ก ์ฌ๋ฌ ์ปดํ์ผ๋ฌ๋ก ์์ค๋ฅผ ๋น๋ํ๋๋ก ๋น๋ ๊ณผ์ ์ ๊ฐ์ ํด์ผ ํ๋ค.
- ํธํ์ฑ ๋ฌธ์ ๋ฅผ ๊ณ ๋ คํด์ผํ๋ค
- ์์ ๋ง์ ๋ฌธ๋ฒ๊ณผ ๊ตฌ๋ฌธ์ผ๋ก ์๋ก์ด ์ธ์ด๋ฅผ ์ค๊ณํด์ผ ํ๋ค๋ ๋จ์
- ์ฐ๋ฆฌ์๊ฒ ํ์ํ ํน์ฑ์ ์๋ฒฝํ๊ฒ ์ ๊ณตํ๋ ์ธ์ด๋ฅผ ์ค๊ณํ ์ ์๋ค๋ ์ฅ์
- ์๋ฐ์ ์๋ก์ด ๊ธฐ๋ฅ์ ์ฅ์ ์ ์ ์ฉํ ์ฒซ API๋ ๋ค์ดํฐ๋ธ ์๋ฐ API ์์ ์ด๋ค.
- ๋๋ค ํํ์๊ณผ ๋ฉ์๋ ์ฐธ์กฐ๋ฅผ ์ด์ฉํด DSL์ ๊ฐ๋ ์ฑ, ์ฌ์ฌ์ฉ์ฑ, ๊ฒฐํฉ์ฑ์ด ๋์์ก๋ค.
์ฌ๋๋ค์ ๊ฐ์ง๊ณ ์๋ ๋ฆฌ์คํธ์์ ๋์ด์์ผ๋ก ๊ฐ์ฒด๋ฅผ ์ ๋ ฌํ๋ ์์
Collections.sort(persons, new Comparator<Person>() {
public int compare(Person p1, Person p2) {
return p1.getAge() - p2.getAge();
}
});
- java8 ์ด์ ์๋ ์์ ๊ฐ์ด ์ต๋ช ํด๋์ค๋ฅผ ํ์ฉํ์ฌ ๊ตฌํ -> ๋๋ค ํํ์์ผ๋ก ๋ณ๊ฒฝ
Collections.sort(persons, (p1, p2) -> p1.getAge() - p2.getAge());
- ์ ์ ์ ํธ๋ฆฌํฐ ๋ฉ์๋ ์งํฉ๊ณผ ๋ฉ์๋ ์ฐธ์กฐ ์ ๊ณต
Collections.sort(persons, comparing(p -> p.getAge()));
Collections.sort(persons, comparing(Person::getAge));
- reverse ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ์ญ์์ผ๋ก ์ ๋ ฌํ๊ฑฐ๋ ์ด๋ฆ์ผ๋ก ๋น๊ต๋ฅผ ์ํํ๋ Comparator๋ฅผ ๊ตฌํํ์ฌ ์ํ๋ฒณ ์ ์ ๋ ฌ
Collections.sort(persons, comparing(Person::getAge).reverse());
Collections.sort(persons, comparing(Person::getAge)
.thenComparing(Person::getName));
- List ์ธํฐํ์ด์ค์ ์ถ๊ฐ๋ ์ sort ๋ฉ์๋๋ฅผ ์ด์ฉํด ์ฝ๋๋ฅผ ๊น๋ํ๊ฒ ์ ๋ฆฌ
persons.sort(comparing(Person::getAge)
.thenComparing(Person::getName));
- ์ปฌ๋ ์ ์ ๋ ฌ ๋๋ฉ์ธ์ ์ต์ DSL
- ์์ ์์ญ์ ๊ตญํ๋ ์์ ์ง๋ง ์ด๋ฏธ ๋๋ค์ ๋ฉ์๋ ์ฐธ์กฐ๋ฅผ ์ด์ฉํ DSL์ด ์ฝ๋์ ๊ฐ๋ ์ฑ, ์ฌ์ฌ์ฉ์ฑ, ๊ฒฐํฉ์ฑ์ ๋์ผ์ ์๋์ง ๋ณด์ฌ์ค๋ค.
- Stream ์ธํฐํ์ด์ค๋ ๋ค์ดํฐ๋ธ ์๋ฐ API์ ์์ ๋ด๋ถ DSL์ ์ ์ฉํ ์ข์ ์์
- ๋ฐ์ดํฐ ์กฐ์(ํํฐ๋ง, ์ ๋ ฌ, ๋ณํ, ๊ทธ๋ฃนํ ๋ฑ) ๊ธฐ๋ฅ ์ ๊ณต
๋ฐ๋ณต ํ์์ผ๋ก ์์ ๋ก๊ทธ ํ์ผ์์ ์๋ฌ ํ์ ์ฝ๋ ์ฝ๋
List<String> errors = new ArrayList<>();
int errorCount = 0;
BufferedReader bufferedReader = new BufferedReader(new FileReader(fileName));
String line = bufferedReader.readLine();
while (errorCount < 40 && line != null) {
if (line.startsWith("ERROR")) {
errors.add(line);
errorCount++;
}
line = bufferedReader.readLine();
}
- ์ฝ๋๊ฐ ์ฅํฉํ์ฌ ์๋๋ฅผ ํ ๋์ ํ์ ํ๊ธฐ ์ด๋ ต๊ณ , ๋ฌธ์ ๊ฐ ๋ถ๋ฆฌ๋์ง ์์ ๊ฐ๋ ์ฑ๊ณผ ์ ์ง๋ณด์์ฑ ๋ชจ๋ ์ ํ๋จ
ํจ์ํ์ผ๋ก ๋ก๊ทธ ํ์ผ์ ์๋ฌ ํ์ ์ฝ๋ ์ฝ๋
List<String> errors = Files.lines(Paths.get(fileName))
.filter(line -> line.startsWith("ERROR"))
.limit(40)
.collect(toList());
- ์คํธ๋ฆผ API์ ํ๋ฃจ์ธํธ ์คํ์ผ์ธ ๋ฉ์๋ ์ฒด์ธ์ ์ ์ค๊ณ๋ DSL์ ๋ ๋ค๋ฅธ ํน์ง
- ๋ชจ๋ ์ค๊ฐ ์ฐ์ฐ์ ๊ฒ์ผ๋ฅด๋ฉฐ ๋ค๋ฅธ ์ฐ์ฐ์ผ๋ก ํ์ดํ๋ผ์ธ๋ ์ ์๋ ์คํธ๋ฆผ์ผ๋ก ๋ฐํ
- ์ต์ข ์ฐ์ฐ์ ์ ๊ทน์ ์ด๋ฉฐ ์ ์ฒด ํ์ดํ๋ผ์ธ์ด ๊ณ์ฐ์ ์ผ์ผํจ๋ค.
- Collector ์ธํฐํ์ด์ค๋ ๋ฐ์ดํฐ ์์ง์ ์ํํ๋ DSL
- ์ฐจ๋ฅผ ๋ธ๋๋์ ์์์ผ๋ก ๊ทธ๋ฃนํํ๋ ๋ก์ง
// ์ค์ฒฉํ์
Map<String, Map<Color, List<Car>>> carsByBrandAndColor
= cars.stream().collect(groupingBy(Car::getBrand,
groupingBy(Car::getColor)));
// ํ๋ฃจ์ธํธ ๋ฐฉ์
Comparator<Person> comparator =
comparing(Person::getAge).thenComparing(Person::getName);
- ์ ์ด์์ ์ปดํฌ๋ํธ๋ฅผ ์กฐํฉํ ๋๋ ๋ณดํต ํ๋ฃจ์ธํธ ํ์์ด ์ค์ฒฉ ํ์์ ๋นํด ๊ฐ๋ ์ฑ์ด ์ข์
- groupingBy ํฉํฐ๋ฆฌ ๋ฉ์๋์ ์์ ์ ์์ํ๋ GroupingBuilder๋ฅผ ๋ง๋ค์ด ์ ์ฐํ ๋ฐฉ์์ผ๋ก ๊ทธ๋ฃนํ ์์ ๊ฐ๋ฅ
import static java.util.stream.Collectors.groupingBy;
public class GroupingBuilder<T, D, K> {
private final Collector<? super T, ?, Map<K, D>> collector;
private GroupingBuilder(Collector<? super T, ?, Map<K, D>> collector) {
this.collector = collector;
}
public Collector<? super T, ?, Map<K, D>> get() {
return collector;
}
public <J> GroupingBuilder<T, Map<K, D>, J>
after(Function<? super T, ? extends J> classifier) {
return new GroupingBuilder<>(groupingBy(classifier, collector));
}
public static <T, D, K> GroupingBuilder<T, List<T>, K>
groupOn(Function<? super T, ? extends K> classifier) {
return new GroupingBuilder<>(groupingBy(classifier));
}
}
- ํ๋ฃจ์ธํธ ํ์ ๋น๋ ์ฌ์ฉ์ ์ค์ฒฉ๋ ๊ทธ๋ฃนํ ์์ค์ ๋ฐ๋๋ก ๊ทธ๋ฃนํ ํจ์๋ฅผ ๊ตฌํํด์ผํจ -> ์ง๊ด์ ์ด์ง ๋ชปํจ
Collector<? super Car, ?, Map<Brand, Map<Color, List<Car>>>>
carGroupingCollector =
GroupingBuilder.groupOn(Car::getColor)
.after(Car::getBrand).get();
- ์๋ฐ์ ๋ณต์กํ ๋ฃจํ ์ ์ด์ ๋น๊ตํด ์ ์ฐฝํจ์ ์๋ฏธํ๋ ํ๋ฃจ์ธํธ ์คํ์ผ์ ๋ฉ์๋ ์ฒด์ธ์ ์ด์ฉํ์ฌ DSL์ ๋ง๋ ๊ฒ
์ฅ์
- ์ฃผ๋ฌธ์ ์ฌ์ฉํ ํ๋ผ๋ฏธํฐ๊ฐ ๋น๋ ๋ด๋ถ๋ก ๊ตญํ๋๋ค
- ์ ์ ๋ฉ์๋ ์ฌ์ฉ์ ์ต์ํํ๊ณ ๋ฉ์๋ ์ด๋ฆ์ด ์ธ์์ ์ด๋ฆ์ ๋์ ํ๋๋ก ๋ง๋ฆ์ผ๋ก์ DSL ๊ฐ๋ ์ฑ์ ๊ฐ์ ํ๋ ํจ๊ณผ
- ์ด๋ฐ ๊ธฐ๋ฒ์ ์ ์ฉํ ํ๋ฃจ์ธํธ DSL์๋ ๋ถ๋ฒ์ ์ก์์ด ์ต์ํ
๋จ์
- ๋น๋๋ฅผ ๊ตฌํํด์ผ ํ๋ค
- ์์๋ค ์์ค์ ๋น๋๋ฅผ ํ์ ์์ค์ ๋น๋์ ์ฐ๊ฒฐํ ์ ์ฐฉ ์ฝ๋๊ฐ ํ์ํ๋ค
- ๋๋ฉ์ธ ๊ฐ์ฒด ์ค์ฒฉ๊ตฌ์กฐ์ ์ผ์นํ๊ฒ ๋ค์ฌ์ฐ๊ธฐ๋ฅผ ๊ฐ์ ํ๋ ๋ฐฉ๋ฒ์ด ์์
- ๋ค๋ฅธ ํจ์ ์์ ํจ์๋ฅผ ์ด์ฉํด ๋๋ฉ์ธ ๋ชจ๋ธ์ ๋ง๋ ๋ค
์ฅ์
- ๋ฉ์๋ ์ฒด์ธ์ ๋นํด ํจ์์ ์ค์ฒฉ ๋ฐฉ์์ด ๋๋ฉ์ธ ๊ฐ์ฒด ๊ณ์ธต ๊ตฌ์กฐ์ ๊ทธ๋๋ก ๋ฐ์๋จ
๋จ์
- DSL์ ๋ ๋ง์ ๊ดํธ๋ฅผ ์ฌ์ฉํด์ผ ํ๋ค
- ์ธ์ ๋ชฉ๋ก์ ์ ์ ๋ฉ์๋์ ๋๊ฒจ์ฃผ์ด์ผ ํ๋ค
- ์ธ์์ ์๋ฏธ๊ฐ ์ด๋ฆ์ด ์๋๋ผ ์์น์ ์ํด ์ ์ ๋จ
- ์ธ์์ ์ญํ ์ ํ์คํ๊ฒ ๋ง๋๋ ์ฌ๋ฌ ๋๋ฏธ๋ฉ์๋(at, on)๋ฅผ ์ด์ฉ
- ๋๋ค ํํ์์ผ๋ก ์ ์ํ ํจ์ ์ํ์ค๋ฅผ ์ฌ์ฉํ๋ DSL ํจํด
์ฅ์
- ๋ฉ์๋ ์ฒด์ธ ํจํด์ฒ๋ผ ํ๋ฃจ์ธํธ ๋ฐฉ์์ผ๋ก ๊ฑฐ๋ ์ฃผ๋ฌธ์ ์ ์ํ ์ ์๋ค
- ์ค์ฒฉ ํจ์ ํ์ ์ฒ๋ผ ๋ค์ํ ๋๋ค ํํ์์ ์ค์ฒฉ ์์ค๊ณผ ๋น์ทํ๊ฒ ๊ณ์ธต ๊ตฌ์กฐ๋ฅผ ์ ์ง
๋จ์
- ๋ง์ ์ค์ ์ฝ๋๊ฐ ํ์ํ๋ฉฐ, ๋๋ค ํํ์ ๋ฌธ๋ฒ์ ์ํ ์ก์์ ์ํฅ์ ๋ฐ์๋ค
- ์ธ ๊ฐ์ง DSL ํจํด์ ํผ์ฉํด ๊ฐ๋ ์ฑ ์๋ DSL์ ๋ง๋ค ์ ์์
- ์ฌ์ฉ์๊ฐ ๊ฐ DSL ํจํด์ ๋ฐฐ์ฐ๋๋ฐ ์ค๋ ์๊ฐ์ด ๊ฑธ๋ฆฐ๋ค
- ์ฃผ๋ฌธ์ ์ด ํฉ์ 0๊ฐ ์ด์์ ์ธ๊ธ์ ์ถ๊ฐํด ์ต์ข ๊ฐ์ ๊ณ์ฐํ๋ ๊ธฐ๋ฅ ์ถ๊ฐ
double value = calculate(order, true, false, true);
- ๋ถ๋ฆฌ์ธ ๋ณ์์ ์์๋ฅผ ๊ธฐ์ตํ๊ธฐ๋ ์ด๋ ต๊ณ ์ด๋ค ์ธ๊ธ์ด ์ ์ฉ๋์๋์ง ํ์ ํ๊ธฐ ์ด๋ ค์
double value = new TaxCalculator().withTaxRegional()
.withTaxSurcharge()
.calculate(order);
- ๋๋ฉ์ธ์ ๊ฐ ์ธ๊ธ์ ํด๋นํ๋ ๋ถ๋ฆฌ์ธ ํ๋๊ฐ ํ์ํ๋ฏ๋ก ํ์ฅ์ฑ์ด ์ ํ์ ์
- ์๋ฐ์ ํจ์ํ ๊ธฐ๋ฅ์ ์ด์ฉํ์ฌ ๋ ๊ฐ๊ฒฐํ๊ณ ์ ์ฐํ ๋ฐฉ์์ผ๋ก ๋ฆฌํฉํฐ๋ง
double value = new TaxCalculator().with(Tax::regional)
.with(Tax::surcharge)
.calculate(order);
- DSL ํจํด์ ์ฅ์ ๊ณผ ๋จ์
- SQL์ ๊ตฌํํ๋ ๋ด๋ถ์ DSL, ์๋ฐ์ ์ง์ ๋ด์ฅ๋ ํ์ ์์ ์ธ์ด
- ๋์ ์ฃผ๋ ๊ฐ๋ฐ(BDD, Behavior-driven development) ํ๋ ์์ํฌ
- ๊ฐ๋ฐ์๊ฐ ๋น์ฆ๋์ค ์๋๋ฆฌ์ค๋ฅผ ํ๋ฌธ ์์ด๋ก ๊ตฌํํ ์ ์๋๋ก ๋์์ฃผ๋ BDD ๋๊ตฌ
- ์ ์ ์กฐ๊ฑด ์ ์(Given), ์ํํ๋ ค๋ ๋๋ฉ์ธ ๊ฐ์ฒด์ ์ค์ง ํธ์ถ(When), ํ ์คํธ ์ผ์ด์ค์ ๊ฒฐ๊ณผ๋ฅผ ํ์ธํ๋ assertion(Then)
- ์ํฐํ๋ผ์ด์ฆ ํตํฉํจํด์ ์ง์ํ ์ ์๋๋ก ์์กด์ฑ ์ฃผ์ ์ ๊ธฐ๋ฐํ ์คํ๋ง ํ๋ก๊ทธ๋๋ฐ ๋ชจ๋ธ์ ํ์ฅ
- ์คํ๋ง ํตํฉ์ ํต์ฌ ๋ชฉํ๋ ๋ณต์กํ ์ํฐํ๋ผ์ด์ฆ ํตํฉ ์๋ฃจ์ ์ ๊ตฌํํ๋ ๋จ์ํ ๋ชจ๋ธ์ ์ ๊ณตํ๊ณ ๋น๋๊ธฐ, ๋ฉ์์ง ์ฃผ๋ ์ํคํ ์ฒ๋ฅผ ์ฝ๊ฒ ์ ์ฉํ๋๋ก ๋๋ ๊ฒ
- DSL์ ์ฃผ์ ๊ธฐ๋ฅ์ ๊ฐ๋ฐ์์ ๋๋ฉ์ธ ์ ๋ฌธ๊ฐ ์ฌ์ด์ ๊ฐ๊ฒฉ์ ์ขํ๋ ๊ฒ
- DSL์ ๋ด๋ถ์ DSL๊ณผ ์ธ๋ถ์ DSL๋ก ๋ถ๋ฅํ ์ ์๋ค
- JVM์์ ์ด์ฉํ ์ ์๋ ์ค์นผ๋ผ, ๊ทธ๋ฃจ๋น ๋ฑ์ ๋ค๋ฅธ ์ธ์ด๋ก ๋ค์ค DSL์ ๊ฐ๋ฐํ ์ ์๋ค
- ์๋ฐ๋ ์๋ฐ์ ์ฅํฉํจ๊ณผ ๋ฌธ๋ฒ์ ์๊ฒฉํจ ๋๋ฌธ์ ๋ด๋ถ DSL ๊ฐ๋ฐ ์ธ์ด๋ก ์ ํฉํ์ง ์์์ผ๋ ์๋ฐ 8์ ๋๋ค ํํ์๊ณผ ๋ฉ์๋ ์ฐธ์กฐ ๋๋ถ์ ์ํฉ์ด ๋ง์ด ๊ฐ์ ๋จ