GoF์˜ ๋””์ž์ธ ํŒจํ„ด, ๋ช…๋ น ํŒจํ„ด์— ๋Œ€ํ•ด ์•Œ์•„๋ณธ๋‹ค.

ํ•ด๋‹น ๊ธ€์€, ๋‹ค์Œ์˜ ์ฝ”๋“œ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ดํ•ดํ•˜๋Š” ๊ฒƒ์ด ํŽธ๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

ํ•ต์‹ฌ ์š”์•ฝ

  • ํ•˜๋‚˜์˜ ๋ช…๋ น์„ ๊ฐ์ฒดํ™”ํ•œ ํŒจํ„ด
  • ๊ฐ์ฒด๋Š” ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๊ณ , ๋ณด๊ด€ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์ฆ‰, ๋ช…๋ น(๊ธฐ๋Šฅ)์„ ์ „๋‹ฌํ•˜๊ณ  ๋ณด๊ด€ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.
  • Batch ์‹คํ–‰, Undo/Redo, ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋†’์€ ๋ช…๋ น์„ ๋จผ์ € ์‹คํ–‰ ๊ณผ ๊ฐ™์€ ๊ฒƒ๋“ค์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

์˜ˆ์‹œ

Code

Command

//
//  Command.swift
//  Command
//
//  Created by Choiwansik on 2023/01/16.
//
 
import Foundation
 
internal protocol Command {
 
    func run()
 
//    func undo() ํ•„์š”ํ•˜๋‹ค๋ฉด ๊ตฌํ˜„ํ•˜๋ฉด ๋จ
    
}
 

EnterCommand

//
//  EnterCommand.swift
//  Command
//
//  Created by Choiwansik on 2023/01/16.
//
 
import Foundation
 
internal class EnterCommand: Command {
 
    internal func run() {
        (0...4).forEach { _ in print() }
    }
 
}
 

PrintCommand

//
//  PrintCommand.swift
//  Command
//
//  Created by Choiwansik on 2023/01/16.
//
 
import Foundation
 
internal class PrintCommand: Command {
 
    internal init(content: String) {
        self.content = content
    }
 
    internal func run() {
        print(self.content)
    }
 
    private let content: String
 
}
 

TabCommand

//
//  TabCommand.swift
//  Command
//
//  Created by Choiwansik on 2023/01/16.
//
 
import Foundation
 
internal class TabCommand: Command {
 
    internal init(times: Int) {
        self.times = times
    }
 
    internal func run() {
        (0..<self.times).forEach { _ in print("    ", terminator: "") }
    }
 
    private let times: Int
 
}
 

DecorationCommand

//
//  DecorationCommand.swift
//  Command
//
//  Created by Choiwansik on 2023/01/16.
//
 
import Foundation
 
internal class DecorationCommand: Command {
 
    internal func run() {
        print("======================================")
    }
 
}
 

CommandGroup

//
//  CommandGroup.swift
//  Command
//
//  Created by Choiwansik on 2023/01/16.
//
 
import Foundation
 
internal class CommandGroup: Command {
 
    internal func add(command: Command) {
        self.commands.append(command)
    }
 
    internal func run() {
        self.commands.forEach { $0.run() }
    }
 
    private var commands = [Command]()
    
}
 

main

//
//  main.swift
//  Command
//
//  Created by Choiwansik on 2023/01/16.
//
 
import Foundation
 
