U E D R , A S I H C RSS

Gof/Command


1. Command


1.1. Intent

request ๋ฅผ ๊ฐ์ฒด๋กœ ์บก์Аํ™” ์‹œํ‚ด์œผ๋กœ์„œ ๋‹ค๋ฅธ request๋“ค์„ ๊ฐ€์ง„ ํด๋ผ์ด์–ธํŠธ๋ฅผ ์ธ์žํ™”์‹œํ‚ค๊ฑฐ๋‚˜, request๋ฅผ queueํ•˜๊ฑฐ๋‚˜ ๋Œ€๊ธฐ์‹œํ‚ค๋ฉฐ, undo๊ฐ€ ๊ฐ€๋Šฅํ•œ ๋ช…๋ น์„ ์ง€์›ํ•œ๋‹ค.

1.2. Also Known As

Action, Transaction

1.3. Motivation

๋•Œ๋•Œ๋กœ ์š”์ฒญ๋ฐ›์€ ๋ช…๋ น์ด๋‚˜ request๋ฅผ ๋ฐ›๋Š” ๊ฐ์ฒด์— ๋Œ€ํ•œ ์ •๋ณด์—†์ด ๊ฐ์ฒด๋“ค์—๊ฒŒ request๋ฅผ ๋„˜๊ฒจ์ค„ ๋•Œ๊ฐ€ ์žˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด user interface tookit์€ button์ด๋‚˜ menu์ฒ˜๋Ÿผ ์‚ฌ์šฉ์ž ์ž…๋ ฅ์— ๋Œ€ํ•ด ์‘๋‹ตํ•˜๊ธฐ ์œ„ํ•ด ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฐ์ฒด๋“ค์„ ํฌํ•จํ•œ๋‹ค. ํ•˜์ง€๋งŒ, ์˜ค์ง toolkit์„ ์‚ฌ์šฉํ•˜๋Š” ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜๋งŒ์ด ์–ด๋–ค ๊ฐ์ฒด๊ฐ€ ์–ด๋–ค์ผ์„ ํ•ด์•ผ ํ• ์ง€ ์•Œ๊ณ  ์žˆ์œผ๋ฏ€๋กœ, toolkit์€ button์ด๋‚˜ menu์— ๋Œ€ํ•ด์„œ ์š”์ฒญ์— ๋Œ€ํ•ด ๋ช…์‹œ์ ์œผ๋กœ ๊ตฌํ˜„์„ ํ•  ์ˆ˜ ์—†๋‹ค. toolkit ๋””์ž์ด๋„ˆ๋กœ์„œ ์šฐ๋ฆฌ๋Š” request๋ฅผ ๋ฐ›๋Š” ๊ฐœ์ฒด๋‚˜ request๋ฅผ ์ฒ˜๋ฆฌํ•  operations์— ๋Œ€ํ•ด ์•Œ์ง€ ๋ชปํ•œ๋‹ค.

Command Pattern์€ request ๋ฅผ ๊ฐ์ฒดํ™”ํ•จ์œผ๋กœ์„œ toolkit ๊ฐ์ฒด๋กœ ํ•˜์—ฌ๊ธˆ ๋ถˆํŠน์ •ํ•œ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐ์ฒด์— ๋Œ€ํ•œ request๋ฅผ ๋งŒ๋“ค๊ฒŒ ํ•œ๋‹ค. ์ด ๊ฐ์ฒด๋Š” ๋‹ค๋ฅธ ๊ฐ์ฒด์ฒ˜๋Ÿผ ์ €์žฅ๋  ์ˆ˜ ์žˆ์œผ๋ฉฐ pass around ๊ฐ€๋Šฅํ•˜๋‹ค. ์ด pattern์˜ key๋Š” ์ˆ˜ํ–‰ํ•  ๋ช…๋ น์–ด์— ๋Œ€ํ•œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์„ ์–ธํ•˜๋Š” ์ถ”์ƒ Command class์— ์žˆ๋‹ค. ์ด ์ธํ„ฐํŽ˜์ด์Šค์˜ ๊ฐ€์žฅ ๋‹จ์ˆœํ•œ ํ˜•ํƒœ์—์„œ๋Š” ์ถ”์ƒ์ ์ธ Execute operation์„ ํฌํ•จํ•œ๋‹ค. ๊ตฌ์ฒดํ™”๋œ Command subclass๋“ค์€ request์— ๋Œ€ํ•œ receiver๋ฅผ instance ๋ณ€์ˆ˜๋กœ ์ €์žฅํ•˜๊ณ  request๋ฅผ invokeํ•˜๊ธฐ ์œ„ํ•œ Execute operation์„ ๊ตฌํ˜„ํ•จ์œผ๋กœ์„œ receiver-action ์ง์„ ๊ตฌ์ฒดํ™”์‹œํ‚จ๋‹ค. The receiver has the knowledge required to carry out the request.


