Notice
Recent Posts
Recent Comments
Link
ยซ   2024/05   ยป
์ผ ์›” ํ™” ์ˆ˜ ๋ชฉ ๊ธˆ ํ† 
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Archives
Today
Total
๊ด€๋ฆฌ ๋ฉ”๋‰ด

lgvv98

[Swift] Multicast Delegate Pattern ๋ณธ๋ฌธ

apple/๐Ÿก DesignPattern & Architecture

[Swift] Multicast Delegate Pattern

๐Ÿฅ• ์บ๋Ÿฟ๋งจ 2022. 6. 7. 10:45

Multicast Delegate Pattern

โœ… Multicast Delegate Pattern

 

์•„๋ž˜์˜ ๋ฌธ์„œ๋ฅผ ๊ตฌ์ž…ํ•˜์—ฌ ์˜์–ด ๋ฌธ์„œ๋ฅผ ๋ฒˆ์—ญํ•˜๊ณ  ์ดํ•ดํ•œ ๊ฒƒ์„ ๋ฐ”ํƒ•์œผ๋กœ ๊ธ€์„ ์ž‘์„ฑํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

https://www.raywenderlich.com/books/design-patterns-by-tutorials/v3.0/chapters/16-multicast-delegate-pattern

 

Design Patterns by Tutorials, Chapter 16: Multicast Delegate Pattern

The multicast delegate pattern is a behavioral pattern that’s a variation on the delegate pattern. It allows you to create one-to-many delegate relationships, instead of one-to-one relationships in a simple delegate.

www.raywenderlich.com

 

multicast delegate ํŒจํ„ด์€ delegate ํŒจํ„ด์˜ ๋ณ€ํ˜•์ธ ํ–‰๋™ ํŒจํ„ด์ด๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๋‹จ์ˆœ delegate์˜ 1:1 ๊ด€๊ณ„ ๋Œ€์‹  1:N delegate ๊ด€๊ณ„๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

multicast delegate pattern

 

1. object needing a delegate(a.k.a delegating object)๋Š” ํ•˜๋‚˜ ํ˜น์€ ๊ทธ ์ด์ƒ์˜ delegate๋ฅผ ๊ฐ€์ง€๋Š” ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค.

2. delegate protocol์€ ๊ตฌํ˜„ํ•˜๊ฑฐ๋‚˜ ๊ตฌํ˜„ํ•ด์•ผํ•˜๋Š” ๋ฉ”์†Œ๋“œ๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. (protocol ์ •์˜์—์„œ optional๋กœ ๋งŒ๋“œ๋Š” ๊ธฐ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค.)

3. delegate(s)๋Š” delegate protocol์„ ๊ตฌํ˜„ํ•˜๋Š” ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค.

4. multicast delegate๋Š” delegate๋ฅผ ๋ณด์œ ํ•˜๋Š” helper class์ž…๋‹ˆ๋‹ค. delegate-worthy ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•  ๋•Œ๋งˆ๋‹ค ๊ฐ์ž์—๊ฒŒ ํ†ต์ง€ํ•ฉ๋‹ˆ๋‹ค.

 

๋ฉ€ํ‹ฐ์บ์ŠคํŠธ ๋”œ๋ฆฌ๊ฒŒ์ดํŠธ ํŒจํ„ด๊ณผ ๋”œ๋ฆฌ๊ฒŒ์ดํŠธ ํŒจํ„ด์˜ ์ฃผ์š” ์ฐจ์ด์ ์€ ๋ฉ€ํ‹ฐ์บ์ŠคํŠธ ๋”œ๋ฆฌ๊ฒŒ์ดํŠธ๋ฅผ ์œ„ํ•ด์„œ helper class๊ฐ€ ์žˆ๋‹ค๋Š” ์ ์ž…๋‹ˆ๋‹ค. Swift๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์ด ํด๋ž˜์Šค๋ฅผ ์ œ๊ณตํ•˜์ง€ ์•Š์œผ๋‚˜, ์šฐ๋ฆฌ๊ฐ€ ์ด๋ฒˆ ์‹œ๊ฐ„์— ๋งŒ๋“ค์–ด ๋ณผ ์˜ˆ์ •์ž…๋‹ˆ๋‹ค.

 

