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.0641 sec