๐Ÿ”ฎ ์”จ-์—์Šค/๐Ÿ— ๋””์ž์ธํŒจํ„ด

[์Šค์œ„ํ”„ํŠธ ๋””์ž์ธํŒจํ„ด] ์ปค๋งจ๋“œ ํŒจํ„ด(Command Pattern)

๊ฐœ๋ฐœํ•˜๋Š” ํ›ˆ์ด 2022. 2. 20. 23:34

์ปค๋งจ๋“œ ํŒจํ„ด(Command Pattern)

The command pattern encapsulate a request as an object, thereby letting you parameterize other objects different requests queue or log request and support undoable operation

 

์ปค๋งจ๋“œ ํŒจํ„ด์€ ์–ด๋–ค ๊ฐ์ฒด๋กœ ๋ณด๋‚ด๋Š” ์š”์ฒญ์„ ์บก์Šํ™”ํ•˜๋Š” ํŒจํ„ด์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์š”์ฒญ์„ ๋ณด๋‚ด๋Š” ๊ฐ์ฒด๋‚˜, ์š”์ฒญ์„ ๋ฐ›๋Š” ๊ฐ์ฒด์™€ ์ƒ๊ด€์—†์ด ์š”์ฒญ ์ž์ฒด๋ฅผ ๊ฐ์ฒด๋กœ ์บก์Šํ™” ํ•˜๋Š” ํŒจํ„ด์ด์ฃ . ์ด๋ ‡๊ฒŒ ์š”์ฒญ์„ ์บก์Šํ™” ํ•œ๋‹ค๋ฉด, ์–ด๋–ค ์ž‘์—…์— ๋Œ€ํ•œ ์š”์ฒญ๋“ค์„ ๊ฐ์ฒด๋กœ ๋งŒ๋“ค์–ด ๋‘๊ณ , ํ•„์š”์— ๋”ฐ๋ผ์„œ ๊ฐ์ฒด์—๊ฒŒ ์ „๋‹ฌํ•˜๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์š”์ฒญ์— ๋Œ€ํ•œ ๊ฐ์ฒด๋“ค์„ ๋ฆฌ์ŠคํŠธ์— ๋‹ด์•„๋‘๋ฉด ์–ด๋–ค ์ ˆ์ฐจ์  ์ž‘์—…๋“ค์„ ์ˆœ์„œ๋Œ€๋กœ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ํ˜น์€, ์–ด๋–ค ์ž‘์—…๋“ค์ด ๋ฐ˜๋“œ์‹œ ์ˆœ์„œ๋Œ€๋กœ ์ฒ˜๋ฆฌ๋˜์–ด์•ผ ํ•˜๊ณ , ์ด ์ˆœ์„œ๊ฐ€ ์ค‘๋ณต์ ์œผ๋กœ ์‚ฌ์šฉ๋œ๋‹ค๋ฉด, ์š”์ฒญ ๊ฐ์ฒด๋“ค์„ ํฌํ•จํ•˜๋Š” ํ•˜๋‚˜์˜ ํฐ ์š”์ฒญ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ฒ ์ฃ .

๋˜, ์ •์˜์—์„œ๋Š” support undoable operation ์ด๋ผ๋Š” ํ‘œํ˜„์„ ์‚ฌ์šฉํ•˜๋Š”๋ฐ์š”, ์š”์ฒญ ๊ฐ์ฒด๋“ค์€ ์š”์ฒญ์„ ์—ญ์œผ๋กœ ์ˆ˜ํ–‰ํ•˜๋Š”(undo) ์ž‘์—…์„ ํฌํ•จํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ˆœ์ฐจ์ ์œผ๋กœ ์‹คํ–‰ํ–ˆ๋˜ ์š”์ฒญ ๊ฐ์ฒด๋“ค์„ ์—ญ์ˆœ์œผ๋กœ ์‹คํ–‰ํ•˜๋ฉด ์ž‘์—…์„ ์ทจ์†Œํ•˜๋Š” ์š”์ฒญ์„ ๋งŒ๋“œ๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•ด์ง‘๋‹ˆ๋‹ค.

 

