๐ŸŽต Groovy์˜ ์นดํ…Œ๊ณ ๋ฆฌ ํด๋ž˜์Šค: ์ž„์‹œ ๋ฉ”์„œ๋“œ ์ฃผ์ž… ๐ŸŽต

์ฝ˜ํ…์ธ  ๋Œ€ํ‘œ ์ด๋ฏธ์ง€ - ๐ŸŽต Groovy์˜ ์นดํ…Œ๊ณ ๋ฆฌ ํด๋ž˜์Šค: ์ž„์‹œ ๋ฉ”์„œ๋“œ ์ฃผ์ž… ๐ŸŽต

 

 

์•ˆ๋…•ํ•˜์„ธ์š”, ์—ฌ๋Ÿฌ๋ถ„! ์˜ค๋Š˜์€ Groovy๋ผ๋Š” ์ดˆ์ฟจํ•œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์˜ ์ˆจ๊ฒจ์ง„ ๋ณด์„ ๊ฐ™์€ ๊ธฐ๋Šฅ์— ๋Œ€ํ•ด ์–˜๊ธฐํ•ด๋ณผ๊ฒŒ์š”. ๋ฐ”๋กœ "์นดํ…Œ๊ณ ๋ฆฌ ํด๋ž˜์Šค"์™€ "์ž„์‹œ ๋ฉ”์„œ๋“œ ์ฃผ์ž…"์ด๋ผ๋Š” ๊ฐœ๋…์ธ๋ฐ์š”. ์ด๊ฒŒ ๋ญ” ์†Œ๋ฆฌ๋ƒ๊ณ ์š”? ใ…‹ใ…‹ใ…‹ ๊ฑฑ์ • ๋งˆ์„ธ์š”! ์ œ๊ฐ€ ์‰ฝ๊ณ  ์žฌ๋ฐŒ๊ฒŒ ์„ค๋ช…ํ•ด๋“œ๋ฆด๊ฒŒ์š”. ๐Ÿ˜Ž

๋จผ์ €, Groovy๊ฐ€ ๋ญ”์ง€ ๋ชจ๋ฅด๋Š” ๋ถ„๋“ค์„ ์œ„ํ•ด ๊ฐ„๋‹จํžˆ ์„ค๋ช…ํ•˜์ž๋ฉด, Java ํ”Œ๋žซํผ ์œ„์—์„œ ๋Œ์•„๊ฐ€๋Š” ๋™์  ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์˜ˆ์š”. Java๋ž‘ ๋น„์Šทํ•˜๋ฉด์„œ๋„ ๋” ๊ฐ„๊ฒฐํ•˜๊ณ  ์œ ์—ฐํ•œ ๋ฌธ๋ฒ•์„ ๊ฐ€์ง€๊ณ  ์žˆ์ฃ . ๋งˆ์น˜ Java์— ์Šคํ…Œ๋กœ์ด๋“œ๋ฅผ ์ฃผ์‚ฌํ•œ ๊ฒƒ ๊ฐ™๋‹ฌ๊นŒ์š”? ๐Ÿ’ช

๐Ÿ” Groovy ํŠน์ง• ํ•œ๋ˆˆ์— ๋ณด๊ธฐ:

  • Java์™€ ํ˜ธํ™˜์„ฑ ๊ตฟ๊ตฟ๐Ÿ‘
  • ๋™์  ํƒ€์ดํ•‘ ์ง€์› (๋ณ€์ˆ˜ ํƒ€์ž… ์•ˆ ์จ๋„ ๋ผ์š”!)
  • ํด๋กœ์ €(Closure) ์ง€์› (ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ๊ฝƒ๐ŸŒธ)
  • ๋ฉ”ํƒ€ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ธฐ๋Šฅ (ํ”„๋กœ๊ทธ๋žจ์ด ์ž๊ธฐ ์ž์‹ ์„ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์–ด์š”!)
  • DSL(Domain-Specific Language) ์ž‘์„ฑ ์‰ฌ์›€

์ž, ์ด์ œ ๋ณธ๊ฒฉ์ ์œผ๋กœ ์นดํ…Œ๊ณ ๋ฆฌ ํด๋ž˜์Šค์™€ ์ž„์‹œ ๋ฉ”์„œ๋“œ ์ฃผ์ž…์— ๋Œ€ํ•ด ์•Œ์•„๋ณผ๊นŒ์š”? ์ด ๊ฐœ๋…๋“ค์€ Groovy์˜ ๋ฉ”ํƒ€ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋Šฅ๋ ฅ์„ ๋ณด์—ฌ์ฃผ๋Š” ๋Œ€ํ‘œ์ ์ธ ์˜ˆ์‹œ๋ž๋‹ˆ๋‹ค. ๋ญ”๊ฐ€ ์–ด๋ ค์›Œ ๋ณด์ด์ฃ ? ํ•˜์ง€๋งŒ ๊ฑฑ์ • ๋งˆ์„ธ์š”! ์šฐ๋ฆฌ ํ•จ๊ป˜ ์ฒœ์ฒœํžˆ ํŒŒํ—ค์ณ ๋ณผ๊ฒŒ์š”. ๐Ÿ•ต๏ธโ€โ™‚๏ธ

๐Ÿฑ ์นดํ…Œ๊ณ ๋ฆฌ ํด๋ž˜์Šค: Groovy์˜ ๋งˆ๋ฒ• ์ฃผ๋จธ๋‹ˆ