internal func main() {
 
    // ํ•˜๋‚˜์”ฉ ํ…Œ์ŠคํŠธ ํ•ด๋ณด๊ธฐ
 
    let enterCommand: Command = EnterCommand()
    enterCommand.run()
 
    let tabCommand: Command = TabCommand(times: 3)
    tabCommand.run()
 
    let printCommand: Command = PrintCommand(content: "์ถœ๋ ฅํ•ด์ฃผ์„ธ์š”.")
    printCommand.run()
 
    let decorationCommand: Command = DecorationCommand()
    decorationCommand.run()
 
    // ๊ธฐ์กด์— ๋งŒ๋“ค์—ˆ๋˜ ๊ฐ์ฒด๋ฅผ ์žฌ์‚ฌ์šฉํ•ด๋ณด๊ธฐ (print)
 
    let tabCommand2: Command = TabCommand(times: 6)
    tabCommand2.run()
    printCommand.run()
 
    // Command Group์„ ํ†ตํ•ด Batch๋กœ ๋งŒ๋“ค๊ธฐ
 
    let commandGroup = CommandGroup()
    commandGroup.add(command: enterCommand)
    commandGroup.add(command: tabCommand)
    commandGroup.add(command: printCommand)
    commandGroup.add(command: decorationCommand)
 
    commandGroup.run()
 
}
 
main()
 

๋™๊ธฐ

  • ๋ฉ”๋‰ด๊ฐ€ ์žˆ๋Š” ์–ด๋–ค ํ”„๋กœ๊ทธ๋žจ์„ ์ƒ๊ฐํ•ด๋ณด์ž.
  • ๋‹ซ๊ธฐ ๋ฒ„ํŠผ์€ ๋ฉ”๋‰ด์—๋„ ์žˆ๊ณ , X๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ๋„ ๋‚ด๋ ค๊ฐ„๋‹ค.
  • ์ด๋ ‡๊ฒŒ ๋‹ค๋ฅธ ๋™์ž‘์— ๋Œ€ํ•ด ๊ฐ™์€ ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์•ผํ•  ํ•„์š”๊ฐ€ ์žˆ๋‹ค.
  • ์ด๋Ÿด ๊ฒฝ์šฐ โ€œ๋™์ž‘โ€ ์ž์ฒด(ํ˜น์€ ์š”์ฒญ)๋ฅผ ๋ฌถ์–ด์ฃผ๋ฉด ์ข‹๋‹ค.
  • ๋˜ํ•œ ์—ฌ๋Ÿฌ ๋ช…๋ น์„ ๋ณตํ•ฉ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•ด์•ผํ•  ๋•Œ๋„ ์žˆ๋‹ค.
  • ์ด๋Ÿฐ ๊ฒฝ์šฐ๋„ ์ƒ๊ฐํ•˜์—ฌ ์œ„์—์„œ ๋ฌถ์€ โ€œ๋ช…๋ นโ€์„ ๋‹ค์‹œ ๋ฌถ์–ด์ฃผ๋Š” ๊ฐ์ฒด๋„ ์žˆ์œผ๋ฉด ์ข‹๊ฒ ๋‹ค.

ํ™œ์šฉ์„ฑ

  • ์ˆ˜ํ–‰ํ•  ๋™์ž‘์„ ๊ฐ์ฒด๋กœ ๋งค๊ฐœ๋ณ€์ˆ˜ํ™” ํ•˜๊ณ ์ž ํ•  ๋•Œ
    • Callback๊ณผ ๊ฐ™์ด ์–ด๋–ค ๋™์ž‘์„ ๋“ฑ๋กํ•ด์•ผํ•  ํ•„์š”๊ฐ€ ์žˆ๋‹ค.
    • Command ํŒจํ„ด์€ ์ด์™€ ๊ฐ™์ด ๋™์ž‘์„ ๊ฐ์ฒด ์ง€ํ–ฅ ๋ฐฉ์‹์œผ๋กœ ๋‚˜ํƒ€๋‚ธ ๊ฒƒ์ด๋ผ ์ƒ๊ฐํ•˜๋ฉด ๋˜๊ฒ ๋‹ค.
  • ์‹คํ–‰ ์ทจ์†Œ ๊ธฐ๋Šฅ์„ ์ง€์›ํ•˜๊ณ  ์‹ถ์„ ๋•Œ
    • ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” Group๊ณผ ๊ฐ™์€ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋˜๋Œ๋ฆฌ๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.
  • ๋ณ€๊ฒฝ๊ณผ์ •์— ๋Œ€ํ•œ ๋กœ๊น…์„ ์ง€์›ํ•˜๊ณ  ์‹ถ์„ ๋•Œ
    • Command ๊ฐ์ฒด์— load(), store()์™€ ๊ฐ™์€ ์—ฐ์‚ฐ์„ ์ง€์›ํ•˜๋ฉด ์ €์žฅ์†Œ์— ์ €์žฅํ–ˆ๋‹ค๊ฐ€ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•ด์ง„๋‹ค.
    • ์‹œ์Šคํ…œ์ด ๊ฐ‘์ž๊ธฐ ์ข…๋ฃŒ(์›Œ๋“œ ๊ฐ™์€ ๊ฑฐ)๋˜์—ˆ์„ ์‹œ ๋ณต๊ตฌํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ํ•ด๋‹น ํŒจํ„ด์„ ๊ณ ๋ คํ•ด๋ณด์ž.