์ปค๋งจ๋“œ ํŒจํ„ด ์ดํ•ดํ•˜๊ธฐ

์ปค๋งจ๋“œ ํŒจํ„ด์„ ์ดํ•ดํ•˜๊ธฐ ์œ„ํ•ด์„œ ์ปค๋งจ๋“œ ํŒจํ„ด์„ ๊ตฌ์„ฑํ•˜๋Š” ๊ตฌ์„ฑ์š”์†Œ๋ฅผ ์ •๋ฆฌํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์ปค๋งจ๋“œ ํŒจํ„ด์€ ํฌ๊ฒŒ ์š”์ฒญ์„ ๋ณด๋‚ด๋Š” Invoker, ์š”์ฒญ์„ ์บก์Šํ™”ํ•œ Command์™€ ๊ทธ ์ธํ„ฐํŽ˜์ด์Šค์ธ Commanding, ๊ทธ๋ฆฌ๊ณ  ์š”์ฒญ ๊ฐ์ฒด์˜ ๋กœ์ง์„ ํ†ตํ•ด ์˜ํ–ฅ์„ ๋ฐ›๋Š” Receiver ๋กœ ๊ตฌ์„ฑ์ด ๋ฉ๋‹ˆ๋‹ค. Invoker๋Š” ์ƒํ™ฉ์— ๋”ฐ๋ผ ์—ฌ๋Ÿฌ๊ฐœ์˜ Command๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์ฃ .

๊ทธ๋ฆฌ๊ณ  ๊ฐ ๊ฐ์ฒด๋“ค์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ€์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

Invoker๋Š” ์ด ๊ฐ์ฒด์—์„œ ์‚ฌ์šฉํ•  ์š”์ฒญ ๊ฐ์ฒด์ธ Command ํƒ€์ž…์˜ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑ์ž๋ฅผ ํ†ตํ•ด ์ฃผ์ž…๋ฐ›์„ ์ˆ˜ ์žˆ๋„๋ก ๋˜์–ด ์žˆ์–ด์š”. ๊ทธ๋ฆฌ๊ณ  Command์™€ ์ธํ„ฐํŽ˜์ด์Šค์ธ Commanding์€ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๋Š” execute ๋ฉ”์„œ๋“œ, ๊ทธ๋ฆฌ๊ณ  ๊ทธ ์ฒ˜๋ฆฌ๋ฅผ ์—ญ์œผ๋กœ ์ˆ˜ํ–‰ํ•˜๋Š” unexecute ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ€์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์—ญ์œผ๋กœ ์ˆ˜ํ–‰ํ•œ๋‹ค๋Š” ๋ง์€ ์ •์˜์—์„œ ๋‹ค๋ฃจ์—ˆ๋˜ undo ๋ฅผ ์˜๋ฏธํ•ด์š”.

๋งŒ์•ฝ ์šฐ๋ฆฌ๊ฐ€ TV ๋ฆฌ๋ชจ์ปจ์„ ์ปค๋งจ๋“œ ํŒจํ„ด์œผ๋กœ ๊ตฌํ˜„ํ•œ๋‹ค๊ณ  ํ•œ๋‹ค๋ฉด, Command ์ค‘ ํ•˜๋‚˜๋Š” ์ „์›์„ ํ‚ค๋Š” ๋™์ž‘์— ๋Œ€ํ•œ ์š”์ฒญ์ด ๋  ์ˆ˜ ์žˆ๊ฒ ์ฃ ? ์ด๋•Œ execute๋Š” ์ „์›์„ ํ‚ค๋Š” ๋ฉ”์„œ๋“œ๊ฐ€ ๋  ๊ฒƒ์ด๊ณ , unexecute๋Š” ์ „์›์„ ์ข…๋ฃŒํ•˜๋Š” ๋ฉ”์„œ๋“œ๊ฐ€ ๋  ๊ฑฐ์—์š”.