์นดํ…Œ๊ณ ๋ฆฌ ํด๋ž˜์Šค๋ž€ ๋ญ˜๊นŒ์š”? ๊ฐ„๋‹จํžˆ ๋งํ•ด์„œ, ์ด๋ฏธ ์กด์žฌํ•˜๋Š” ํด๋ž˜์Šค์— ์ƒˆ๋กœ์šด ๋ฉ”์„œ๋“œ๋‚˜ ์†์„ฑ์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” Groovy์˜ ํŠน๋ณ„ํ•œ ๊ธฐ๋Šฅ์ด์—์š”. ๋งˆ์น˜ ๋งˆ๋ฒ• ์ฃผ๋จธ๋‹ˆ์—์„œ ์ƒˆ๋กœ์šด ๋„๊ตฌ๋ฅผ ๊บผ๋‚ด๋Š” ๊ฒƒ์ฒ˜๋Ÿผ์š”! ๐ŸŽฉโœจ

์˜ˆ๋ฅผ ๋“ค์–ด๋ณผ๊นŒ์š”? ์—ฌ๋Ÿฌ๋ถ„์ด String ํด๋ž˜์Šค์— ์ƒˆ๋กœ์šด ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ๋‹ค๊ณ  ํ•ด๋ด์š”. Java์—์„œ๋Š” ์ด๊ฒŒ ๋ถˆ๊ฐ€๋Šฅํ•˜์ฃ . ํ•˜์ง€๋งŒ Groovy์—์„œ๋Š” ์นดํ…Œ๊ณ ๋ฆฌ ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๊ฐ€๋Šฅํ•ด์š”!


class StringEnhancer {
    static String shout(String self) {
        return self.toUpperCase() + "!!!"
    }
}

use(StringEnhancer) {
    println "hello".shout()  // ์ถœ๋ ฅ: HELLO!!!
}

์™€! ๋ญ”๊ฐ€ ์‹ ๊ธฐํ•˜์ง€ ์•Š๋‚˜์š”? ์šฐ๋ฆฌ๊ฐ€ ๋งŒ๋“  'shout' ๋ฉ”์„œ๋“œ๋ฅผ String ํด๋ž˜์Šค์— ์ž„์‹œ๋กœ ์ถ”๊ฐ€ํ–ˆ์–ด์š”. ์ด๊ฒŒ ๋ฐ”๋กœ ์นดํ…Œ๊ณ ๋ฆฌ ํด๋ž˜์Šค์˜ ๋งˆ๋ฒ•์ด์—์š”! ๐Ÿง™โ€โ™‚๏ธ

์ด๋Ÿฐ ๊ธฐ๋Šฅ์ด ์™œ ํ•„์š”ํ• ๊นŒ์š”? ์Œ... ์žฌ๋Šฅ๋„ท์—์„œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ํŠœํ„ฐ๋ง์„ ํ•˜๋Š” ์ƒํ™ฉ์„ ์ƒ๊ฐํ•ด๋ด์š”. ์—ฌ๋Ÿฌ๋ถ„์ด ํ•™์ƒ๋“ค์—๊ฒŒ String ํด๋ž˜์Šค์˜ ์ƒˆ๋กœ์šด ์‚ฌ์šฉ๋ฒ•์„ ๊ฐ€๋ฅด์น˜๊ณ  ์‹ถ์€๋ฐ, ๊ธฐ์กด String ํด๋ž˜์Šค๋ฅผ ๊ฑด๋“œ๋ฆฌ์ง€ ์•Š๊ณ  ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด? ๋ฐ”๋กœ ์ด๋Ÿด ๋•Œ ์นดํ…Œ๊ณ ๋ฆฌ ํด๋ž˜์Šค๊ฐ€ ๋น›์„ ๋ฐœํ•˜๋Š” ๊ฑฐ์ฃ ! ๐Ÿ‘จโ€๐Ÿซโœจ

๐Ÿ’ก ์นดํ…Œ๊ณ ๋ฆฌ ํด๋ž˜์Šค์˜ ์žฅ์ :

  • ๊ธฐ์กด ํด๋ž˜์Šค ์ˆ˜์ • ์—†์ด ์ƒˆ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ ๊ฐ€๋Šฅ
  • ์ฝ”๋“œ์˜ ๋ชจ๋“ˆ์„ฑ๊ณผ ์žฌ์‚ฌ์šฉ์„ฑ ํ–ฅ์ƒ
  • ๋Ÿฐํƒ€์ž„์— ๋™์ ์œผ๋กœ ๊ธฐ๋Šฅ ํ™•์žฅ ๊ฐ€๋Šฅ
  • ํ…Œ์ŠคํŠธ์™€ ๋ชฉ์—…(Mock-up) ์ž‘์„ฑ ์‹œ ์œ ์šฉ

์ž, ์ด์ œ ์นดํ…Œ๊ณ ๋ฆฌ ํด๋ž˜์Šค๊ฐ€ ๋ญ”์ง€ ๋Œ€์ถฉ ๊ฐ์ด ์˜ค์‹œ๋‚˜์š”? ใ…‹ใ…‹ใ…‹ ๊ทธ๋Ÿผ ์ด์ œ ๋” ๊นŠ์ด ๋“ค์–ด๊ฐ€๋ณผ๊นŒ์š”? ๐ŸŠโ€โ™‚๏ธ

๐Ÿ” ์นดํ…Œ๊ณ ๋ฆฌ ํด๋ž˜์Šค์˜ ๋™์ž‘ ์›๋ฆฌ