Note: Swift 5.1์—์„œ Combine ํ”„๋ ˆ์ž„์›Œํฌ ์•ˆ์—์„œ Multicast ์œ ํ˜•์„ ๋„์ž…ํ–ˆ์Šต๋‹ˆ๋‹ค. Combine ํ”„๋ ˆ์ž„์›Œํฌ ๋‚ด์— ์žˆ๋Š” ๊ฒƒ์€ ์—ฌ๊ธฐ์„œ ์ด์•ผ๊ธฐํ•˜๋Š” MulticastDelegate์™€๋Š” ๋‹ค๋ฆ…๋‹ˆ๋‹ค. 

Combine์— ๋Œ€ํ•ด์„œ ๋” ์ž์„ธํžˆ ์•Œ๊ณ  ์‹ถ๋‹ค๋ฉด ์•„๋ž˜ ๋งํฌ๋ฅผ ํ™•์ธํ•ด์ฃผ์„ธ์š”!

(RxSwift ๋งŒํผ Combine์ด ์ •๋ฆฌ๊ฐ€ ์ž˜ ๋˜์–ด ์žˆ์–ด์„œ, ๋‚˜์ค‘์— ์‚ฌ์„œ ๊ณต๋ถ€ํ•ด์•ผ์ง€ !_!)

https://www.raywenderlich.com/books/combine-asynchronous-programming-with-swift

 

Combine: Asynchronous Programming with Swift

<h2>Master declarative asynchronous programming with Swift using the Combine framework!</h2> <p>Writing asynchronous code can be challenging, with a variety of possible interfaces to represent, perform, and consume asynchronous work — delegates, notifica

www.raywenderlich.com

 

 

When should you use it?

1:N delegate ๊ด€๊ณ„๋ฅผ ๋งŒ๋“ค ๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

 

์˜ˆ๋ฅผ ๋“ค์–ด์„œ ์ด ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜์—ฌ, ๋‹ค๋ฅธ ๊ฐ์ฒด์— ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ์šฐ ์—ฌ๋Ÿฌ ๊ฐ์ฒด์— ์•Œ๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ๊ฐ delegate๋Š” ์Šค์Šค๋กœ์˜ ์ƒํƒœ๋ฅผ ์—…๋ฐ์ดํŠธ ํ•˜๊ฑฐ๋‚˜, ์‘๋‹ต์œผ๋กœ ๊ด€๋ จ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

 

Playground example

 

์šฐ์„  MuticastDelegate helper class๋ฅผ ๋งŒ๋“ค์–ด ๋ด…์‹œ๋‹ค!

// 1
public class MulticastDelegate<ProtocolType> {

  // MARK: - DelegateWrapper
  // 2
  private class DelegateWrapper {

    weak var delegate: AnyObject?

    init(_ delegate: AnyObject) {
      self.delegate = delegate
    }
  }
}

 

 

1. MulticaseDelegate์€ ๋ชจ๋“  ProtocolType์„ ์ œ๋„ค๋ฆญ ํ˜•์‹์œผ๋กœ ํ—ˆ์šฉํ•˜๋Š” ์ œ๋„ค๋ฆญ ํด๋ž˜์Šค๋กœ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. Swift๋Š” ์•„์ง <ProtocolType>์„ ํ”„๋กœํ† ์ฝœ๋งŒ์œผ๋กœ ์ œํ•œํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ProtocolType์— ๋Œ€ํ•œ ํ”„๋กœํ† ์ฝœ ๋Œ€์‹  ๊ตฌ์ฒด์ ์ธ ํด๋ž˜์Šค ์œ ํ˜•์„ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ํ”„๋กœํ† ์ฝœ์„ ์‚ฌ์šฉํ•  ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์œผ๋ฏ€๋กœ ์ผ๋ฐ˜ ์œ ํ˜•์˜ ์ด๋ฆ„์„ Type์ด ์•„๋‹Œ ProtocolType์œผ๋กœ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค!