๊ทธ๋Ÿผ ๊ฐ„๋‹จํ•œ TV ๋ฆฌ๋ชจ์ปจ ์ปจ์…‰์„ ์ปค๋งจ๋“œ ํŒจํ„ด์œผ๋กœ ๋งŒ๋“ค๋ฉด์„œ ํ™•์‹คํ•˜๊ฒŒ ์ดํ•ด๋ฅผ ํ•ด๋ณด๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™๋„ค์š”.

 

TV ๋ฆฌ๋ชจ์ปจ ๊ตฌํ˜„ํ•˜๊ธฐ

๋จผ์ € ์ปค๋งจ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์˜ํ–ฅ์„ ๋ฐ›๊ฒŒ๋  Invoker์™€ Receiver ๋ถ€ํ„ฐ ์ •์˜ํ•ด๋ณผ๊ฒŒ์š”. ๋ฆฌ๋ชจ์ปจ์˜ ์ปค๋งจ๋“œ๋Š” TV๋ฅผ ๋ˆ๋‹ค, ์ผ ๋‹ค, ์ฑ„๋„์„ ์ด๋™ํ•œ๋‹ค, ์ด์ „ ์ฑ„๋„๋กœ ์ด๋™ํ•œ๋‹ค ์ด๋Ÿฐ ๊ฒƒ๋“ค์ด ๋˜๊ฒ ์ฃ ? ๊ทธ๋Ÿผ ์ปค๋งจ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฆฌ๋ชจ์ปจ์„ Invoker๋กœ ๋‘๊ณ , ์˜ํ–ฅ์„ ๋ฐ›๊ฒŒ๋˜๋Š” TV๋ฅผ Receiver๋กœ ์ •์˜ํ•˜๋ฉด ๋  ๊ฒƒ ๊ฐ™๋„ค์š”.

TV๊ฐ€ ์ˆ˜ํ–‰ํ•˜๊ฒŒ๋  ๋™์ž‘์€ ์œ„์—์„œ ๋‚˜์—ดํ–ˆ๋˜ ๊ฒƒ ์ฒ˜๋Ÿผ, ๋„๊ธฐ, ์ผœ๊ธฐ, ์œ„๋กœ ํ•œ ์ฑ„๋„ ์ด๋™, ์•„๋ž˜๋กœ ํ•œ ์ฑ„๋„ ์ด๋™์œผ๋กœ ์„ค์ •ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

final class TVRemoteControl {
    private let onCommand: Commanding
    private let offCommand: Commanding
    private let upCommand: Commanding
    private let downCommand: Commanding
    
    init(
        on: Commanding,
        off: Commanding,
        up: Commanding,
        down: Commanding
    ) {
        self.onCommand = on
        self.offCommand = off
        self.upCommand = up
        self.downCommand = down
    }
    
    func on() {
        self.onCommand.execute()
    }
    
    func off() {
        self.offCommand.execute()
    }
    
    func up() {
        self.upCommand.execute()
    }
    
    func down() {
        self.downCommand.execute()
    }
}

๊ทธ๋Ÿผ ์ด๋ ‡๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๊ฒ ์ฃ . 

์šฐ๋ฆฌ๋Š” ์ปค๋งจ๋“œ ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฆฌ๋ชจ์ปจ์ด ์ง์ ‘ TV๋ฅผ ์กฐ์ž‘ํ•˜๊ฒŒ ํ•˜์ง€ ์•Š๊ณ , ๋ฆฌ๋ชจ์ปจ์ด ๊ฐ€์ง€๊ฒŒ๋  ์ปค๋งจ๋“œ๋ฅผ ํ†ตํ•ด TV๋ฅผ ์กฐ์ž‘ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๊ฐ ๋™์ž‘์— ๋Œ€ํ•œ ์š”์ฒญ์„ ๊ฐ์ฒด๋กœ ์บก์Šํ™”ํ•˜๋ ค๋ฉด ์ด ๋„ค ๊ฐœ์˜ ์ปค๋งจ๋“œ ๊ฐ์ฒด๊ฐ€ ํ•„์š”ํ•˜๊ฒŒ ๋˜์ฃ .