์นดํ…Œ๊ณ ๋ฆฌ ํด๋ž˜์Šค๊ฐ€ ๋™์ž‘ํ•˜๋Š” ์›๋ฆฌ๋Š” ์ƒ๊ฐ๋ณด๋‹ค ๊ฐ„๋‹จํ•ด์š”. Groovy ๋Ÿฐํƒ€์ž„์ด 'use' ๋ธ”๋ก์„ ๋งŒ๋‚˜๋ฉด, ํ•ด๋‹น ๋ธ”๋ก ๋‚ด์—์„œ ์นดํ…Œ๊ณ ๋ฆฌ ํด๋ž˜์Šค์˜ static ๋ฉ”์„œ๋“œ๋“ค์„ ๋Œ€์ƒ ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค ๋ฉ”์„œ๋“œ์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค˜์š”.

์ด๋•Œ ์ค‘์š”ํ•œ ์ ์€, ์นดํ…Œ๊ณ ๋ฆฌ ํด๋ž˜์Šค์˜ static ๋ฉ”์„œ๋“œ์˜ ์ฒซ ๋ฒˆ์งธ ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” ํ•ญ์ƒ ํ™•์žฅํ•˜๋ ค๋Š” ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ›์•„์š”. ์šฐ๋ฆฌ ์˜ˆ์ œ์—์„œ๋Š” 'String self'๊ฐ€ ๊ทธ ์—ญํ• ์„ ํ–ˆ์ฃ .


class DateCategory {
    static String yesterday(Date self) {
        return (self - 1).format('yyyy-MM-dd')
    }
}

use(DateCategory) {
    println new Date().yesterday()  // ์–ด์ œ ๋‚ ์งœ ์ถœ๋ ฅ
}

์ด ์˜ˆ์ œ์—์„œ๋Š” Date ํด๋ž˜์Šค์— 'yesterday'๋ผ๋Š” ์ƒˆ ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ–ˆ์–ด์š”. ์ด์ œ Date ๊ฐ์ฒด์—์„œ ๋ฐ”๋กœ ์–ด์ œ ๋‚ ์งœ๋ฅผ ๊ตฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋๋„ค์š”! ๐Ÿ‘

์žฌ๋Šฅ๋„ท์—์„œ ๋‚ ์งœ ๊ด€๋ จ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ๊ฐ€๋ฅด์น˜๋Š” ํŠœํ„ฐ๋ผ๋ฉด, ์ด๋Ÿฐ ๊ธฐ๋Šฅ์„ ํ™œ์šฉํ•ด์„œ ํ•™์ƒ๋“ค์—๊ฒŒ ๋” ์ง๊ด€์ ์ธ ๋‚ ์งœ ์ฒ˜๋ฆฌ ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ค„ ์ˆ˜ ์žˆ๊ฒ ์ฃ ? ์ด๋ ‡๊ฒŒ ์‹ค์šฉ์ ์ธ ์˜ˆ์ œ๋ฅผ ํ†ตํ•ด ํ•™์Šตํ•˜๋ฉด ํ•™์ƒ๋“ค์˜ ์ดํ•ด๋„๊ฐ€ ํ›จ์”ฌ ๋†’์•„์งˆ ๊ฑฐ์˜ˆ์š”! ๐Ÿ“…๐ŸŽ“

๐Ÿš€ ์นดํ…Œ๊ณ ๋ฆฌ ํด๋ž˜์Šค์˜ ํ™œ์šฉ

์นดํ…Œ๊ณ ๋ฆฌ ํด๋ž˜์Šค๋Š” ์ •๋ง ๋‹ค์–‘ํ•œ ์ƒํ™ฉ์—์„œ ์œ ์šฉํ•˜๊ฒŒ ์“ธ ์ˆ˜ ์žˆ์–ด์š”. ๋ช‡ ๊ฐ€์ง€ ์˜ˆ๋ฅผ ๋” ๋“ค์–ด๋ณผ๊นŒ์š”?

  1. ๋‹จ์œ„ ํ…Œ์ŠคํŠธ ์ž‘์„ฑ ์‹œ: ํ…Œ์ŠคํŠธ์šฉ ๋ฉ”์„œ๋“œ๋ฅผ ์ž„์‹œ๋กœ ์ถ”๊ฐ€ํ•  ๋•Œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด์š”.
  2. ๋ ˆ๊ฑฐ์‹œ ์ฝ”๋“œ ๊ฐœ์„ : ์˜ค๋ž˜๋œ ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•˜์ง€ ์•Š๊ณ  ์ƒˆ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์–ด์š”.
  3. DSL(Domain-Specific Language) ๋งŒ๋“ค๊ธฐ: ํŠน์ • ๋„๋ฉ”์ธ์— ํŠนํ™”๋œ ์–ธ์–ด๋ฅผ ๋งŒ๋“ค ๋•Œ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์–ด์š”.
  4. ์ฝ”๋“œ ๊ฐ€๋…์„ฑ ํ–ฅ์ƒ: ๋ณต์žกํ•œ ์—ฐ์‚ฐ์„ ๊ฐ„๋‹จํ•œ ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ๋กœ ๋Œ€์ฒดํ•  ์ˆ˜ ์žˆ์–ด์š”.

์˜ˆ๋ฅผ ๋“ค์–ด, ์žฌ๋Šฅ๋„ท์—์„œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ณผ์ œ๋ฅผ ์ œ์ถœํ•˜๋Š” ์‹œ์Šคํ…œ์„ ๋งŒ๋“ ๋‹ค๊ณ  ์ƒ๊ฐํ•ด๋ด์š”. ํ•™์ƒ๋“ค์˜ ์ฝ”๋“œ๋ฅผ ์ž๋™์œผ๋กœ ํ…Œ์ŠคํŠธํ•˜๋Š” ๊ธฐ๋Šฅ์ด ํ•„์š”ํ•  ๊ฑฐ์˜ˆ์š”. ์ด๋•Œ ์นดํ…Œ๊ณ ๋ฆฌ ํด๋ž˜์Šค๋ฅผ ํ™œ์šฉํ•˜๋ฉด ๊ธฐ์กด ํด๋ž˜์Šค๋“ค์„ ๊ฑด๋“œ๋ฆฌ์ง€ ์•Š๊ณ ๋„ ํ…Œ์ŠคํŠธ์— ํ•„์š”ํ•œ ๋ฉ”์„œ๋“œ๋“ค์„ ์‰ฝ๊ฒŒ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ต๋‹ˆ๋‹ค! ๐Ÿ‘จโ€๐Ÿ’ป


