GoF์ ๋์์ธ ํจํด, ๊ฐ์์ ํจํด์ ๋ํด ์์๋ณธ๋ค.
ํต์ฌ ์์ฝ
๊ฐ์ฒด ์ฌ์ด์ ์ผ ๋ ๋ค ์์กด ๊ด๊ณ๋ฅผ ์ ์ํด๋์ด, ์ด๋ค ๊ฐ์ฒด์ ์ํ๊ฐ ๋ณํ ๋, ๊ทธ ๊ฐ์ฒด์ ์์กด์ฑ์ ๊ฐ์ง ๋ค๋ฅธ ๊ฐ์ฒด๋ค์ด ๋ณํ๋ฅผ ํต์ง๋ฐ๊ณ ์๋์ผ๋ก ๊ฐฑ์ ๋ ์ ์๊ฒ ๋ง๋ ๋ค.
- ์ข ์์, ๊ฒ์-๊ตฌ๋ (Publish-Subscribe)๋ผ ๋ถ๋ฆฐ๋ค.
 - swift index์ด ์ด ํํ๋ผ ์๊ฐํ๋ฉด ๋๋ค.
 - 03. Notification To Combine ์์ ์ฌ์ฉํ๋ Notification๋ ๊ฐ์ ํํ๋ค.
 
์์

Code
//
//  main.swift
//  Observer
//
//  Created by Choiwansik on 2023/09/26.
//
 
import Foundation
 
internal func main() {
    let diceGame: DiceGame = FairDiceGame()
 
    let player1: Player = EvenBettingPlayer(name: "์์")
    let player2: Player = OddBettingPlayer(name: "์ต์์")
    let player3: Player = OddBettingPlayer(name: "์์์ด")
 
    diceGame.add(player: player1)
    diceGame.add(player: player2)
    diceGame.add(player: player3)
 
    (0..<5).forEach { _ in
        diceGame.play()
        print()
    }
}
 
main()
 //
//  Player.swift
//  Observer
//
//  Created by Choiwansik on 2023/09/26.
//
 
import Foundation
 
public class Player {
 
    public init(name: String) {
        self.name = name
    }
 
    public func update(diceNumber: Int) {
 
    }
 
    public let name: String
 
}
 //
//  OddBettingPlayer.swift
//  Observer
//
//  Created by Choiwansik on 2023/09/26.
//
 
import Foundation
 
public class OddBettingPlayer: Player {
 
    override public init(name: String) {
        super.init(name: name)
    }
 
    override public func update(diceNumber: Int) {
        if diceNumber % 2 == 1 {
            print("\(self.name)๊ฐ ์ด๊น!")
        }
    }
 
}
 //
//  EvenBettingPlayer.swift
//  Observer
//
//  Created by Choiwansik on 2023/09/26.
//
 
import Foundation
 
public class EvenBettingPlayer: Player {
 
    override public init(name: String) {
        super.init(name: name)
    }
 
    override public func update(diceNumber: Int) {
        if diceNumber % 2 == 0 {
            print("\(self.name)๊ฐ ์ด๊น!")
        }
    }
 
}
 //
//  DiceGame.swift
//  Observer
//
//  Created by Choiwansik on 2023/09/26.
//
 
import Foundation
 
public class DiceGame {
 
    public func add(player: Player) {
        self.players.append(player)
    }
 
    public func play() {
        
    }
 
    public var players = [Player]()
 
}
 //
//  FairDiceGame.swift
//  Observer
//
//  Created by Choiwansik on 2023/09/26.
//
 
import Foundation
 
public class FairDiceGame: DiceGame {
 
    override public func play() {
        guard let diceNumber = (1...6).randomElement() else {
            return
        }
 
        print("์ฃผ์ฌ์ ๋์ง \(diceNumber)")
 
        var iter = self.players.makeIterator()
        while let player = iter.next() {
            player.update(diceNumber: diceNumber)
        }
 
    }
    
}
 ์ฃผ์ฌ์ ๋์ง 4