๊ทธ๋ฆฌ๊ณ  ์ปค๋งจ๋“œ ๊ฐ์ฒด๋ฅผ ์ง์ ‘ ์†Œ์œ ํ•˜์ง€ ์•Š๊ณ , ์•ž์„œ ์ •๋ฆฌํ–ˆ๋˜๋Œ€๋กœ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์†Œ์œ ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์ธํ„ฐํŽ˜์ด์Šค๋Š” ๋‹จ์ˆœํ•˜๊ฒŒ execute์™€ unexecute์˜ ์กฐํ•ฉ์œผ๋กœ ์‰ฝ๊ฒŒ ์ •์˜ํ•  ์ˆ˜ ์žˆ์–ด์š”.

protocol Commanding {
    func execute()
    func unexecute()
}

๊ทธ๋ฆฌ๊ณ  on, off, up, down ๊ฐ๊ฐ์— ๋Œ€ํ•œ ๊ฐ์ฒด๋ฅผ Commanding์„ ์ฑ„ํƒํ•˜๋Š” ๊ฐ์ฒด๋กœ ๊ตฌํ˜„ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์˜ํ–ฅ์„ ๋ฐ›์„ Recevier๋Š” ์ด ๊ฐ์ฒด๊ฐ€ ์†Œ์œ ํ•˜๊ณ  ์žˆ์–ด์•ผ๊ฒ ์ฃ ?

final class OnCommand: Commanding {
    let tv: TV
    
    init(tv: TV) {
        self.tv = tv
    }
    
    func execute() {
        tv.on()
    }
    
    func unexecute() {
        tv.off()
    }
}

final class OffCommand: Commanding {
    let tv: TV
    
    init(tv: TV) {
        self.tv = tv
    }
    
    func execute() {
        tv.off()
    }
    
    func unexecute() {
        tv.on()
    }
}

final class UpCommand: Commanding {
    let tv: TV
    
    init(tv: TV) {
        self.tv = tv
    }
    
    func execute() {
        tv.up()
    }
    
    func unexecute() {
        tv.down()
    }
}


final class DownCommand: Commanding {
    let tv: TV
    
    init(tv: TV) {
        self.tv = tv
    }
    
    func execute() {
        tv.down()
    }
    
    func unexecute() {
        tv.up()
    }
}

์ด๋ ‡๊ฒŒ ๊ฐ„๋‹จํ•˜๊ฒŒ ์ปค๋งจ๋“œ ๊ฐ์ฒด๋ฅผ ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์€ ์ฃผ์ž…๋œ TVํƒ€์ž…์˜ ๊ฐ์ฒด์ด์ง€๋งŒ ํ•ด๋‹น ๋™์ž‘์— ๋Œ€ํ•œ ์š”์ฒญ์„ ์ปค๋งจ๋“œ ๊ฐ์ฒด๊ฐ€ ํ•˜๊ฒŒ๋˜๋Š” ๊ฒƒ์ด์ฃ . 

๊ทธ๋Ÿผ ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“ค์–ด์„œ ์‚ฌ์šฉํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

let appleTV = TV()
let appleRemoteControl = TVRemoteControl(
    on: OnCommand(tv: appleTV),
    off: OffCommand(tv: appleTV),
    up: UpCommand(tv: appleTV),
    down: DownCommand(tv: appleTV)
)

appleRemoteControl.on()
appleRemoteControl.off()
appleRemoteControl.down()
appleRemoteControl.up()

//on
//off
//down
//up
//Program ended with exit code: 0

์ด๋ ‡๊ฒŒ Receiver์ธ TV๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•œ ๋’ค์— ์ปค๋งจ๋“œ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๋ฉฐ TV ์ธ์Šคํ„ด์Šค๋ฅผ ์ฃผ์ž…ํ•˜๊ณ , ์ƒ์„ฑ๋œ ์ปค๋งจ๋“œ ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฆฌ๋ชจ์ปจ ์ธ์Šคํ„ด์Šค์— ์ฃผ์ž…ํ•˜๋ฉด ์ปค๋งจ๋“œ ํŒจํ„ด์„ ํ†ตํ•ด ๋ฆฌ๋ชจ์ปจ์œผ๋กœ TV์— ๋™์ž‘์„ ์š”์ฒญํ•˜๋„๋ก ๊ตฌํ˜„์ด ๋ฉ๋‹ˆ๋‹ค.

 