class CodeTesterCategory {
    static boolean passesAllTests(String code) {
        // ์—ฌ๊ธฐ์— ์ฝ”๋“œ ํ…Œ์ŠคํŠธ ๋กœ์ง ๊ตฌํ˜„
        return true  // ์˜ˆ์‹œ๋ฅผ ์œ„ํ•ด ํ•ญ์ƒ true ๋ฐ˜ํ™˜
    }
}

use(CodeTesterCategory) {
    String studentCode = "def add(a, b) { return a + b }"
    if (studentCode.passesAllTests()) {
        println "์ถ•ํ•˜ํ•ด์š”! ๋ชจ๋“  ํ…Œ์ŠคํŠธ๋ฅผ ํ†ต๊ณผํ–ˆ์–ด์š”! ๐ŸŽ‰"
    } else {
        println "์•—, ์•„์‰ฝ๋„ค์š”. ๋‹ค์‹œ ํ•œ๋ฒˆ ๋„์ „ํ•ด๋ณด์„ธ์š”! ๐Ÿ’ช"
    }
}

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด String ํด๋ž˜์Šค์— 'passesAllTests' ๋ฉ”์„œ๋“œ๋ฅผ ์ž„์‹œ๋กœ ์ถ”๊ฐ€ํ•ด์„œ ํ•™์ƒ๋“ค์˜ ์ฝ”๋“œ๋ฅผ ์‰ฝ๊ฒŒ ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ์–ด์š”. coolํ•˜์ง€ ์•Š๋‚˜์š”? ๐Ÿ˜Ž

๐Ÿง™โ€โ™‚๏ธ ์ž„์‹œ ๋ฉ”์„œ๋“œ ์ฃผ์ž…: Groovy์˜ ์‹œ๊ฐ„ ์—ฌํ–‰

์ž, ์ด์ œ "์ž„์‹œ ๋ฉ”์„œ๋“œ ์ฃผ์ž…"์— ๋Œ€ํ•ด ์•Œ์•„๋ณผ ์ฐจ๋ก€์˜ˆ์š”. ์ด ๊ฐœ๋…์€ ์นดํ…Œ๊ณ ๋ฆฌ ํด๋ž˜์Šค์™€ ๋ฐ€์ ‘ํ•˜๊ฒŒ ์—ฐ๊ด€๋˜์–ด ์žˆ์–ด์š”. ์‚ฌ์‹ค, ์นดํ…Œ๊ณ ๋ฆฌ ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์šฐ๋ฆฌ๋Š” ์ด๋ฏธ ์ž„์‹œ ๋ฉ”์„œ๋“œ ์ฃผ์ž…์„ ํ•˜๊ณ  ์žˆ์—ˆ๋˜ ๊ฑฐ์˜ˆ์š”! ๐Ÿคฏ

์ž„์‹œ ๋ฉ”์„œ๋“œ ์ฃผ์ž…์ด๋ž€, ๋ง ๊ทธ๋Œ€๋กœ ๋ฉ”์„œ๋“œ๋ฅผ ์ž„์‹œ๋กœ ์ฃผ์ž…ํ•˜๋Š” ๊ฑฐ์˜ˆ์š”. ๋งˆ์น˜ ์‹œ๊ฐ„ ์—ฌํ–‰์„ ํ•˜๋“ฏ์ด, ์ž ๊น ๋™์•ˆ๋งŒ ํด๋ž˜์Šค์— ์ƒˆ๋กœ์šด ๋Šฅ๋ ฅ์„ ๋ถ€์—ฌํ•˜๋Š” ๊ฑฐ์ฃ . ๊ทธ๋ฆฌ๊ณ  ๊ทธ ๋Šฅ๋ ฅ์€ ์šฐ๋ฆฌ๊ฐ€ ์ •ํ•œ ์‹œ๊ฐ„์ด ์ง€๋‚˜๋ฉด ์‚ฌ๋ผ์ ธ์š”. ๋ฉ‹์ง€์ง€ ์•Š๋‚˜์š”? ๐Ÿ•ฐ๏ธโœจ

๐ŸŽญ ์ž„์‹œ ๋ฉ”์„œ๋“œ ์ฃผ์ž…์˜ ํŠน์ง•:

  • ํŠน์ • ์Šค์ฝ”ํ”„ ๋‚ด์—์„œ๋งŒ ์œ ํšจํ•จ
  • 'use' ๋ธ”๋ก์„ ๋ฒ—์–ด๋‚˜๋ฉด ์ฃผ์ž…๋œ ๋ฉ”์„œ๋“œ๋Š” ์‚ฌ๋ผ์ง
  • ์›๋ณธ ํด๋ž˜์Šค๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š์Œ
  • ๋Ÿฐํƒ€์ž„์— ๋™์ ์œผ๋กœ ๋™์ž‘ํ•จ