Menu๋Š” ์‰ฝ๊ฒŒ Command Object๋กœ ๊ตฌํ˜„๋  ์ˆ˜ ์žˆ๋‹ค. Menu ์˜ ๊ฐ๊ฐ์˜ ์„ ํƒ์€ ๊ฐ๊ฐ MenuItem ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค์ด๋‹ค. Application ํด๋ž˜์Šค๋Š” ์ด ๋ฉ”๋‰ด๋“ค๊ณผ ๋‚˜๋จธ์ง€ ์œ ์ € ์ธํ„ฐํŽ˜์ด์Šค์— ๋”ฐ๋ผ์„œ ๋ฉ”๋‰ด์•„์ดํ…œ์„ ๊ตฌ์„ฑํ•œ๋‹ค. Application ํด๋ž˜์Šค๋Š” ์œ ์ €๊ฐ€ ์—ด Document ๊ฐ์ฒด์˜ track์„ ์œ ์ง€ํ•œ๋‹ค.

์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ๊ฐ๊ฐ์˜ ๊ตฌ์ฒด์ ์ธ Command ์˜ subclass๋“ค๋กœ ๊ฐ๊ฐ€๊ฐMenuItem ๊ฐ์ฒด๋ฅผ ์„ค์ •ํ•œ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ MenuItem์„ ์„ ํƒํ–ˆ์„๋•Œ MenuItem์€ ๋ฉ”๋‰ด์•„์ดํ…œ์˜ ํ•ด๋‹น ๋ช…๋ น์œผ๋กœ์„œ Execute oeration์„ ํ˜ธ์ถœํ•˜๊ณ , Execute๋Š” ์‹ค์ œ์˜ ๋ช…๋ น์„ ์ˆ˜ํ–‰ํ•œ๋‹ค. MenuItem๊ฐ์ฒด๋“ค์€ ์ž์‹ ๋“ค์ด ์‚ฌ์šฉํ•  Command์˜ subclass์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์ง€ ์•Š๋‹ค. Command subclass๋Š” ํ•ด๋‹น request์— ๋Œ€ํ•œ receiver๋ฅผ ์ €์žฅํ•˜๊ณ , receiver์˜ ํ•˜๋‚˜๋‚˜ ๊ทธ ์ด์ƒ์˜ ๋ช…๋ น์–ด๋“ค์„ invokeํ•œ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด PasteCommand๋Š” clipboard์— ์žˆ๋Š” text๋ฅผ Document์— ๋ถ™์ด๋Š” ๊ธฐ๋Šฅ์„ ์ง€์›ํ•œ๋‹ค. PasteCommand ์˜ receiver๋Š” ์ธ์Šคํ„ด์Šคํ™”ํ• ๋•Œ ์„ค์ •๋˜์–ด์žˆ๋Š” Docuemnt๊ฐ์ฒด์ด๋‹ค. Execute ๋ช…๋ น์€ ํ•ด๋‹น ๋ช…๋ น์˜ receiver์ธ Document์˜ Paste operation ์„ invoke ํ•œ๋‹ค.


OpenCommand์˜ Execute operation์€ ๋‹ค๋ฅด๋‹ค. OpenCommand๋Š” ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ฌธ์„œ ์ด๋ฆ„์„ ๋ฌผ์€๋’ค, ๋Œ€์‘ํ•˜๋Š” Document ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ณ , ํ•ด๋‹น ๋ฌธ์„œ๋ฅผ ์—ฌ๋Š” ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์— ๋ฌธ์„œ๋ฅผ ์ถ”๊ฐ€ํ•œ ๋’ค (MDI๋ฅผ ์ƒ๊ฐํ• ๊ฒƒ) ๋ฌธ์„œ๋ฅผ ์—ฐ๋‹ค.