์์๊ฐ ์ด๊น!
์ฃผ์ฌ์ ๋์ง 6
์์๊ฐ ์ด๊น!
์ฃผ์ฌ์ ๋์ง 5
์ต์์๊ฐ ์ด๊น!
์์์ด๊ฐ ์ด๊น!
์ฃผ์ฌ์ ๋์ง 2
์์๊ฐ ์ด๊น!
์ฃผ์ฌ์ ๋์ง 5
์ต์์๊ฐ ์ด๊น!
์์์ด๊ฐ ์ด๊น!
ํ์ฉ์ฑ
- ์ด๋ค ์ถ์ ๊ฐ๋ ์ด ๋ ๊ฐ์ง ์์์ ๊ฐ๊ณ , ํ๋๊ฐ ๋ค๋ฅธ ํ๋์ ์ข ์์ ์ผ ๋.
 - ํ ๊ฐ์ฒด์ ๊ฐํด์ง ๋ณ๊ฒฝ์ผ๋ก ๋ค๋ฅธ ๊ฐ์ฒด๋ฅผ ๋ณ๊ฒฝํด์ผ ํ๊ณ , ํ๋ก๊ทธ๋๋จธ๋ค์ ์ผ๋ง๋ ๋ง์ ๊ฐ์ฒด๋ค์ด ๋ณ๊ฒฝ๋์ด์ผ ํ๋์ง ๋ชฐ๋ผ๋ ๋๋ ๊ฒฝ์ฐ.
 
์ฐธ์ฌ์
- Subject(
DiceGame)- ๊ฐ์์๋ค์ ์๊ณ ์๋ ์ฃผ์ฒด.
 - ๊ฐ์์๋ค์ ๋ถ์ผ ์ ์๋ ์ธํฐํ์ด์ค๊ฐ ์ ์๋์ด์ผ ํจ
 
 - Observer(
Player)- ์ฃผ์ฒด์ ๋ณํ๋ฅผ ๊ด์ฌ์์ด ํ๋ ์น๊ตฌ๋ค์๊ฒ ํ์ํ ์ธํฐํ์ด์ค ์ ์
 
 - ConcreteSubject(
FairDiceGame) - ConcreteObserver(
OddBettingPlayer,EvenBettingPlayer) 
์๊ฐํด๋ณผ ์ 
- Subject์ Observer ํด๋์ค ๊ฐ์๋ ์ถ์์ ์ธ ๊ฒฐํฉ๋ง์ด ์กด์ฌํ๋ค.
- ์ธํฐํ์ด์ค๋ก๋ง ์ฝํ์์ ๋ฟ์ด๋ค.
 
 - Broadcast ๋ฐฉ์์ ๊ต๋ฅ๋ฅผ ๊ฐ๋ฅํ๊ฒ ํ๋ค.
- ์ด ํจํด์์ ์ฃผ์ฒด์๋ ๊ตฌ์ฒด์ ์ธ ์์ ์๋ฅผ ์ ํ์๊ฐ ์๋ค.
 - ๊ทธ๋ฅ ๋ฑ๋ก๋์ ํํ  ๋ค ๋ฟ๋ฆฌ๊ณ ๋์ด๋ค.
 - ๋ฐ๋์ชฝ์์ ๋ฌด์ํ ์ง ๋ฐ์์ง๋ฅผ ๊ฒฐ์ ํ๋ค.
 
 - ์์ธกํ์ง ๋ชปํ ์ ๋ณด๋ฅผ ๊ฐฑ์ ํ  ์ ์๋ค.
- ๊ฐ์์๋ค๋ผ๋ฆฌ ์๋ก ์ฐ๊ฒฐ๋์ด ์๋ค๊ณ ํ์.
 - ์ ๋ณด ๊ฐฑ์ ์์ฒด์ ๋น์ฉ์ด ํฐ ์ํฉ์ผ ๋, ํ ์ ๋ณด๊ฐ ๋ณ๊ฒฝ๋์์ ๋ ์ฐ๊ฒฐ๋ ๋ชจ๋ ์ฃผ์ฒด๋ค์ ํ์ ๊ฐ์์๋ค์๊ฒ ๋ ์์ ์ ๊ฐํ๊ฒ ํ ์ ์๋ค.
 - ์ด ์์ ์ ๋ถํ์ํ ์๋ ์๊ณ , ๋ด๊ฐ ์ํ๋ ์ ๋ณด๊ฐ ์๋ ์๋ ์๋ค.
 - ์ฆ, ๋ณ๊ฒฝ์ ์ด์ ์ ๋ํ ๊ฒ์ ์ ์ถํ๋ ๊ฒ์ด ์ด๋ ต๋ค.