์ด ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๋ฉด ์ •๋ง ๋‹ค์–‘ํ•œ ๋งˆ๋ฒ• ๊ฐ™์€ ์ผ๋“ค์„ ํ•  ์ˆ˜ ์žˆ์–ด์š”. ์˜ˆ๋ฅผ ๋“ค์–ด, ์žฌ๋Šฅ๋„ท์—์„œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ฐ•์˜๋ฅผ ๋“ค์„ ๋•Œ, ํŠน์ • ๊ฐœ๋…์„ ์„ค๋ช…ํ•˜๊ธฐ ์œ„ํ•ด ์ผ์‹œ์ ์œผ๋กœ ํด๋ž˜์Šค์— ์ƒˆ๋กœ์šด ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์ฃ . ํ•™์ƒ๋“ค์ด ๊ทธ ๊ฐœ๋…์„ ์ดํ•ดํ•˜๊ณ  ๋‚˜๋ฉด, ๋‹ค์‹œ ์›๋ž˜๋Œ€๋กœ ๋Œ์•„๊ฐˆ ์ˆ˜ ์žˆ์–ด์š”. ๋งˆ์น˜ ์น ํŒ์— ๊ธ€์”จ๋ฅผ ์ผ๋‹ค๊ฐ€ ์ง€์šฐ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ง์ด์—์š”! โœ๏ธ๐Ÿงฝ

๐Ÿ”ฎ ์ž„์‹œ ๋ฉ”์„œ๋“œ ์ฃผ์ž…์˜ ๋งˆ๋ฒ• ๋ถ€๋ฆฌ๊ธฐ

์ž, ์ด์ œ ์‹ค์ œ๋กœ ์ž„์‹œ ๋ฉ”์„œ๋“œ ์ฃผ์ž…์„ ์–ด๋–ป๊ฒŒ ํ•˜๋Š”์ง€ ์‚ดํŽด๋ณผ๊นŒ์š”? ์ฝ”๋“œ๋กœ ๋ณด๋ฉด ๋” ์‰ฝ๊ฒŒ ์ดํ•ดํ•  ์ˆ˜ ์žˆ์„ ๊ฑฐ์˜ˆ์š”.


class MathMagic {
    static Integer squared(Integer self) {
        return self * self
    }
}

use(MathMagic) {
    println 5.squared()  // ์ถœ๋ ฅ: 25
    println 7.squared()  // ์ถœ๋ ฅ: 49
}

// use ๋ธ”๋ก ๋ฐ–์—์„œ๋Š” ์‚ฌ์šฉ ๋ถˆ๊ฐ€
// println 10.squared()  // ์—๋Ÿฌ ๋ฐœ์ƒ!

์šฐ์™€! ๐Ÿ˜ฒ Integer ํด๋ž˜์Šค์— 'squared' ๋ฉ”์„œ๋“œ๋ฅผ ์ž„์‹œ๋กœ ์ถ”๊ฐ€ํ–ˆ์–ด์š”. use ๋ธ”๋ก ์•ˆ์—์„œ๋Š” ๋งˆ์น˜ Integer ํด๋ž˜์Šค๊ฐ€ ์›๋ž˜๋ถ€ํ„ฐ squared ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์—ˆ๋˜ ๊ฒƒ์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ฃ . ํ•˜์ง€๋งŒ use ๋ธ”๋ก์„ ๋ฒ—์–ด๋‚˜๋ฉด ๊ทธ ๋งˆ๋ฒ•์€ ํ’€๋ ค๋ฒ„๋ ค์š”. ใ…‹ใ…‹ใ…‹

์ด๋Ÿฐ ๊ธฐ๋Šฅ์€ ํŠนํžˆ DSL(Domain-Specific Language)์„ ๋งŒ๋“ค ๋•Œ ์œ ์šฉํ•ด์š”. ์˜ˆ๋ฅผ ๋“ค์–ด, ์žฌ๋Šฅ๋„ท์—์„œ ์ฝ”๋”ฉ ๊ณผ์ œ๋ฅผ ์ž๋™์œผ๋กœ ์ฑ„์ ํ•˜๋Š” ์‹œ์Šคํ…œ์„ ๋งŒ๋“ ๋‹ค๊ณ  ์ƒ๊ฐํ•ด๋ด์š”. ์ด๋Ÿด ๋•Œ ์ž„์‹œ ๋ฉ”์„œ๋“œ ์ฃผ์ž…์„ ํ™œ์šฉํ•˜๋ฉด ์ •๋ง ๋ฉ‹์ง„ DSL์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์–ด์š”!


class GradingSystem {
    static void grade(String self, Closure grader) {
        println "์ฑ„์  ์‹œ์ž‘: ${self}"
        grader()
        println "์ฑ„์  ์™„๋ฃŒ!"
    }
    
    static void checkSyntax(String self) {
        println "๋ฌธ๋ฒ• ๊ฒ€์‚ฌ ์ค‘..."
    }
    
    static void runTests(String self) {
        println "ํ…Œ์ŠคํŠธ ์‹คํ–‰ ์ค‘..."
    }
}

use(GradingSystem) {
    "ํ•™์ƒA์˜ ์ฝ”๋“œ".grade {
        it.checkSyntax()
        it.runTests()
    }
}

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ฝ”๋“œ ์ฑ„์  ๊ณผ์ •์„ ์•„์ฃผ ์ง๊ด€์ ์œผ๋กœ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ์–ด์š”. ๋งˆ์น˜ ์ž์—ฐ์–ด๋กœ ์“ฐ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ง์ด์ฃ ! ๐Ÿ‘จโ€๐Ÿซโœ…

๐ŸŽญ ์ž„์‹œ ๋ฉ”์„œ๋“œ ์ฃผ์ž…์˜ ํ™œ์šฉ ์‚ฌ๋ก€