2. DelegateWrapper๋ฅผ ๋‚ด๋ถ€ ํด๋ž˜์Šค๋กœ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. ์ด ์˜ต์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ, delegate ๊ฐ์ฒด๋ฅผ weak property๋กœ ๋ฌถ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฐ ๋ฐฉ์‹์œผ๋กœ multicast delegate๋Š” strong warpper ์ธ์Šคํ„ด์Šค๋ฅผ ์ง์ ‘ delegatesํ•˜์ง€ ์•Š๊ณ ๋„ ๋ณด์œ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

์•ˆํƒ€๊น๊ฒŒ๋„ ์—ฌ๊ธฐ์„œ๋Š” delegate property์„ ProtocolType๋Œ€์‹  AnyObject๋กœ ์„ ์–ธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด weak ๋ณ€์ˆ˜๋Š” AnyObject(์ฆ‰, ํด๋ž˜์Šค)์ด์–ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ProtocolType์ด AnyObject๋กœ์จ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ œ๋„ค๋ฆญ ํƒ€์ž…์ด๋ผ๊ณ  ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ํ”„๋ฅดํ† ์ฝœ ์ž์ฒด๋ฅผ ๊ฐ์ฒด๊ฐ€ ์•„๋‹Œ Type์œผ๋กœ ์ „๋‹ฌํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

 

// MARK: - Instance Properties
// 1
private var delegateWrappers: [DelegateWrapper]

// 2
public var delegates: [ProtocolType] {
  delegateWrappers = delegateWrappers
    .filter { $0.delegate != nil }
  return delegateWrappers.map
    { $0.delegate! } as! [ProtocolType]
}

// MARK: - Object Lifecycle
// 3
public init(delegates: [ProtocolType] = []) {
  delegateWrappers = delegates.map {
    DelegateWrapper($0 as AnyObject)
  }
}

1. DelegateWrapper๊ฐ€ DelegateWrapper ์ธ์Šคํ„ด์Šค๋ฅผ ๋ณด์œ ํ•˜๋„๋ก ์„ ์–ธํ•ฉ๋‹ˆ๋‹ค. DelegateWrapper ์ธ์Šคํ„ด์Šค๋Š” MulticastDelegate์— ์˜ํ•ด์„œ ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค.

2. delegate๋ฅผ ์œ„ํ•œ ์—ฐ์‚ฐ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒํ•˜๋ฉด ํ•„ํ„ฐ๋ง ํ•œ ๋‹ค์Œ์— nil์ด ์•„๋‹Œ delegate์˜ ๋ฐฐ์—ด์„ ๋ฐ˜ํ™˜ํ•ด์ค๋‹ˆ๋‹ค!

3. ๋งˆ์ง€๋ง‰์œผ๋กœ ์ด๋‹ˆ์…œ๋ผ์ด์ €๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค!

 

์ด๋ฏธ ์ƒ์„ ๋œ ๋ฉ€ํ‹ฐ์บ์ŠคํŠธ delegate๋ฅผ ์ถ”๊ฐ€ ๋ฐ ์‚ญ์ œํ•˜๋Š” ์ˆ˜๋‹จ๋„ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. 

// MARK: - Delegate Management
// 1
public func addDelegate(_ delegate: ProtocolType) {
  let wrapper = DelegateWrapper(delegate as AnyObject)
  delegateWrappers.append(wrapper)
}

// 2
public func removeDelegate(_ delegate: ProtocolType) {
  guard let index = delegateWrappers.firstIndex(where: {
    $0.delegate === (delegate as AnyObject)
  }) else {
    return
  }
  delegateWrappers.remove(at: index)
}

 

1. ์ด๋ฆ„์—์„œ ์•Œ ์ˆ˜ ์žˆ๋“ฏ์ด delegate๋ฅผ addํ•˜๋Š” ๋ฉ”์†Œ๋“œ์ž…๋‹ˆ๋‹ค. delegate๋ฅผ AnyObject๋กœ ๋ž˜ํ•‘ํ•ฉ๋‹ˆ๋‹ค.

2. ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ remove๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค! 

 

๋‹ค์Œ์œผ๋กœ๋Š” ์‹ค์ œ๋กœ delegate๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ์ˆ˜๋‹จ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. 

public func invokeDelegates(_ closure: (ProtocolType) -> ()) {
  delegates.forEach { closure($0) }
}

์—ฐ์‚ฐ ํ”„๋กœํผํ‹ฐ๋ฅผ delegate๋ฅผ ์ž๋™์œผ๋กœ ํ•„ํ„ฐ๋งํ•˜๊ณ , ํด๋กœ์ €๋ฅผ ์ „๋‹ฌ๋œ ์†์„ฑ์„ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

 

์—ฌ๊ธฐ๊นŒ์ง€๊ฐ€ MulticastDelegate helper class๊ฐ€ ์ƒ๊ฒผ๊ณ , ๋‹ค์Œ ์ž‘์—…์„ ๋ณด์ฃ !

// MARK: - Delegate Protocol
public protocol EmergencyResponding {
  func notifyFire(at location: String)
  func notifyCarCrash(at location: String)
}

EmergencyResponding ํ”„๋กœํฌํ†จ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

 

// MARK: - Delegates
public class FireStation: EmergencyResponding {

  public func notifyFire(at location: String) {
    print("Firefighters were notified about a fire at "
      + location)
  }

  public func notifyCarCrash(at location: String) {
    print("Firefighters were notified about a car crash at "
      + location)
  }
}

public class PoliceStation: EmergencyResponding {

  public func notifyFire(at location: String) {
    print("Police were notified about a fire at "
      + location)
  }

  public func notifyCarCrash(at location: String) {
    print("Police were notified about a car crash at "
      + location)
  }
}

๋‘๊ฐœ์˜ delegate ๊ฐ์ฒด๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. ๊ธด๊ธ‰์ƒํ™ฉ์ด ๋ฐœ์ƒํ•˜๋ฉด ๊ฒฝ์ฐฐ๊ด€๊ณผ ์†Œ๋ฐฉ๊ด€์ด ๋ชจ๋‘ ๋Œ€์‘ํ•ฉ๋‹ˆ๋‹ค.

 

// MARK: - Delegating Object
public class DispatchSystem {
  let multicastDelegate =
    MulticastDelegate<EmergencyResponding>()
}

MulticastDelegate์„ ํƒ€์ž…์œผ๋กœํ•˜๋Š” ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ•ฉ๋‹ˆ๋‹ค. 

 

// MARK: - Example
let dispatch = DispatchSystem()
var policeStation: PoliceStation! = PoliceStation()
var fireStation: FireStation! = FireStation()

dispatch.multicastDelegate.addDelegate(policeStation)
dispatch.multicastDelegate.addDelegate(fireStation)

dispatch๋ฅผ DispatchSystem ์ธ์Šคํ„ด์Šค๋กœ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ policeStation ๋ฐ fireStation์— ๋Œ€ํ•œ ์œ„์ž„ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ณ  dispatch.multicastDelegate.addDelegate(_:)๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๋‘˜ ๋‹ค ๋“ฑ๋กํ•ฉ๋‹ˆ๋‹ค.

 

dispatch.multicastDelegate.invokeDelegates {
  $0.notifyFire(at: "Ray’s house!")
}

// console
// Police were notified about a fire at Ray's house!
// Firefighters were notified about a fire at Ray's house!

 

 

delegate๊ฐ€ 0์ด ๋˜๋Š” ๊ฒฝ์šฐ, multicast delegate์— ๋Œ€ํ•œ ์–ด๋– ํ•œ ํ–ฅํ›„ ํ˜ธ์ถœ์— ๋Œ€ํ•ด์„œ๋„ ํ†ต์ง€๋˜๋ฉด ์•ˆ๋ฉ๋‹ˆ๋‹ค.

print("")
fireStation = nil

dispatch.multicastDelegate.invokeDelegates {
  $0.notifyCarCrash(at: "Ray's garage!")
}