๋•Œ๋•Œ๋กœ MenuItem์€ ์—ฐ์†๋œ ๋ช…๋ น์–ด๋“ค์˜ ์ผ๊ด„์ˆ˜ํ–‰์„ ํ•„์š”๋กœ ํ•œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด์„œ ํ•ด๋‹น ํŽ˜์ด์ง€๋ฅผ ์ค‘์•™์— ๋†“๊ณ  ์ผ๋ฐ˜ํฌ๊ธฐํ™” ์‹œํ‚ค๋Š” MenuItem์€ CenterDocumentCommand ๊ฐ์ฒด์™€ NormalSizeCommand ๊ฐ์ฒด๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ฐฉ์‹์œผ๋กœ ๋ช…๋ น์–ด๋“ค์„ ์ด์–ด์ง€๊ฒŒ ํ•˜๋Š” ๊ฒƒ์€ ์ผ๋ฐ˜์ ์ด๋ฏ€๋กœ, ์šฐ๋ฆฌ๋Š” ๋ณต์ˆ˜๋ช…๋ น์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•œ MenuItem์„ ํ—ˆ์šฉํ•˜๊ธฐ ์œ„ํ•ด MacroCommand๋ฅผ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค. MacroCommand๋Š” ๋‹จ์ˆœํžˆ ๋ช…๋ น์–ด๋“ค์˜ sequence๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” Command subclass์˜ ๊ตฌ์ฒดํ™”์ด๋‹ค. MacroCommand๋Š” MacroCommand๋ฅผ ์ด๋ฃจ๊ณ  ์žˆ๋Š” command๋“ค์ด ๊ทธ๋“ค์˜ receiver๋ฅผ ์ •์˜ํ•˜๋ฏ€๋กœ ๋ช…์‹œ์ ์ธ receiver๋ฅผ ๊ฐ€์ง€์ง€ ์•Š๋Š”๋‹ค.


์ด๋Ÿฌํ•œ ์˜ˆ๋“ค์—์„œ, ์–ด๋–ป๊ฒŒ Command pattern์ด ํ•ด๋‹น ๋ช…๋ น์„ invokeํ•˜๋Š” ๊ฐ์ฒด์™€ ๋ช…๋ น์„ ์ˆ˜ํ–‰ํ•˜๋Š” ์ •๋ณด๋ฅผ ๊ฐ€์ง„ ๊ฐ์ฒด๋ฅผ ๋ถ„๋ฆฌํ•˜๋Š”์ง€ ์ฃผ๋ชฉํ•˜๋ผ. ์ด๋Ÿฌํ•จ์€ ์œ ์ €์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋””์ž์ธํ•จ์— ์žˆ์–ด์„œ ๋งŽ์€ ์œ ์—ฐ์„ฑ์„ ์ œ๊ณตํ•œ๋‹ค. ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ๋‹จ์ง€ menu์™€ push button์ด ๊ฐ™์€ ๊ตฌ์ฒด์ ์ธ Command subclass์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ๊ณต์œ ํ•จ์œผ๋กœ์„œ menu ์™€ push button ์ธํ„ฐํŽ˜์ด์Šค ์ œ๊ณตํ•  ์ˆ˜ ์žˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๋™์ ์œผ๋กœ command๋ฅผ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด๋Ÿฌํ•จ์€ context-sensitive menu ๋ฅผ ๊ตฌํ˜„ํ•˜๋Š”๋ฐ ์œ ์šฉํ•˜๋‹ค. ๋˜ํ•œ ์šฐ๋ฆฌ๋Š” ๋ช…๋ น์–ด๋“ค์„ ์ปค๋‹ค๋ž€ ๋ช…๋ น์–ด์— ํ•˜๋‚˜๋กœ ์กฐํ•ฉํ•จ์œผ๋กœ์„œ command scripting์„ ์ง€์›ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ชจ๋“  ๊ฒƒ์€ request๋ฅผ issueํ•˜๋Š” ๊ฐ์ฒด๊ฐ€ ์˜ค์ง ์–ด๋–ป๊ฒŒ issueํ™” ํ•˜๋Š”์ง€๋งŒ ์•Œ๊ณ  ์žˆ์œผ๋ฉด ๋˜๊ธฐ๋•Œ๋ฌธ์— ๊ฐ€๋Šฅํ•˜๋‹ค. request๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๊ฐ์ฒด๋Š” ์–ด๋–ป๊ฒŒ request๊ฐ€ ์ˆ˜ํ–‰๋˜์–ด์•ผ ํ• ์ง€ ์•Œ ํ•„์š”๊ฐ€ ์—†๋‹ค.

1.4. Applicability

๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฝ์šฐ์— CommandPattern์„ ์ด์šฉํ•˜๋ผ.

  • MenuItem ๊ฐ์ฒด๊ฐ€ ํ•˜๋ ค๋Š” ์ผ์„ ๋„˜์–ด์„œ ์ˆ˜ํ–‰ํ•˜๋ ค๋Š” action์— ์˜ํ•ด ๊ฐ์ฒด๋ฅผ์„ ์ธ์žํ™”์‹œํ‚ฌ๋•Œ. ํ”„๋กœ๊ทธ๋ž˜๋จธ๋Š” procedural language์—์„œ์˜ callback ํ•จ์ˆ˜์ฒ˜๋Ÿผ ์ธ์žํ™”์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค. Command๋Š” callbackํ•จ์ˆ˜์— ๋Œ€ํ•œ ๊ฐ์ฒด์ง€ํ–ฅ์ ์ธ ๋Œ€์•ˆ์ด๋‹ค.

  • ๋‹ค๋ฅธ ์‹œ๊ฐ„๋Œ€์— request๋ฅผ ๊ตฌ์ฒดํ™”ํ•˜๊ฑฐ๋‚˜ queueํ•˜๊ฑฐ๋‚˜ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์›ํ• ๋•Œ. Command ๊ฐ์ฒด๋Š” request์™€ ๋…๋ฆฝ์ ์ธ lifetime์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค. ๋งŒ์ผ request์˜ receiver๊ฐ€ ๊ณต๊ฐ„ ๋…๋ฆฝ์ ์ธ ๋ฐฉ๋ฒ•์œผ๋กœ (๋„คํŠธ์›Œํฌ ๋“ฑ) ์ฃผ์†Œ๋ฅผ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ํ”„๋กœ๊ทธ๋ž˜๋จธ๋Š” request์— ๋Œ€ํ•œ Command ๊ฐ์ฒด๋ฅผ ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค์—๊ฒŒ ์ „๋‹ฌํ•˜์—ฌ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

  • undo ๊ธฐ๋Šฅ์„ ์ง€์›ํ•˜๊ธฐ ์›ํ• ๋•Œ. Command์˜ Execute operation์€ ํ•ด๋‹น Command์˜ ํšจ๊ณผ๋ฅผ ๋˜๋Œ๋ฆฌ๊ธฐ ์œ„ํ•œ state๋ฅผ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋‹ค. Command ๋Š” Execute ์ˆ˜ํ–‰์˜ ํšจ๊ณผ๋ฅผ ๋˜๋Œ๋ฆฌ๊ธฐ ์œ„ํ•œ Unexecute operation์„ ์ธํ„ฐํŽ˜์ด์Šค๋กœ์„œ ์ถ”๊ฐ€ํ•ด์•ผ ํ•œ๋‹ค. ์ˆ˜ํ–‰๋œ command๋Š” history list์— ์ €์žฅ๋œ๋‹ค. history list๋ฅผ ์•ž ๋’ค๋กœ ๊ฒ€์ƒ‰ํ•˜๋ฉด์„œ Unexecute์™€ Execute๋ฅผ ๋ถ€๋ฆ„์œผ๋กœ์„œ ๋ฌด์ œํ•œ์˜ undo๊ธฐ๋Šฅ๊ณผ redo๊ธฐ๋Šฅ์„ ์ง€์›ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

  • logging change๋ฅผ ์ง€์›ํ•˜๊ธฐ ์›ํ• ๋•Œ. logging change ๋ฅผ ์ง€์›ํ•จ์œผ๋กœ์„œ ์‹œ์Šคํ…œ ์ถฉ๋Œ์ด ๋‚œ ๊ฒฝ์šฐ์— ๋Œ€ํ•ด ํ•ด๋‹น command๋ฅผ ์žฌ์‹œ๋„ ํ•  ์ˆ˜ ์žˆ๋‹ค. Command ๊ฐ์ฒด์— load ์™€ store operation์„ ์ถ”๊ฐ€ํ•จ์œผ๋กœ์„œ change์˜ log๋ฅผ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค. crash๋กœ๋ถ€ํ„ฐ ๋ณต๊ตฌํ•˜๋Š” ๊ฒƒ์€ ๋””์Šคํฌ๋กœ๋ถ€ํ„ฐ logged command๋ฅผ ์ฝ์–ด๋“ค์ด๊ณ  Execute operation์„ ์žฌ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ์€ ์ค‘์š”ํ•œ ๋ถ€๋ถ„์ด๋‹ค.

  • ๊ธฐ๋ณธ๋ช…๋ น์–ด๋“ค๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ด์šฉํ•œ ํ•˜์ด๋ ˆ๋ฒจ์˜ ๋ช…๋ น๋“ค๋กœ ์‹œ์Šคํ…œ์„ ์กฐ์งํ•  ๋•Œ. ๊ทธ๋Ÿฌํ•จ ์กฐ์ง์€ transaction์„ ์ง€์›ํ•˜๋Š” ์ •๋ณด์‹œ์Šคํ…œ์—์„œ ๋ณดํŽธํ™”๋œ ๋ฐฉ์‹์ด๋‹ค. transaction์€ ๋ฐ์ดํ„ฐ์˜ ๋ณ€ํ™”์˜ ์ง‘ํ•ฉ์„ ์บก์Аํ™”ํ•œ๋‹ค. CommandPattern์€ transaction์„ ๋””์ž์ธํ•˜๋Š” ํ•˜๋‚˜์˜ ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•œ๋‹ค. Command๋“ค์€ ๊ณตํ†ต๋œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ฐ€์ง€๋ฉฐ, ๋ชจ๋“  transaction๋ฅผ ๊ฐ™์€ ๋ฐฉ๋ฒ•์œผ๋กœ invokeํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค. CommandPattern์€ ๋˜ํ•œ ์ƒˆ๋กœ์šด transaction๋“ค์„ ์‹œ์Šคํ…œ์— ํ™•์žฅ์‹œํ‚ค๊ธฐ ์‰ฝ๊ฒŒ ํ•œ๋‹ค.