์ž„์‹œ ๋ฉ”์„œ๋“œ ์ฃผ์ž…์€ ์ •๋ง ๋‹ค์–‘ํ•œ ์ƒํ™ฉ์—์„œ ํ™œ์šฉ๋  ์ˆ˜ ์žˆ์–ด์š”. ๋ช‡ ๊ฐ€์ง€ ์žฌ๋ฏธ์žˆ๋Š” ์˜ˆ๋ฅผ ๋” ๋“ค์–ด๋ณผ๊นŒ์š”?

  1. ํ…Œ์ŠคํŠธ ๋”๋ธ” ๋งŒ๋“ค๊ธฐ: ํ…Œ์ŠคํŠธ์šฉ ๊ฐ์ฒด๋ฅผ ์‰ฝ๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ์–ด์š”.
  2. ๋ ˆ๊ฑฐ์‹œ ์ฝ”๋“œ ๋ฆฌํŒฉํ† ๋ง: ๊ธฐ์กด ์ฝ”๋“œ๋ฅผ ๊ฑด๋“œ๋ฆฌ์ง€ ์•Š๊ณ  ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์–ด์š”.
  3. ํ”„๋กœํ† ํƒ€์ดํ•‘: ์ƒˆ๋กœ์šด ์•„์ด๋””์–ด๋ฅผ ๋น ๋ฅด๊ฒŒ ํ…Œ์ŠคํŠธํ•ด๋ณผ ์ˆ˜ ์žˆ์–ด์š”.
  4. ํ”Œ๋Ÿฌ๊ทธ์ธ ์‹œ์Šคํ…œ ๊ตฌํ˜„: ๋™์ ์œผ๋กœ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€/์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ๋Š” ์‹œ์Šคํ…œ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์–ด์š”.

์˜ˆ๋ฅผ ๋“ค์–ด, ์žฌ๋Šฅ๋„ท์—์„œ ์ฝ”๋”ฉ ๋Œ€ํšŒ๋ฅผ ๊ฐœ์ตœํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ด๋ด์š”. ์ฐธ๊ฐ€์ž๋“ค์˜ ์ฝ”๋“œ๋ฅผ ์‹ค์‹œ๊ฐ„์œผ๋กœ ์ฑ„์ ํ•˜๊ณ  ์ˆœ์œ„๋ฅผ ๋งค๊ธฐ๋Š” ์‹œ์Šคํ…œ์ด ํ•„์š”ํ•  ๊ฑฐ์˜ˆ์š”. ์ด๋•Œ ์ž„์‹œ ๋ฉ”์„œ๋“œ ์ฃผ์ž…์„ ํ™œ์šฉํ•˜๋ฉด ์ •๋ง ๋ฉ‹์ง„ ์‹œ์Šคํ…œ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์–ด์š”!


class CodingCompetition {
    static void submit(String self, String participant) {
        println "${participant}๊ฐ€ ์ฝ”๋“œ๋ฅผ ์ œ์ถœํ–ˆ์Šต๋‹ˆ๋‹ค: ${self}"
    }
    
    static int score(String self) {
        // ์‹ค์ œ๋กœ๋Š” ์—ฌ๊ธฐ์— ๋ณต์žกํ•œ ์ฑ„์  ๋กœ์ง์ด ๋“ค์–ด๊ฐˆ ๊ฑฐ์˜ˆ์š”
        return self.length() * 10  // ์˜ˆ์‹œ๋ฅผ ์œ„ํ•ด ๊ฐ„๋‹จํ•œ ์ ์ˆ˜ ๊ณ„์‚ฐ
    }
}

use(CodingCompetition) {
    "def hello(): print('Hello, World!')".submit("์ฐธ๊ฐ€์žA")
    println "์ฐธ๊ฐ€์žA์˜ ์ ์ˆ˜: ${"def hello(): print('Hello, World!')".score()}"
    
    "for i in range(10): print(i)".submit("์ฐธ๊ฐ€์žB")
    println "์ฐธ๊ฐ€์žB์˜ ์ ์ˆ˜: ${"for i in range(10): print(i)".score()}"
}

์™€! ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ฝ”๋”ฉ ๋Œ€ํšŒ ์‹œ์Šคํ…œ์„ ์•„์ฃผ ์ง๊ด€์ ์œผ๋กœ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์–ด์š”. ์ฐธ๊ฐ€์ž๋“ค์˜ ์ฝ”๋“œ๋ฅผ ๋ฌธ์ž์—ด๋กœ ๋ฐ›์•„์„œ ๋ฐ”๋กœ ์ฑ„์ ํ•˜๊ณ  ์ ์ˆ˜๋ฅผ ๋งค๊ธธ ์ˆ˜ ์žˆ์ฃ . ๋ฉ‹์ง€์ง€ ์•Š๋‚˜์š”? ๐Ÿ†๐Ÿ‘จโ€๐Ÿ’ป

๐ŸŽจ ์นดํ…Œ๊ณ ๋ฆฌ ํด๋ž˜์Šค์™€ ์ž„์‹œ ๋ฉ”์„œ๋“œ ์ฃผ์ž…์˜ ์•„๋ฆ„๋‹ค์šด ์กฐํ™”

์ž, ์ด์ œ ์นดํ…Œ๊ณ ๋ฆฌ ํด๋ž˜์Šค์™€ ์ž„์‹œ ๋ฉ”์„œ๋“œ ์ฃผ์ž…์— ๋Œ€ํ•ด ๊ฝค ๋งŽ์ด ์•Œ๊ฒŒ ๋์–ด์š”. ๊ทธ๋Ÿฐ๋ฐ ์ด ๋‘ ๊ฐ€์ง€ ๊ฐœ๋…์ด ์–ด๋–ป๊ฒŒ ์กฐํ™”๋ฅผ ์ด๋ฃจ๋Š”์ง€ ๊ถ๊ธˆํ•˜์ง€ ์•Š๋‚˜์š”? ๐Ÿค”