๋‹ค๋ฅธ ์ด๋ฆ„

  • Action
  • Transaction

๊ฒฐ๊ณผ

  1. ์—ฐ์‚ฐ์„ ํ˜ธ์ถœํ•˜๋Š” ๊ฐ์ฒด์™€ ์ˆ˜ํ–‰๋ฐฉ๋ฒ•์„ ๊ตฌํ˜„ํ•˜๋Š” ๊ฐ์ฒด๋ฅผ ๋ถ„๋ฆฌํ•œ๋‹ค.
  2. ๋ณตํ•ฉ ๋ช…๋ น์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.
  3. ์ƒˆ๋กœ์šด Command ๊ฐ์ฒด๋ฅผ ์ถ”๊ฐ€ํ•˜๊ธฐ ์‰ฝ๋‹ค.

์ƒ๊ฐํ•ด๋ณผ ์ 

  • ๊ฒฐ๊ตญ Command ๋Š” ์–ด๋–ค ๋™์ž‘์„ ์บก์Šํ™” ํ•œ ๊ฒƒ์œผ๋กœ ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ๊ฒ ๋‹ค.
    • ๊ทธ๋ž˜์„œ ํ–‰๋™ ํŒจํ„ด์— ๋“ค์–ด๊ฐ„ ๊ฒƒ์ผ ๋“ฏ
  • ๊ทธ๋ฆฌ๊ณ  ๊ทธ Command๋ผ๊ณ  ๊ฐ์‹ธ์ง„ ๋•๋ถ„์—, ์ด ๋™์ž‘๋“ค์„ ์œ ์—ฐํ•˜๊ฒŒ ์—ฎ๊ณ , ๋ฐ˜๋Œ€๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.
  • ๊ฒฐ๊ตญ ์บก์Šํ™”๊ฐ€ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ํ™”๋‘๋ผ๋Š” ์ƒ๊ฐ์ด ๋“ ๋‹ค.
  • ๋™์ž‘์„ ๋‚˜๋ˆ„๋Š” ๊ฒƒ์—์„œ โ€œ๋ฌด์—‡โ€์— ๋Œ€ํ•ด ์ดˆ์ ์„ ๋งž์ถ˜ ๊ฒƒ์ด ๋ช…๋ น ํŒจํ„ด์ด๋‹ค.
    • โ€์–ด๋–ป๊ฒŒโ€๋Š” ์ „๋žต ํŒจํ„ด
  • IBAction์œผ๋กœ ํŠน์ • ๋™์ž‘ ์ž์ฒด๋ฅผ ๋„˜๊ฒจ ๋ฐ”์ธ๋”ฉํ•˜๋Š” ๋ฐฉ์‹์ด ๋ช…๋ น ํŒจํ„ด์ผ ๋“ฏ ํ•˜๋‹ค.
    • ์ด๋ฒคํŠธ๊ฐ€ ์™”์„ ์‹œ ์ฒ˜๋ฆฌ๋  ๋™์ž‘ ์ž์ฒด๋ฅผ ์บก์Šํ™”(ํ•จ์ˆ˜ํ™”)ํ•ด์„œ ๋„˜๊ธฐ๊ธฐ ๋•Œ๋ฌธ

Reference