1.6. Participants

  • Command
    - ์ˆ˜ํ–‰ํ•  operation์„ ์œ„ํ•œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์„ ์–ธํ•œ๋‹ค.
  • ConcreteCommand (PasteCommand, OpenCommand)
    - Receiver ๊ฐ์ฒด์™€ action ๋ฌถ์Œ์„ ์ •์˜ํ•œ๋‹ค.
  • Client (Application)
    - ConcreteCommand ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ณ  receiver๋กœ ์ •ํ•œ๋‹ค.
  • Invoker (MenuItem)
    - command ์—๊ฒŒ request๋ฅผ ์ˆ˜ํ–‰ํ•˜๋„๋ก ์š”์ฒญํ•œ๋‹ค.
  • Receiver (Document, Application)
    - ์ฒ˜๋ฆฌํ•  request์— ๋Œ€ํ•ด ๋ช…๋ น์–ด๋“ค์„ ์–ด๋–ป๊ฒŒ ์ˆ˜ํ–‰ํ•ด์•ผ ํ• ์ง€ ์•Œ๊ณ  ์žˆ๋‹ค. ์–ด๋– ํ•œ ํด๋ž˜์Šค๋“ ์ง€ Receiver๋กœ์„œ ํ™œ๋™๊ฐ€๋Šฅํ•˜๋‹ค.

1.7. Collaborations

  • client๋Š” ConcreteCommand ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ณ , receiver๋ฅผ ์ •ํ•œ๋‹ค.
  • Invoker ๊ฐ์ฒด๋Š” ConcreteCommand๊ฐ์ฒด๋ฅผ ์ €์žฅํ•œ๋‹ค.
  • invoker๋Š” command์—์„œ Execute๋ฅผ ํ˜ธ์ถœํ•จ์œผ๋กœ์„œ request๋ฅผ issueํ•œ๋‹ค. ๋ช…๋ น์–ด๊ฐ€ undo๊ฐ€๋Šฅํ• ๋•Œ, ConcreteCommand๋Š” ๋ช…๋ น์–ด๋ฅผ undoํ•˜๊ธฐ ์œ„ํ•œ state๋ฅผ ์ €์žฅํ•œ๋‹ค.
  • ConcreteCommand ๊ฐ์ฒด๋Š” request๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด receiver์—์„œ operation์„ invokeํ•œ๋‹ค.

๋‹ค์Œ์˜ ๋‹ค์ด์–ด๊ทธ๋žจ์€ ์ด ๊ฐ์ฒด๋“ค์ด ์–ด๋–ป๊ฒŒ ์ƒํ˜ธ์ž‘์šฉํ•˜๋Š”์ง€ ๋ณด์—ฌ์ค€๋‹ค. ์ด ๋‹ค์ด์–ด๊ทธ๋žจ์€ ๋˜ํ•œ ์–ด๋–ป๊ฒŒ Command ๊ฐ€ receiver์™€ ์ฒ˜๋ฆฌํ•  request๋กœ๋ถ€ํ„ฐ invoker๋ฅผ ๋ถ„๋ฆฌํ•˜๋Š”์ง€ ์„ค๋ช…ํ•œ๋‹ค.


1.8. Consequences


CommandPattern์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ€์ ธ์˜จ๋‹ค.
  1. Command๋Š” ํ•ด๋‹น ๊ฐ์ฒด์˜ ๋ช…๋ น์„ invokeํ•˜๋Š” ๊ฐ์ฒด์™€ ์–ด๋–ป๊ฒŒ ์ˆ˜ํ–‰ํ•ด์•ผ ํ• ์ง€ ์•Œ๊ณ  ์žˆ๋Š” ๊ฐ์ฒด์™€์˜ ๊ฒฐํ•ฉ์„ ํ•ด์ œํ•œ๋‹ค.
  2. Command๋Š” ์ฒซ๋ฒˆ์งธ๋‹จ๊ณ„์˜ ํด๋ž˜์Šค ๊ฐ์ฒด์ด๋‹ค. Command๋Š” ์กฐ์ž‘๋˜์–ด์งˆ ์ˆ˜ ์žˆ์œผ๋ฉด์„œ ๋‹ค๋ฅธ ๊ฐ์ฒด๋“ค๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ํ™•์žฅ๊ฐ€๋Šฅํ•˜๋‹ค.
  3. Command๋ฅผ ๋ฌถ์„ ์ˆ˜ ์žˆ๋‹ค. ์•ž์„œ ์„ค๋ช…ํ•œ MacroCommand๊ฐ€ ๊ทธ ์˜ˆ๊ฐ€ ๋œ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ composite command๋“ค์€ CompositePattern์˜ ์ธ์Šคํ„ด์Šค์ด๋‹ค.
  4. ์ƒˆ๋กœ์šด Command๋ฅผ ์ถ”๊ฐ€ํ•˜๊ธฐ๊ฐ€ ์‰ฝ๋‹ค. ์™œ๋ƒํ•˜๋ฉด ์ด๋ฏธ ์กด์žฌํ•˜๊ณ ์žˆ๋Š” ํด๋ž˜์Šค๋“ค์„ ๊ณ ์น  ํ•„์š”๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

1.9. Implementation


1.10. Sample Code

์—ฌ๊ธฐ ๋ณด์—ฌ์ง€๋Š” C++ code๋Š” Motivation ์„น์…˜์˜ Command ํฌ๋ž˜์Šค์— ๋Œ€ํ•œ ๋Œ€๊ฐ•์˜ ๊ตฌํ˜„์ด๋‹ค. ์šฐ๋ฆฌ๋Š” OpenCommand, PasteCommand ์™€ MacroCommand๋ฅผ ์ •์˜ํ•  ๊ฒƒ์ด๋‹ค. ๋จผ์ € ์ถ”์ƒ Commmand class ๋Š” ์ด๋ ‡๋‹ค.
~cpp 
class Command {
public:
	virtual ~Command ();

	virtual void Execute () = 0;
protected:
	Command ();
};

OpenCommand๋Š” ์œ ์ €๋กœ๋ถ€ํ„ฐ ์ œ๊ณต๋œ ์ด๋ฆ„์˜ ๋ฌธ์„œ๋ฅผ ์—ฐ๋‹ค. OpenCommand๋Š” ๋ฐ˜๋“œ์‹œ Constructor์— Application ๊ฐ์ฒด๋ฅผ ๋„˜๊ฒจ๋ฐ›์•„์•ผ ํ•œ๋‹ค. AskUser ๋Š” ์œ ์ €์—๊ฒŒ ์—ด์–ด์•ผ ํ•  ๋ฌธ์„œ์˜ ์ด๋ฆ„์„ ๋ฌป๋Š” ๋ฃจํ‹ด์„ ๊ตฌํ˜„ํ•œ๋‹ค.

~cpp 
class OpenCommand : public Command {
public:
	OpenCommand (Application*);

	virtual void Execute ();
protected:
	virtual const char* AskUser ();
private:
	Application* _application;
	char* _response;
};

OpenCommand::OpenCommand (Application* a) {
	_application = a;
}

void OpenCommand::Execute () {
	const char* name = AskUser ();

	if (name != 0) {
		Document* document = new Document (name);
		_application->Add (document);
		document->Open ();
	}
}

PasteCommand ๋Š” receiver๋กœ์„œ Document๊ฐ์ฒด๋ฅผ ๋„˜๊ฒจ๋ฐ›์•„์•ผ ํ•œ๋‹ค. receiver๋Š” PasteCommand์˜ constructor์˜ parameter๋กœ์„œ ๋ฐ›๋Š”๋‹ค.
~cpp 
class PasteCommand : public Command {
public:
	PasteCommand (Document*);

	virtual void Execute ();
private:
	Document* _document;
};

PasteCommand::PasteCommand (Document* doc) {
	_document = doc;
}

void PasteCommand::Execute () {
	_document->Paste ();
}