์‚ฌ์‹ค ์ด ๋‘ ๊ฐœ๋…์€ ๋งˆ์น˜ ์Œ๋‘ฅ์ด์ฒ˜๋Ÿผ ๋ฐ€์ ‘ํ•˜๊ฒŒ ์—ฐ๊ด€๋˜์–ด ์žˆ์–ด์š”. ์นดํ…Œ๊ณ ๋ฆฌ ํด๋ž˜์Šค๋Š” ์ž„์‹œ ๋ฉ”์„œ๋“œ ์ฃผ์ž…์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•˜๋Š” ๋ฉ”์ปค๋‹ˆ์ฆ˜์ด๊ณ , ์ž„์‹œ ๋ฉ”์„œ๋“œ ์ฃผ์ž…์€ ์นดํ…Œ๊ณ ๋ฆฌ ํด๋ž˜์Šค์˜ ์‹ค์ œ ํ™œ์šฉ์ด๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ์ฃ . ๋‘˜์ด ํ•ฉ์ณ์ง€๋ฉด ์ •๋ง ๊ฐ•๋ ฅํ•œ ๋งˆ๋ฒ•์„ ๋ถ€๋ฆด ์ˆ˜ ์žˆ์–ด์š”! โœจ๐Ÿง™โ€โ™‚๏ธ

๐ŸŽญ ์นดํ…Œ๊ณ ๋ฆฌ ํด๋ž˜์Šค์™€ ์ž„์‹œ ๋ฉ”์„œ๋“œ ์ฃผ์ž…์˜ ์‹œ๋„ˆ์ง€:

  • ์ฝ”๋“œ์˜ ์œ ์—ฐ์„ฑ ๊ทน๋Œ€ํ™”
  • ๋Ÿฐํƒ€์ž„์— ๋™์ ์œผ๋กœ ๊ธฐ๋Šฅ ํ™•์žฅ ๊ฐ€๋Šฅ
  • ํ…Œ์ŠคํŠธ ์šฉ์ด์„ฑ ํ–ฅ์ƒ
  • DSL ์ž‘์„ฑ ์‹œ ๊ฐ•๋ ฅํ•œ ๋„๊ตฌ
  • ๋ ˆ๊ฑฐ์‹œ ์ฝ”๋“œ ๊ฐœ์„ ์— ํšจ๊ณผ์ 

์ด ๋‘ ๊ฐœ๋…์„ ์ž˜ ํ™œ์šฉํ•˜๋ฉด, ์—ฌ๋Ÿฌ๋ถ„์˜ ์ฝ”๋“œ๋Š” ๋งˆ์น˜ ์‚ด์•„์žˆ๋Š” ์ƒ๋ช…์ฒด์ฒ˜๋Ÿผ ์œ ์—ฐํ•˜๊ฒŒ ๋ณ€ํ™”ํ•  ์ˆ˜ ์žˆ์–ด์š”. ํ•„์š”ํ•  ๋•Œ ์ƒˆ๋กœ์šด ๋Šฅ๋ ฅ์„ ์–ป์—ˆ๋‹ค๊ฐ€, ํ•„์š” ์—†์–ด์ง€๋ฉด ๊ทธ ๋Šฅ๋ ฅ์„ ๋ฐ˜๋‚ฉํ•  ์ˆ˜ ์žˆ์ฃ . ์ด๊ฒŒ ๋ฐ”๋กœ Groovy์˜ ์ง„์ •ํ•œ ๋งค๋ ฅ์ด์—์š”! ๐Ÿ˜

๐ŸŒˆ ์‹ค์ „ ์˜ˆ์ œ: ์žฌ๋Šฅ๋„ท ์ฝ”๋”ฉ ํŠœํ„ฐ๋ง ์‹œ์Šคํ…œ

์ž, ์ด์ œ ์šฐ๋ฆฌ๊ฐ€ ๋ฐฐ์šด ๊ฐœ๋…๋“ค์„ ์ด๋™์›ํ•ด์„œ ์žฌ๋Šฅ๋„ท์˜ ์ฝ”๋”ฉ ํŠœํ„ฐ๋ง ์‹œ์Šคํ…œ์„ ๋งŒ๋“ค์–ด๋ณผ๊นŒ์š”? ์ด ์‹œ์Šคํ…œ์€ ํ•™์ƒ๋“ค์˜ ์ฝ”๋“œ๋ฅผ ์ž๋™์œผ๋กœ ๋ถ„์„ํ•˜๊ณ , ํ”ผ๋“œ๋ฐฑ์„ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋Šฅ์„ ๊ฐ€์งˆ ๊ฑฐ์˜ˆ์š”. ์ •๋ง ์ฟจํ•˜์ง€ ์•Š๋‚˜์š”? ๐Ÿ˜Ž


class CodingTutor {
    static void analyze(String self) {
        println "์ฝ”๋“œ ๋ถ„์„ ์‹œ์ž‘..."
        self.checkSyntax()
        self.runTests()
        self.provideFeedback()
        println "์ฝ”๋“œ ๋ถ„์„ ์™„๋ฃŒ!"
    }
    
    static void checkSyntax(String self) {
        println "๋ฌธ๋ฒ• ๊ฒ€์‚ฌ ์ค‘... ${self.contains(';') ? '์„ธ๋ฏธ์ฝœ๋ก  ๋ฐœ๊ฒฌ!' : '์„ธ๋ฏธ์ฝœ๋ก  ์—†์Œ.'}"
    }
    