Undo ์‚ฌ์šฉํ•˜๊ธฐ

์ด๋ฒˆ์—” undo๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ƒํ™ฉ์„ ์ƒ๊ฐํ•ด๋ณผ๊ฒŒ์š”. ๋งŒ์•ฝ ๋ฆฌ๋ชจ์ปจ์— ํŠน์ˆ˜ํ•œ ๊ธฐ๋Šฅ์ด ์žˆ์–ด์„œ ์ง€๊ธˆ๊นŒ์ง€ ์ˆ˜ํ–‰ํ–ˆ๋˜ ๋ชจ๋“  ๋ฆฌ๋ชจ์ปจ ๋™์ž‘์„ ๊ธฐ๋กํ•˜๊ณ  ์—ญ์œผ๋กœ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ์–ด๋–จ๊นŒ์š”? ๊ตฌํ˜„์„ ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

final class TVRemoteControl {
    private let onCommand: Commanding
    private let offCommand: Commanding
    private let upCommand: Commanding
    private let downCommand: Commanding
    private var commandHistory: [Commanding] = []
    
    init(
        on: Commanding,
        off: Commanding,
        up: Commanding,
        down: Commanding
    ) {
        self.onCommand = on
        self.offCommand = off
        self.upCommand = up
        self.downCommand = down
    }
    
    func on() {
        self.onCommand.execute()
        self.commandHistory.append(self.onCommand)
    }
    
    func off() {
        self.offCommand.execute()
        self.commandHistory.append(self.offCommand)
    }
    
    func up() {
        self.upCommand.execute()
        self.commandHistory.append(self.upCommand)
    }
    
    func down() {
        self.downCommand.execute()
        self.commandHistory.append(self.downCommand)
    }
}

๊ฐ€์žฅ ๋จผ์ € Commanding ํƒ€์ž…์„ ๋‹ด์„ ์ˆ˜ ์žˆ๋Š” ๋ฆฌ์ŠคํŠธ๋ฅผ ํ•˜๋‚˜ ๋งŒ๋“ค๊ณ , ์ƒˆ๋กœ์šด ์š”์ฒญ์„ ๋ณด๋‚ผ ๋•Œ๋งˆ๋‹ค ์š”์ฒญ์˜ ๋ž˜ํผ๋Ÿฐ์Šค๋ฅผ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋„๋ก ํ–ˆ์–ด์š”. ์‚ฌ์‹ค enum์œผ๋กœ ์š”์ฒญ์˜ ํƒ€์ž…๋“ค์„ ๋งŒ๋“ค์–ด์„œ ๋ฐฐ์—ด์— ๊ฐ’ํƒ€์ž…์„ ์ฃผ๋Š” ๊ฒƒ์ด ์ œ์ผ ์ข‹๊ฒ ์ง€๋งŒ ์—ฌ๊ธฐ์„œ๋Š” ์ผ๋‹จ ์ด๋ ‡๊ฒŒ ์ง„ํ–‰ํ• ๊ฒŒ์š”.

๊ทธ๋ฆฌ๊ณ  ์ด์ œ ์—ญ์ˆœ์œผ๋กœ ๋™์ž‘ ์ทจ์†Œ๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด์„œ ํ•œ๊ฐ€์ง€ ๋ฉ”์„œ๋“œ๋ฅผ ๋” ์ถ”๊ฐ€ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

func reverseAll() {
    while self.commandHistory.isEmpty == false {
        let command = self.commandHistory.removeLast()
        command.unexecute()
    }
}