undo ํ•  ํ•„์š”๊ฐ€ ์—†๊ณ , ์ธ์ž๋ฅผ ์š”๊ตฌํ•˜์ง€ ์•Š๋Š” ๋‹จ์ˆœํ•œ ๋ช…๋ น์–ด์— ๋Œ€ํ•ด์„œ ์šฐ๋ฆฌ๋Š” command์˜ receiver๋ฅผ parameterizeํ•˜๊ธฐ ์œ„ํ•ด class template๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๊ทธ๋Ÿฌํ•œ ๋ช…๋ น๋“ค์„ ์œ„ํ•ด template subclass์ธ SimpleCommand๋ฅผ ์ •์˜ํ•  ๊ฒƒ์ด๋‹ค. SimpleCommand๋Š” Receiver type์— ์˜ํ•ด parameterize ๋˜๊ณ 

~cpp 
template <class Receiver>
class SimpleCommand : public Command {
public:
	typedef void (Receiver::* Action) ();

	SimpleCommand (Receiver* r, Action a) : 
		_receiver (r), _action (a) { }

	vitual void Execute ();

private:
	Action _action;
	Receiver* _receiver;
};

constructor๋Š” receiver์™€ instance ๋ณ€์ˆ˜์— ๋Œ€์‘๋˜๋Š” action์„ ์ €์žฅํ•œ๋‹ค. Execute๋Š” ๋‹จ์ˆœํžˆ action์„ receiver์— ์ ์šฉํ•œ๋‹ค.
~cpp 
template <class Receiver>
void Simplecommand<Receiver>::Execute () {
	(_receiver->*_action) ();

MyClass์˜ instance๋กœ ์žˆ๋Š” Action์„ ํ˜ธ์ถœํ•  command๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด์„œ, ํด๋ผ์ด์–ธํŠธ๋Š” ๋‹จ์ˆœํžˆ ์ด๋ ‡๊ฒŒ ์ฝ”๋”ฉํ•œ๋‹ค.
~cpp 
MyClass* receiver = new MyClass;
// ...
Command* aCommand = 
	new SimpleCommand<MyClass> (receiver, &MyClass::Action);
// ...
aCommand->Execute ();

์ด ๋ฐฉ๋ฒ•์€ ๋‹จ์ง€ ๋‹จ์ˆœํ•œ ๋ช…๋ น์–ด์—๋Œ€ํ•œ ํ•ด๊ฒฐ์ฑ…์ผ ๋ฟ์ž„์„ ๋ช…์‹ฌํ•˜๋ผ. track์„ ์œ ์ง€ํ•˜๊ฑฐ๋‚˜, receiver์™€ undo state๋ฅผ argument ๋กœ ํ•„์š”๋กœ ํ•˜๋Š” ์ข€๋” ๋ณต์žกํ•œ ๋ช…๋ น๋“ค์€ Command์˜ subclass๋ฅผ ์š”๊ตฌํ•œ๋‹ค.

MacroCommand๋Š” ๋ถ€๋ช…๋ น์–ด๋“ค์˜ sequence๋ฅผ ๊ด€๋ฆฌํ•˜๊ณ  ๋ถ€๋ช…๋ น์–ด๋“ค์„ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ์‚ญ์ œํ•˜๋Š” operation์„ ์ œ๊ณตํ•œ๋‹ค. subcommand๋“ค์€ ์ด๋ฏธ ๊ทธ๋“ค์˜ receiver๋ฅผ ์ •์˜ํ•˜๋ฏ€๋กœ MacroCommand๋Š” ๋ช…์‹œ์ ์ธ receiver๋ฅผ ์š”๊ตฌํ•˜์ง€ ์•Š๋Š”๋‹ค.

~cpp 
class MacroCommand : public Command {
public:
	MacroCommand ();
	virtual ~MacroCommand ();

	virtual void Add (Command*);
	virtual void Remove (Command*);

	virtual void Execute ();

private:
	List<Command*>* _cmds;
};

MacroCommand์˜ ์—ด์‡ ๋Š” Execute ๋งด๋ฒ„ํ•จ์ˆ˜์— ์žˆ๋‹ค. ์ด๊ฒƒ์€ ๋ชจ๋“  ๋ถ€๋ช…๋ น์–ด๋“ค์„ ํƒ์ƒ‰ํ•˜๋ฉด์„œ ๊ทธ๋“ค ๊ฐ๊ฐ์˜ Execute operation๋ฅผ ์ˆ˜ํ–‰ํ•œ๋‹ค.

~cpp 
void MacroCommand::Execute () {
	ListIterator<Command*> i (_cmds);
	
	for (i.First (); !i.IsDone (); i.Next()) {
		Command* c = i.CurrentItem ();
		c->Execute ();
	}
}


MacroCommand ๊ฐ€ Unexecute operation์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด์„œ MacroCommand์˜ ๋ถ€๋ช…๋ น์–ด๋“ค์€ Execute operation์—์„œ ๊ตฌํ˜„๋œ ์ˆœ์„œ์˜ ์—ญ์ˆœ์œผ๋กœ ์ฐธ์กฐ๋˜๋ฉด์„œ unexecuteํ•ด์•ผ ํ•จ์„ ์ˆ™์ง€ํ•˜์ž.

์ตœ์ข…์ ์œผ๋กœ MacroCommand ๋Š” ๋ถ€๋ช…๋ น์–ด๋“ค์„ ๊ด€๋ฆฌํ•  operation์„ ์ œ๊ณตํ•ด์•ผํ•œ๋‹ค. MacroCommand๋Š” ๋˜ํ•œ MacroCommand๋ฅผ ์ด๋ฃจ๋Š” ๋ถ€๋ช…๋ น์–ด๋“ค์„ ์‚ญ์ œํ•  ์ฑ…์ž„์„ ์ง„๋‹ค.

~cpp 
void MacroCommand::Add (Command* c) {
	_cmds->Append (c);
}

void MacroCommand::Remove (Command* c) {
	_cmds->Remove (c);
}


1.11. Known Uses

์•„๋งˆ๋„ CommandPattern์— ๋Œ€ํ•œ ์ฒซ๋ฒˆ์งธ ์˜ˆ์ œ๋Š” Lieberman ์˜ ๋…ผ๋ฌธ(Lie85)์—์„œ ๋‚˜ํƒ€๋‚ฌ์„ ๊ฒƒ์ด๋‹ค. MacApp App89 ๋Š” undo๊ฐ€๋Šฅํ•œ ๋ช…๋ น์˜ ๊ตฌํ˜„์„ ์œ„ํ•œ command์˜ ํ‘œ๊ธฐ๋ฅผ ๋Œ€์ค‘ํ™”์‹œ์ผฐ๋‹ค. ET++WGM88, InterViews LCI+92, UnidrawVL90 ์—ญ์‹œ CommandPatter์— ๋”ฐ๋ผ ํด๋ž˜์Šค๋“ค์„ ์ •์˜ํ–ˆ๋‹ค. InterViews๋Š” ๊ฐ ๊ธฐ๋Šฅ๋ณ„ ๋ช…๋ น์— ๋Œ€ํ•œ Action ์ถ”์ƒ ํด๋ž˜์Šค๋ฅผ ์ •์˜ํ–ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  action ๋ฉ”์†Œ๋“œ์— ์˜ํ•ด ์ธ์žํ™”๋จ์œผ๋กœ์„œ ์ž๋™์ ์œผ๋กœ command subclass๋“ค์„ ์ธ์Šคํ„ด์Šคํ™” ์‹œํ‚ค๋Š” ActionCallback ํ…œํ”Œ๋ฆฟ๋„ ์ •์˜ํ•˜์˜€๋‹ค.

THINK ํด๋ž˜์Šค ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ Sym93b ๋˜ํ•œ undo ๊ฐ€๋Šฅํ•œ ๋ช…๋ น์„ ์ง€์›ํ•˜๊ธฐ ์œ„ํ•ด CommandPattern์„ ์‚ฌ์šฉํ•œ๋‹ค. THINK ์—์„œ์˜ Command๋“ค์€ "Tasks" ๋กœ ๋ถˆ๋ฆฐ๋‹ค. Task ๊ฐ์ฒด๋“ค์€ ChainOfResponsibilityPattern์— ์ž…๊ฐํ•˜์—ฌ ๋„˜๊ฒจ์ง€๊ณ  ์†Œ๋น„๋˜์–ด์ง„๋‹ค.

AddMe)

1.12. Related Patterns

CompositePattern ๋Š” MacroCommand๋ฅผ ๊ตฌํ˜„ํ•˜๋Š”๋ฐ ์ด์šฉ๋  ์ˆ˜ ์žˆ๋‹ค.

MementoPattern ์€ undo๋ฅผ ์œ„ํ•œ state๋ฅผ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค.

history list ์— ์œ„์น˜ํ•˜๊ธฐ ์ „์— ๋ณต์‚ฌ๋˜์—ฌ์•ผ ํ•  command๋Š” Prototype์œผ๋กœ์„œ ์ž‘์šฉํ•œ๋‹ค.



Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2021-02-07 05:23:18
Processing time 0.0118 sec