    static void runTests(String self) {
        println "ํ…Œ์ŠคํŠธ ์‹คํ–‰ ์ค‘... ${self.contains('def') ? 'ํ•จ์ˆ˜ ์ •์˜ ํ™•์ธ!' : 'ํ•จ์ˆ˜๊ฐ€ ์—†์–ด์š”.'}"
    }
    
    static void provideFeedback(String self) {
        println "ํ”ผ๋“œ๋ฐฑ: ${self.length() > 50 ? '์ฝ”๋“œ๊ฐ€ ์กฐ๊ธˆ ๊ธธ์–ด์š”. ๊ฐ„๊ฒฐํ•˜๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ์„๊นŒ์š”?' : '์ข‹์€ ์‹œ์ž‘์ด์—์š”!'}"
    }
}

use(CodingTutor) {
    String studentCode = """
        def greet(name):
            print("Hello, " + name + "!")
        
        greet("Groovy")
    """
    
    studentCode.analyze()
}

์šฐ์™€! ๐Ÿ˜ฒ ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ํ•™์ƒ๋“ค์˜ ์ฝ”๋“œ๋ฅผ ์ž๋™์œผ๋กœ ๋ถ„์„ํ•˜๊ณ  ํ”ผ๋“œ๋ฐฑ์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์–ด์š”. ๋ฌผ๋ก  ์ด ์˜ˆ์ œ๋Š” ๋งค์šฐ ๋‹จ์ˆœํ™”๋œ ๋ฒ„์ „์ด์ง€๋งŒ, ์ด๋Ÿฐ ์‹์œผ๋กœ ์ •๋ง ๊ฐ•๋ ฅํ•œ ํŠœํ„ฐ๋ง ์‹œ์Šคํ…œ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฑธ ๋ณด์—ฌ์ฃผ์ฃ .

์žฌ๋Šฅ๋„ท์—์„œ ์ด๋Ÿฐ ์‹œ์Šคํ…œ์„ ํ™œ์šฉํ•˜๋ฉด, ํ”„๋กœ๊ทธ๋ž˜๋ฐ ํŠœํ„ฐ๋“ค์˜ ์—…๋ฌด ํšจ์œจ์„ฑ์„ ํฌ๊ฒŒ ๋†’์ผ ์ˆ˜ ์žˆ์„ ๊ฑฐ์˜ˆ์š”. ํŠœํ„ฐ๋“ค์€ ๋ฐ˜๋ณต์ ์ธ ๊ธฐ์ดˆ ๊ฒ€์‚ฌ๋Š” ์‹œ์Šคํ…œ์— ๋งก๊ธฐ๊ณ , ๋” ์‹ฌ๋„ ์žˆ๋Š” ์ฝ”๋“œ ๋ฆฌ๋ทฐ์— ์ง‘์ค‘ํ•  ์ˆ˜ ์žˆ๊ฒ ์ฃ . ์ด๊ฒŒ ๋ฐ”๋กœ ๊ธฐ์ˆ ์˜ ํž˜์ด์—์š”! ๐Ÿ’ช๐Ÿš€

๐ŸŽญ ์ž„์‹œ ๋ฉ”์„œ๋“œ ์ฃผ์ž…์˜ ์ฃผ์˜์ 

์ž, ์—ฌ๊ธฐ์„œ ์ž ๊น! ์ž„์‹œ ๋ฉ”์„œ๋“œ ์ฃผ์ž…์ด ์ •๋ง ๋ฉ‹์ง€๋‹ค๊ณ  ํ•ด์„œ ๋งˆ๊ตฌ์žก์ด๋กœ ์‚ฌ์šฉํ•˜๋ฉด ์•ˆ ๋ผ์š”. ์ด ๊ธฐ๋Šฅ๋„ ์žฅ๋‹จ์ ์ด ์žˆ๊ฑฐ๋“ ์š”. ๋ช‡ ๊ฐ€์ง€ ์ฃผ์˜ํ•  ์ ์„ ์•Œ์•„๋ณผ๊นŒ์š”?

  1. ๊ฐ€๋…์„ฑ ๋ฌธ์ œ: ๋„ˆ๋ฌด ๋งŽ์€ ์ž„์‹œ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ฝ”๋“œ๋ฅผ ์ดํ•ดํ•˜๊ธฐ ์–ด๋ ค์›Œ์งˆ ์ˆ˜ ์žˆ์–ด์š”.
  2. ์„ฑ๋Šฅ ์ด์Šˆ: ๋Ÿฐํƒ€์ž„์— ๋ฉ”์„œ๋“œ๋ฅผ ์ฃผ์ž…ํ•˜๋Š” ๊ฒƒ์€ ์•ฝ๊ฐ„์˜ ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ์–ด์š”.
  3. ๋””๋ฒ„๊น…์˜ ์–ด๋ ค์›€: ๋™์ ์œผ๋กœ ์ถ”๊ฐ€๋œ ๋ฉ”์„œ๋“œ๋Š” ๋””๋ฒ„๊น… ์‹œ ์ถ”์ ํ•˜๊ธฐ ์–ด๋ ค์šธ ์ˆ˜ ์žˆ์–ด์š”.
  4. ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ๋™์ž‘: ๋‹ค๋ฅธ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ž„์‹œ๋กœ ์ฃผ์ž…๋œ ๋ฉ”์„œ๋“œ์˜ ์กด์žฌ๋ฅผ ๋ชจ๋ฅผ ์ˆ˜ ์žˆ์–ด์š”.