๋ฆฌ์ŠคํŠธ์— ์ €์žฅ๋œ ์ปค๋งจ๋“œ๋“ค์„ ์Šคํƒ์ฒ˜๋Ÿผ ๋’ค์—์„œ๋ถ€ํ„ฐ ์ œ๊ฑฐํ•˜๋ฉด์„œ unexecute๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋ฉ”์„œ๋“œ์ž…๋‹ˆ๋‹ค.

appleRemoteControl.on()
appleRemoteControl.off()
appleRemoteControl.down()
appleRemoteControl.up()
appleRemoteControl.reverseAll()

//on
//off
//down
//up
//down
//up
//on
//off
//Program ended with exit code: 0

์œ„์—์„œ ์‚ฌ์šฉํ–ˆ๋˜ ์˜ˆ์ œ ๋์— reverseAll์„ ํ˜ธ์ถœํ•˜๋ฉด, ์ง€๊ธˆ๊นŒ์ง€ ์ˆ˜ํ–‰ํ–ˆ๋˜ ์ž‘์—…๋“ค์„ ์ˆœ์ฐจ์ ์œผ๋กœ ์ทจ์†Œํ•˜๋Š” ๋™์ž‘์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๊ฐ„๋‹จํ•˜์ฃ ?

 

๋งˆ๋ฌด๋ฆฌ

์ด๋ ‡๊ฒŒ ํ•ด์„œ ์ปค๋งจ๋“œ ํŒจํ„ด์„ ์ •๋ฆฌํ•ด๋ณด์•˜์Šต๋‹ˆ๋‹ค. iOS์—์„œ ์ž์ฃผ ์‚ฌ์šฉํ•˜๋Š” ์•„ํ‚คํ…์ฒ˜ ํŒจํ„ด์ธ MVVM ์—์„œ ๋ทฐ ์ปจํŠธ๋กค๋Ÿฌ์™€ ๋ทฐ ๋ชจ๋ธ ์‚ฌ์ด์˜ ์˜์กด์„ฑ์„ ๋Š์Šจํ•˜๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด์„œ ์ปค๋งจ๋“œ ํŒจํ„ด์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์„ํ…๋ฐ์š”, ์ด๋ฒคํŠธ๋ฅผ ๋ฐ›์•„์„œ ๋‚ ๋ฆฌ๋Š” ๋ทฐ ์ปจํŠธ๋กค๋Ÿฌ๊ฐ€ Invoker๊ฐ€ ๋˜๊ฒ ๊ณ , ์ด๋ฒคํŠธ๋ฅผ ๋ฐ›์•„ ์ฒ˜๋ฆฌํ•˜๋Š” Receiver๊ฐ€ ๋ทฐ๋ชจ๋ธ, ๋ทฐ๋ชจ๋ธ์„ ์†Œ์œ ํ•˜๊ณ  ํŠน์ •ํ•œ ์ด๋ฒคํŠธ๋ฅผ ์บก์Šํ™”ํ•œ Command๋กœ ๊ตฌ์„ฑํ•œ๋‹ค๋ฉด, ๋ทฐ ์ปจํŠธ๋กค๋Ÿฌ์™€ ๋ทฐ๋ชจ๋ธ์€ ์„œ๋กœ๋ฅผ ์•Œ์ง€ ๋ชปํ•œ ์ฑ„๋กœ ์ด๋ฒคํŠธ๋ฅผ ์ „๋‹ฌํ•˜๊ณ  ๋ฐ์ดํ„ฐ ๋ฐ”์ธ๋”ฉ์„ ํ†ตํ•ด ๋ทฐ๋ฅผ ์—…๋ฐ์ดํŠธ ํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

์ž˜๋ชป๋œ ๋‚ด์šฉ์ด๋‚˜ ํ‹€๋ฆฐ ๋‚ด์šฉ์ด ์žˆ๋‹ค๋ฉด ์•Œ๋ ค์ฃผ์„ธ์š”..! ์ €๋„ ๋‹ค์‹œ ๊ณต๋ถ€ํ•˜๋ฉด์„œ ๊ณ ๋ฏผํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์˜ค๋Š˜๋„ ์ฝ์–ด์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค :)