GoF์ ๋์์ธ ํจํด, ์ํ ํจํด์ ๋ํด ์์๋ณธ๋ค.
ํด๋น ๊ธ์, ๋ค์์ ์ฝ๋๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ดํดํ๋ ๊ฒ์ด ํธ๋ฆฌํฉ๋๋ค.
ํต์ฌ ์์ฝ
- ์ํ๋ฅผ ๊ฐ์ฒดํ ํ ํจํด
- ์กฐ๊ฑด์ ์ ํจ๊ณผ์ ์ผ๋ก ์ค์ฌ์ฃผ๋ ํจํด
์์
- ์ด๋ค ํ๋ก๊ทธ๋จ์์์ ๋์์ด ๋ ๋ฆฝ์ ์ด์ง ์๋ค๋ฉด ์ด๋ป๊ฒ ๋ ๊น?
- ์ฆ, ์ด์ ์ํ์ ๋ค์ ๋์์ ๊ฒฐ๊ณผ๊ฐ ์ํฅ์ ๋ฏธ์น๋ ์ข ์ ์ฌ๊ฑด์ด๋ผ๋ฉด?
- ์๊ธฐ, ๊ฑท๊ธฐ, ๋ฐ๊ธฐ, ์๊ธฐ์ 4๊ฐ์ง ๋์์ด ์๋ค๊ณ ํ์.
- ๋ค์ ๋์์ ์คํํ ๊ฒฐ๊ณผ๋ ์ด์ ์ํ๊ฐ ์ด๋ค ์ํ๋์ ๋ฐ๋ผ ๋ค๋ฅธ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ์ ธ์จ๋ค๊ณ ํด๋ณด์.
- ์ด๋ด ๊ฒฝ์ฐ 4*4๋ก 16๊ฐ์ง์ ๊ฒฝ์ฐ์ ์๊ฐ ๋์จ๋ค.
- ๋ง์ฝ ์กฐ๊ฑด๋ฌธ์ ์ด๋ค๋ฉด 16๊ฐ๋ฅผ ๋ถ๊ธฐ์ณ์ฃผ์ด์ผ ํ๋ค.
- ์ด๋ฐ ๊ฒฝ์ฐ ์ํ ํจํด์ ์ฌ์ฉํ๋ฉด ์ข๋ค.
- ํต์ฌ์ ๋ด๊ฐ ์จ ์ํ์์ ๋ค์์ผ๋ก ์ํ๋ฅผ ์ ์ด์ํค๋ ์ฑ ์์ State๊ฐ ๊ฐ๋๋ค๋ ๊ฒ์ด๋ค.
- ์ฆ, ์ํ๋ ์์ ์ผ๋ก๋ถํฐ ๋ค์ ์ํ๋ก ์ ํ๋์์ ๋์ ์ฒ๋ฆฌ๋ฅผ ๋ด๋นํด์ผ ํ๋ค.
Code
main
//
// main.swift
// State
//
// Created by Choiwansik on 2023/02/13.
//
import Foundation
internal func main() {
let player = Player(speed: 0)
player.update(state: StandUpState(player: player))
while true {
print("ํ๋ ์ด์ด ์ํ: \(player.state?.description ?? "")")
print("์๋: \(player.speed) km/h")
print("1: ์๊ธฐ, 2: ์๊ธฐ, 3: ๊ฑท๊ธฐ, 4: ๋ฐ๊ธฐ, 5: ์ข
๋ฃ")
print("")
let input = readLine()
guard let first = input?.components(separatedBy: " ").first,
let command = Int(first) else {
return
}
switch command {
case 1:
player.state?.standUp()
case 2:
player.state?.sitDown()
case 3:
player.state?.walk()
case 4:
player.state?.run()
default:
print("์ข
๋ฃํฉ๋๋ค.")
return
}
}
}
main()
Player
//
// Player.swift
// State
//
// Created by Choiwansik on 2023/02/13.
//
import Foundation
public class Player {
private(set) var speed: Int
private(set) var state: State?
internal init(speed: Int) {
self.speed = speed
}
internal func update(state: State) {
self.state = state
}
internal func update(speed: Int) {
self.speed = speed
}
internal func talk(message: String) {
print("ํ๋ ์ด์ด: \(message)")
}
}
State
//
// State.swift
// State
//
// Created by Choiwansik on 2023/02/13.
//
import Foundation
internal protocol State: Loggable {
init(player: Player)
func standUp()
func sitDown()
func walk()
func run()
var player: Player { get }
}
internal protocol Loggable {
var description: String { get }
}
StandUpState
//
// StandUpState.swift
// State
//
// Created by Choiwansik on 2023/02/13.
//
import Foundation
internal class StandUpState: State {
required internal init(player: Player) {
self.player = player
}
internal func standUp() {
self.player.talk(message: "์ธ์ ์์ง์ผ๊บผ์ผ?")
}
internal func sitDown() {
self.player.update(state: SitDownState(player: self.player))
self.player.talk(message: "์์ผ๋ ํธํ๊ณ ์ข์์")
}
internal func walk() {
self.player.update(speed: 5)
self.player.update(state: WalkState(player: self.player))
self.player.talk(message: "๊ฑท๊ธฐ๋ ์ 2์ ์๊ฐํ๊ธฐ๋ค..")
}
internal func run() {
self.player.update(speed: 10)
self.player.update(state: RunState(player: self.player))
self.player.talk(message: "๊ฐ์๊ธฐ ๋ด๋ค๊ณ ?")
}
internal let player: Player
}
extension StandUpState: Loggable {
internal var description: String {
"์ ์๋ฆฌ์ ์์์"
}
}
SitDownState
//
// SitDownState.swift
// State
//
// Created by Choiwansik on 2023/02/13.
//
import Foundation
internal class SitDownState: State {
required internal init(player: Player) {
self.player = player
}
internal func standUp() {
self.player.update(state: StandUpState(player: self.player))
self.player.talk(message: "์ผ์ด๋์..")
}
internal func sitDown() {
self.player.talk(message: "์ผ๋ง๋ ์ค๋ ์์ ์์ ์๊ฐ์ด์ผ")
}
internal func walk() {
self.player.update(state: StandUpState(player: self.player))
self.player.talk(message: "์์์ ์ด๋ป๊ฒ ๊ฑท๋ ์ผ๋จ ์ผ์ด๋์.")
}
internal func run() {
self.player.update(state: StandUpState(player: self.player))
self.player.talk(message: "์์์ ์ด๋ป๊ฒ ๋ฐ๋ ์ผ๋จ ์ผ์ด๋์.")
}
internal let player: Player
}
extension SitDownState: Loggable {
internal var description: String {
"์์์์"
}
}
WalkState
//
// WalkState.swift
// State
//
// Created by Choiwansik on 2023/02/13.
//
import Foundation
internal class WalkState: State {
required internal init(player: Player) {
self.player = player
}
internal func standUp() {
self.player.update(speed: 0)
self.player.update(state: StandUpState(player: self.player))
self.player.talk(message: "๋ฉ์ถฐ")
}
internal func sitDown() {
self.player.update(speed: 0)
self.player.update(state: SitDownState(player: self.player))
self.player.talk(message: "๊ฑท๋ค๊ฐ ์๋ค๋ ์๋ฉ์ด ๊น์ง๋ค.")
}
internal func walk() {
self.player.talk(message: "๊ทธ๋ ๊ณ์ ๊ฑท์.")
}
internal func run() {
self.player.update(speed: 20)
self.player.update(state: RunState(player: self.player))
self.player.talk(message: "๊ฑท๋ค๊ฐ ๋ฐ๋ฉด ์๋๊ฐ ํ ์ค๋ฅด์ง!")
}
internal let player: Player
}
extension WalkState: Loggable {
internal var description: String {
"๊ฑท๋ ์ค"
}
}
RunState
//
// RunState.swift
// State
//
// Created by Choiwansik on 2023/02/13.
//
import Foundation
internal class RunState: State {
required internal init(player: Player) {
self.player = player
}
internal func standUp() {
self.player.update(speed: 0)
self.player.update(state: StandUpState(player: self.player))
self.player.talk(message: "๋ฐ๋ค๊ฐ ์ฐ๋๋ ๋ฌด๋ฆ์ด ์ํ")
}
internal func sitDown() {
self.player.update(speed: 0)
self.player.update(state: SitDownState(player: self.player))
self.player.talk(message: "๋ฐ๋ค๊ฐ ์์ผ๋ผ๊ณ ? ์๋ฉ์ด ๋ค๊น์ก๋ค.")
}
internal func walk() {
self.player.update(speed: 8)
self.player.update(state: WalkState(player: self.player))
self.player.talk(message: "์๋๋ฅผ ์ค์ผ๊ฒ")
}
internal func run() {
self.player.update(speed: self.player.speed + 2)
self.player.talk(message: "๋ ๋นจ๋ฆฌ ๋ฐ๋ผ๋ ์๋ฆฌ์ง?")
}
internal let player: Player
}
extension RunState: Loggable {
internal var description: String {
"๋ฐ๋ ์ค"
}
}
ํ์ฉ์ฑ
- ๊ฐ์ฒด์ ํ๋์ด ์ํ์ ๋ฐ๋ผ ๋ฌ๋ผ์ง ์ ์๋ค.
- ๊ฐ์ฒด์ ์ํ์ ๋ฐ๋ผ ๋ฐํ์์ ํ๋์ด ๋ณ๊ฒฝ๋์ด์ผ ํ๋ค.
- ํน์ ์ฐ์ฐ์ ๋ถ๊ธฐ ์กฐ๊ฑด์ด ๋๋ฌด ๋ง์ ๊ฒฝ์ฐ
๊ฒฐ๊ณผ
- ์ํ์ ๋ฐ๋ฅธ ํ๋์ ๋ชจ์ ์ ์๋ค. ๊ทธ๋ฆฌ๊ณ ์ด๋ฅผ ๋ณ๋์ ๊ฐ์ฒด๋ก ๊ด๋ฆฌํ ์ ์๋ค.
- ์ํ ์ ์ด๋ฅผ ๋ช
ํํ๊ฒ ๋ง๋ ๋ค.
- ์ํ์ ๋ณํ๊ฐ ์์์ ์ผ๋ก ๋ฐ๋๋ค.
- ์ํ ๊ฐ์ฒด๋ ๊ณต์ ๋ ์ ์๋ค.
- ๊ฐ์ ๊ฐ์ฒด๋ฅผ ์ด๊ณณ ์ ๊ณณ์ผ๋ก ๋๊ธธ ์ ์๋ค.
์๊ฐํด๋ณผ ์
- TCP ์ฐ๊ฒฐ ํ๋กํ ์ฝ์ ์ ์ฉํ์์