// ์ฝ˜์†”
// Police were notified about a car crash at Ray's garage!

nil๋กœ ์ฒ˜๋ฆฌํ•˜์—ฌ ์ฝ˜์†”์— ๋‚˜ํƒ€๋‚˜์ง€ ์•Š๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

What should you be careful about?

 

์ด ํŒจํ„ด์€ "information only" delegate ํ˜ธ์ถœ์— ๊ฐ€์žฅ ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค.

 

delegate๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ์ œ๊ณตํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ ์ด ํŒจํ„ด์ด ์ œ๋Œ€๋กœ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด ์ด ํŒจํ„ด์˜ ๊ฒฝ์šฐ ์—ฌ๋Ÿฌ delegate๋“ค์ด ๋ฐ์ดํ„ฐ๋ฅผ ์ œ๊ณตํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ •๋ณด๊ฐ€ ์ค‘๋ณต๋˜๊ฑฐ๋‚˜ ์ฒ˜๋ฆฌ๊ฐ€ ๋‚ญ๋น„๋  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

 

์ด ๊ฒฝ์šฐ์—๋Š” ๋‹ค์Œ ๋””์ž์ธ ํŒจํ„ด์—์„œ ๋‹ค๋ฃจ๋Š” chain-of-responsibility pattern ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ๊ณ ๋ คํ•˜์„ธ์˜ค!

 

Tutorial project

๋ฉ€ํ‹ฐ ์บ์ŠคํŠธ ํŒจํ„ด์ž…๋‹ˆ๋‹ค! ์–ด๋ ต์ง€ ์•Š์•„์š”!

https://github.com/lgvv/DesignPattern/tree/main/multicast-delegate-pattern

 

GitHub - lgvv/DesignPattern: โœจ ๋””์ž์ธ ํŒจํ„ด์„ ๊ณต๋ถ€ํ•ฉ๋‹ˆ๋‹ค!

โœจ ๋””์ž์ธ ํŒจํ„ด์„ ๊ณต๋ถ€ํ•ฉ๋‹ˆ๋‹ค! Contribute to lgvv/DesignPattern development by creating an account on GitHub.

github.com

 

Key points

์ด๋ฒˆ ์‹œ๊ฐ„์—๋Š” multicast delegate pattern์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด์•˜์Šต๋‹ˆ๋‹ค.

 - ๋ฉ€ํ‹ฐ์บ์ŠคํŠธ ๋”œ๋ฆฌ๊ฒŒ์ดํŠธ ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜๋ฉด 1:N delegate ๊ด€๊ณ„๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—๋Š” 4๊ฐ€์ง€ ์œ ํ˜•์ด ์žˆ์Šต๋‹ˆ๋‹ค.

(์œ„์˜ ์ด๋ฏธ์ง€ ์ฐธ๊ณ )

 - object needing a delegate์—๋Š” ํ•˜๋‚˜ ์ด์ƒ์˜ delegates๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. delegate๋Š” ๊ตฌํ˜„ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. delegates๋Š” ํ”„๋กœํ† ์ฝœ์ด๊ณ , multicast delegate๋Š” delegate๋ฅผ ๋ณด์œ ํ•˜๊ณ  ์žˆ๋Š” helper class์ž…๋‹ˆ๋‹ค.

 - Swift์—์„œ๋Š” ์ง์ ‘์ ์œผ๋กœ multicast delegate ๊ฐ์ฒด๋ฅผ ์ œ๊ณตํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด ํŒจํ„ด์„ ์œ„ํ•ด ์ง์ ‘ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์€ ์‰ฝ์Šต๋‹ˆ๋‹ค.

 

'apple > ๐Ÿก DesignPattern & Architecture' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[Swift] FlyWeight Pattern  (1) 2022.06.09
[Swift] Facade Pattern  (1) 2022.06.07
[Swift] State Pattern  (0) 2022.05.30
[Swift] Prototype Pattern  (0) 2022.05.28
[Swift] Iterator Pattern  (0) 2022.05.13
Comments