suvera-dev πŸ₯¦

Design Pattern) μƒμ„±νŒ¨ν„΄ #1 - νŒ©ν† λ¦¬ νŒ¨ν„΄ λ³Έλ¬Έ

iOS/Design Pattern

Design Pattern) μƒμ„±νŒ¨ν„΄ #1 - νŒ©ν† λ¦¬ νŒ¨ν„΄

suvera 2022. 5. 5. 17:17

λ””μžμΈνŒ¨ν„΄ 쀑 μƒμ„±νŒ¨ν„΄μ΄λž€

객체의 생성과정에 μ°Έμ—¬ν•˜λŠ” 것.

객체가 μΈμŠ€ν„΄μŠ€ν™” λ˜λŠ” 과정을 μΆ”μƒν™”ν•©λ‹ˆλ‹€.

객체가 ꡬ성, μƒμ„±λ˜κ³  ν‘œν˜„λ˜λŠ” 방식에 관계없이

μ‹œμŠ€ν…œμ„ λ…λ¦½μ μœΌλ‘œ λ§Œλ“œλŠ”λ° 도움이 λ©λ‹ˆλ‹€ ! 

 

λ²”μœ„λ‘œ λΆ„λ₯˜ν•΄λ³΄μžλ©΄, νŒ¨ν„΄μ„ 주둜 ν΄λž˜μŠ€μ— μ μš©ν•˜λŠ”μ§€

객체에 μ μš©ν•˜λŠ”μ§€ ꡬ뢄해볼 수 μžˆλ‹€.

 

클래슀 : 객체λ₯Ό μƒμ„±ν•˜λŠ” μ±…μž„μ˜ 일뢀λ₯Ό μ„œλΈŒ ν΄λž˜μŠ€κ°€ λ‹΄λ‹Ήν•˜λ„λ‘ λ„˜κΈ°λŠ” 것 

=> νŒ©ν† λ¦¬ λ©”μ„œλ“œ νŒ¨ν„΄

객체 : 객체λ₯Ό μƒμ„±ν•˜λŠ” μ±…μž„μ˜ 일뢀λ₯Ό λ‹€λ₯Έ κ°μ²΄μ—κ²Œ μœ„μž„ν•˜λŠ” 것 

=> 좔상 νŒ©ν† λ¦¬, λΉŒλ”, ν”„λ‘œν† νƒ€μž…, 싱글톀 

 

μ˜€λŠ˜μ€ 이 μ€‘μ—μ„œ νŒ©ν† λ¦¬ λ©”μ„œλ“œ νŒ¨ν„΄κ³Ό 좔상 νŒ©ν† λ¦¬ νŒ¨ν„΄μ— λŒ€ν•΄

λ‹€λ€„λ³΄κ² μŠ΅λ‹ˆλ‹€ !

 

 


🏭 νŒ©ν† λ¦¬ νŒ¨ν„΄μ΄λž€ ? 

객체 생성을 μ „λ‹΄ν•˜λŠ” struct/classλ₯Ό λ§Œλ“€μ–΄ ꡬ체적인 생성과정을 κ·Έ μ•ˆμ— κ΅¬ν˜„ν•˜λŠ” νŒ¨ν„΄ 

 

μ™œ μ‚¬μš©ν• κΉŒ ?

1) 객체의 생성을 κ²‰μœΌλ‘œ λ“œλŸ¬λ‚˜μ§€ μ•Šλ„λ‘ μΊ‘μŠν™”ν•΄μ„œ μ‚¬μš©ν•˜κΈ° μœ„ν•΄μ„œ !

2) 객체 μƒμ„±μ˜ ꡬ체적인 κ΅¬ν˜„μ„ genericν•˜κ²Œ 객체λ₯Ό μ‚¬μš©ν•΄ λΆ„λ¦¬ν•˜κΈ° μœ„ν•΄μ„œ !

 

νŒ©ν† λ¦¬μ™€ κ΄€λ ¨λœ νŒ¨ν„΄μ€ μ•žμ„œ λ§ν–ˆλ“―μ΄ 

2가지가 μžˆμŠ΅λ‹ˆλ‹€ ! 

 

νŒ©ν† λ¦¬ λ©”μ„œλ“œ νŒ¨ν„΄κ³Ό 좔상 νŒ©ν† λ¦¬ νŒ¨ν„΄ !

무가 λ‹€λ₯Έκ±΄μ§€ λ³΄μ‹œμ£ .

 

πŸ­πŸŒ€ νŒ©ν† λ¦¬ λ©”μ„œλ“œ νŒ¨ν„΄ : 단일 μƒν’ˆ 생산 λ‹΄λ‹Ή

(객체 생성 처리λ₯Ό μ„œλΈŒ 클래슀둜 뢄리 ν•΄ μ²˜λ¦¬ν•˜λ„λ‘ μΊ‘μŠν™”ν•˜λŠ” νŒ¨ν„΄)

νŒ©ν† λ¦¬ λ©”μ†Œλ“œ νŒ¨ν„΄(Factory Method Pattern)은 객체λ₯Ό μƒμ„±ν•˜κΈ° μœ„ν•΄ μΈν„°νŽ˜μ΄μŠ€λ₯Ό λ§Œλ“­λ‹ˆλ‹€.

μ–΄λ–€ 클래슀의 μΈμŠ€ν„΄μŠ€λ₯Ό λ§Œλ“€μ§€λ₯Ό μ„œλΈŒν΄λž˜μŠ€μ—μ„œ κ²°μ •ν•˜λ„λ‘ ν•©λ‹ˆλ‹€.

νŒ©ν† λ¦¬ λ©”μ†Œλ“œλ₯Ό μ΄μš©ν•˜λ©΄ μΈμŠ€ν„΄μŠ€λ₯Ό λ§Œλ“œλŠ” 일을 μ„œλΈŒν΄λž˜μŠ€λ‘œ λ―Έλ£° 수 μžˆμŠ΅λ‹ˆλ‹€.

 

πŸ­πŸ‘€ 좔상 νŒ©ν† λ¦¬ νŒ¨ν„΄ : μ„œλ‘œ κ΄€λ ¨μžˆλŠ” μƒν’ˆλ“€μ„ μ „λΆ€ λ¬Άμ–΄μ„œ 같은 μ’…λ₯˜μ˜ μƒν’ˆμ˜ 생산을 λ‹΄λ‹Ή

(νŠΉμ • 그룹에 μ†ν•˜λŠ” μ—¬λŸ¬ 객체듀을 ν•˜λ‚˜μ˜ νŒ©ν† λ¦¬λ‘œ λ¬Άμ–΄μ„œ 생성할 수 μžˆλŠ” νŒ¨ν„΄ )

μΆ”μƒνŒ©ν† λ¦¬ νŒ¨ν„΄μ€ ꡬ상 ν΄λž˜μŠ€μ— μ˜μ‘΄ν•˜μ§€ μ•Šκ³ λ„ μ„œλ‘œ μ—°κ΄€λ˜κ±°λ‚˜ 의쑴적인 객체둜 

이루어진 μ œν’ˆκ΅°μ„ μƒμ‚°ν•˜λŠ” μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ œκ³΅ν•©λ‹ˆλ‹€. ꡬ상 ν΄λž˜μŠ€λŠ” μ„œλΈŒν΄λž˜μŠ€μ—μ„œ λ§Œλ“­λ‹ˆλ‹€. 

 

 

1. νŒ©ν† λ¦¬ λ©”μ„œλ“œ νŒ¨ν„΄ : 단일 μƒν’ˆ 생산 λ‹΄λ‹Ή

 

예λ₯Ό λ“€μ–΄ μ •μž₯ ν•œλ²Œμ„ λ§Œλ“œλŠ” 곡μž₯이 μžˆλ‹€κ³  κ°€μ •ν•΄λ³΄κ² μŠ΅λ‹ˆλ‹€. 

μ •μž₯ μ„ΈνŠΈμ—λŠ” μžμΌ“ μ…”μΈ  바지가 μžˆλ‹€κ³  μƒκ°ν•˜κ³ , 색상 μ’…λ₯˜λ„ 

λΈ”λž™ 넀이비 κ·Έλ ˆμ΄κ°€ μžˆλ‹€κ³  μƒκ°ν•΄λ³Όκ²Œμš” !

 

그러면 νŒ©ν† λ¦¬ λ©”μ„œλ“œμ—μ„œλŠ” 각각 μ œν’ˆλ³„λ‘œ 단일 μ œν’ˆμ„ λ§Œλ“­λ‹ˆλ‹€. 

μžμΌ“ 곡μž₯ / μ…”μΈ  곡μž₯ / 바지 곡μž₯ 으둜 λ‚˜λ‰˜μ–΄μ„œ 

makeJacket(with: 색상)

makeShirt(with: 색상)

makePants(with: 색상)

 

각각의 λ©”μ„œλ“œμ—μ„œ 단일 μ œν’ˆ

즉, μžμΌ“ 곡μž₯μ—μ„œλŠ” λΈ”λž™μžμΌ“, λ„€μ΄λΉ„μžμΌ“, κ·Έλ ˆμ΄μžμΌ“μ„ λ§Œλ“­λ‹ˆλ‹€.

protocol JacketFactory {
    func makeJacket(with: color) -> Jacket
}

class ColoredJacketFactory: JacketFactory {
    static let shared = ColoredJacketFactory()
    private init() { }

    func makeJacket(with: color) {
        switch color {
        case black: return BlackJacket()
        case navy: return NavyJacket()
        case gray: return GrayJacket()
        }
    }
}

class viewController: UIViewController {
    let jacketFactory = ColoredJacketFactory.shared()
    let jacket = JacketFactory.makeJacket(with: "μ›ν•˜λŠ” 색상")
}

 

μ½”λ“œλ‘œ 적어보면 μ΄λŸ°μ‹μœΌλ‘œ ν‘œν˜„λ  수 μžˆλŠ”λ°, μ—¬κΈ°μ„œ 

μžμΌ“ νŒ©ν† λ¦¬λΌλŠ” ν”„λ‘œν† μ½œμ„ ColoredμžμΌ“νŒ©ν† λ¦¬ ν΄λž˜μŠ€κ°€ μ±„νƒμ„ν•΄μ„œ κ΅¬ν˜„μ„ ν•΄μ€λ‹ˆλ‹€.

색상에 맞게 각각의 μžμΌ“μ„ μƒμ‚°ν•˜κ² μ£  

 

μ—¬κΈ°μ„œ νŒ©ν† λ¦¬ λ©”μ„œλ“œμ—μ„œ 각 μ—­ν• λ³„λ‘œ μ§€μΉ­ν•˜λŠ” μš©μ–΄λ‘œ 바꿔보면,

νŒ©ν† λ¦¬μ— λŒ€ν•œ ν”„λ‘œν† μ½œμ„ μ œκ³΅ν•˜λŠ” μžμΌ“νŒ©ν† λ¦¬λŠ” Abstract Creator 라고 ν•©λ‹ˆλ‹€.

ν•΄λ‹Ή ν”„λ‘œν† μ½œμ„ 채택해 μ‹€μ œ νŒ©ν† λ¦¬ 역할을 ν•˜λŠ” μ»¬λŸ¬λ“œμžμΌ“νŒ©ν† λ¦¬λŠ” Concrete Creator 라고 ν•˜κ³ , 

ν•΄λ‹Ή νŒ©ν† λ¦¬μ—μ„œ μƒμ‚°λœ μ œν’ˆλ“€μΈ λΈ”λž™/넀이비/그레이 μžμΌ“λ“€μ€  Concrete Product,

그리고 ν•΄λ‹Ή μ œν’ˆλ“€μ΄ μ±„νƒν•˜κ³  μžˆλŠ” ν”„λ‘œν† μ½œμ΄ μžμΌ“ ν”„λ‘œν† μ½œμ€ Abstract Product라고 ν•©λ‹ˆλ‹€.

 

 

νŒ©ν† λ¦¬ λ©”μ„œλ“œλŠ” 계속 λ§ν–ˆλ‹€μ‹œν”Ό 단일 μƒν’ˆμ„ μƒμ‚°ν•˜λ‹€λ³΄λ‹ˆ, 각 μ œν’ˆμ˜ 생산에 λŒ€ν•œ μ±…μž„λ§Œ μ‘΄μž¬ν•©λ‹ˆλ‹€.

ν•˜μ§€λ§Œ μš°λ¦¬λŠ” μžμΌ“λΏλ§Œμ•„λ‹ˆλΌ 셔츠와 바지도 λ§Œλ“€μ–΄μ„œ μ •μž₯μ„ΈνŠΈλ₯Ό μ™„μ„±ν•΄μ•Ό λ˜λŠ” μƒν™©μž…λ‹ˆλ‹€.

κ·Έλ ‡κ²Œ λ˜λŠ” κ²½μš°μ— μžμΌ“ μ…”μΈ  바지 λͺ¨λ‘μ— λŒ€ν•΄μ„œ 각각 νŒ©ν† λ¦¬ λ©”μ„œλ“œλ₯Ό λ§Œλ“€μ–΄μ•Όλ©λ‹ˆλ‹€. 

 

μ—¬κΈ°μ„œ νŒ©ν† λ¦¬ λ©”μ„œλ“œμ˜ λ¬Έμ œμ μ„ νŒŒμ•…ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

 

class viewController: UIViewController {
    let jacketFactory = ColoredJacketFactory.shared()
    let shirtFactory = ColoredShirtFactory.shared()
    let pantsFactory = ColoredPantsFactory.shared()

    let jacket = JacketFactory.makeJacket(with: "μ›ν•˜λŠ” 색상")
    let shirt = ShirtFactory.makeShirt(with: "μ›ν•˜λŠ” 색상")
    let pants = PantsFactory.makePants(with: "μ›ν•˜λŠ” 색상")
}

μ΄λŸ°μ‹μœΌλ‘œ μΆ”κ°€λ˜λ©΄ 계속 μΆ”κ°€ νŒ©ν† λ¦¬ μΈμŠ€ν„΄μŠ€κ°€ λŠ˜μ–΄λ‚˜κ²Œ λ©λ‹ˆλ‹€. 

λͺ¨λ“  μ œν’ˆλ“€μ΄ λ™μΌν•œ μƒ‰μƒμœΌλ‘œ μ œμž‘λ˜μ–΄μ•Όν•˜λŠ”λ°

μ§€κΈˆ 각 μ œν’ˆλ³„λ‘œ 생산이 λΆ„λ¦¬λ˜μ–΄ μžˆμ–΄μ„œ 

좔후에 μ •μž₯μ„ΈνŠΈμ— μ‹ λ°œμ΄λΌλŠ” μΆ”κ°€ κ΅¬μ„±ν’ˆμ΄ λŠ˜μ–΄λ‚˜κ²Œ λ˜μ–΄

νŒ©ν† λ¦¬κ°€ μΆ”κ°€λ˜μ—ˆμ„ κ²½μš°μ— λ°˜λ“œμ‹œ 같은 색상 μ œν’ˆλΌλ¦¬ λ§Œλ“€μ–΄ λ‚Έλ‹€λŠ” 보μž₯이 μ—†μ£  !

 

κ·Έλž˜μ„œ 이 μƒν™©μ—μ„œλŠ” λ°˜λ“œμ‹œ 같은 색상 μ œν’ˆλΌλ¦¬ μƒμ‚°ν•˜κΈ° μœ„ν•΄

μƒ‰μƒλ³„λ‘œ νŒ©ν† λ¦¬λ₯Ό λ‘κ²Œ λ©λ‹ˆλ‹€ ! 

- λΈ”λž™μ •μž₯ νŒ©ν† λ¦¬

- 넀이비정μž₯ νŒ©ν† λ¦¬

- κ·Έλ ˆμ΄μ •μž₯ νŒ©ν† λ¦¬ 

 

이게 μΆ”μƒνŒ©ν† λ¦¬ νŒ¨ν„΄μ΄λΌκ³  μƒκ°ν•˜λ©΄λ©λ‹ˆλ‹€ .

 

2. 좔상 νŒ©ν† λ¦¬ νŒ¨ν„΄ : μ„œλ‘œ κ΄€λ ¨μžˆλŠ” μƒν’ˆλ“€μ„ μ „λΆ€ λ¬Άμ–΄μ„œ 같은 μ’…λ₯˜μ˜ μƒν’ˆμ˜ 생산을 λ‹΄λ‹Ή

 

μ •μž₯ νŒ©ν† λ¦¬μ—μ„œ 같은 μƒ‰μƒμ˜ μžμΌ“ μ…”μΈ  바지λ₯Ό 생산할 수 μžˆλ„λ‘ λ©”μ„œλ“œλ₯Ό μ •μ˜ν•˜λ©΄ λ©λ‹ˆλ‹€. 

 

protocol SetAbstractFactory {
    func makeJacket() -> Jacket
    func makeShirt() -> Shirt
    func makePants() -> Pants
}

class BlackSetAbstractFactory: SetAbstractFactory {
    func makeJacket() -> Jacket {
        return BlackJacket()
    }
    func makeShirt() -> Shirt {
        return BlackShirt()
    }

    func makePants() -> Pants {
        return BlackPants()
    }
}

μΆ”μƒνŒ©ν† λ¦¬μ˜ κ΅¬μ‘°λŠ” νŒ©ν† λ¦¬ λ©”μ„œλ“œμ™€ λ‹€λ₯΄κ²Œ, μƒ‰μƒλ³„λ‘œ νŒ©ν† λ¦¬λ₯Ό μ •μ˜ν•œ 후에 

각 색상별 μ œν’ˆλ§Œ μƒμ‚°λ˜λ„λ‘ λ”°λ‘œ νŒ©ν† λ¦¬λ₯Ό μ •μ˜ν•©λ‹ˆλ‹€.

μ •μž₯μ„ΈνŠΈμΆ”μƒνŒ©ν† λ¦¬λ₯Ό μ±„νƒν•œ λΈ”λž™μ •μž₯νŒ©ν† λ¦¬μ—μ„œ 

λΈ”λž™ μžμΌ“/ μ…”μΈ / 바지λ₯Ό μƒμ‚°ν•΄λƒ…λ‹ˆλ‹€. 

κ΅¬μ‘°λ„λ‘œ 보면 μ •μž₯νŒ©ν† λ¦¬κ°€ μΆ”μƒνŒ©ν† λ¦¬μ΄κ³  

이λ₯Ό μ±„νƒν•œ λΈ”λž™μ •μž₯νŒ©ν† λ¦¬, 넀이비정μž₯νŒ©ν† λ¦¬, κ·Έλ ˆμ΄μ •μž₯νŒ©ν† λ¦¬

그리고 κ±°κΈ°μ„œ λ§Œλ“€μ–΄λ‚Έ λΈ”λž™μžμΌ“, λΈ”λž™μ…”μΈ , λΈ”λž™λ°”μ§€λŠ” AbstractProduct인

μžμΌ“, μ…”μΈ , 바지 ν”„λ‘œν† μ½œμ„ 각각 μ±„νƒν•˜κ³  있음

 

 

μΆ”μƒνŒ©ν† λ¦¬λŠ” νŒ©ν† λ¦¬ λ©”μ„œλ“œμ˜ μƒμœ„ν˜Έν™˜μ΄ μ•„λ‹ˆλ©°

각 νŒ¨ν„΄λ³„λ‘œ μž₯단점이 μ‘΄μž¬ν•©λ‹ˆλ‹€. 

 

κ΄€λ ¨λœ 객체λ₯Ό μ—¬λŸ¬κ°œ 생산할 수 μžˆλŠ” μΆ”μƒνŒ©ν† λ¦¬λŠ” 

각 μš΄μ˜μ²΄μ œλ³„λ‘œ κ·Έλ €μ•Όν•˜λŠ” 뷰의 μ’…λ₯˜λŠ” λ™μΌν•˜λ‚˜ 세뢀적인 κ΅¬ν˜„μ΄ λ‹€λ₯Όκ²½μš°

ViewAbstractFactoryλ₯Ό ν™œμš©ν•΄μ„œ 각 μš΄μ˜μ²΄μ œλ³„λ‘œ μ›ν•˜λŠ” λ·°λ₯Ό κ·Έλ¦¬λŠ” κ²½μš°κ°€ κ°€λŠ₯ν•©λ‹ˆλ‹€ !

protocol ViewAbstractFactory {
    public func createButton() -> Button
    public func createLabel() -> Label
}

protocol Button {
    func click()
}

protocol Label {
    var text: String
}
class LinuxViewFactory: ViewAbstractFactory {
    func createButton() -> Button {
        return LinuxButton()
    }
    func createLabel() -> Label {
        return LinuxLabel(text: "Linux Label")
    }

}

class LinuxButton: Button {
    func click() {
        print("Linux Button Click")

    }

}

class LinuxLabel: Label {
    var text: String init(text: String) {
        self.text = text

    }
}
let factory = LinuxViewFactory()
let button = factory.createButton()
let label = factory.createLabel()

μœ„μ˜ μ˜ˆμ‹œμ²˜λŸΌ μ‚¬μš©ν•΄μ£Όλ©΄ 되고 !

각 UI μš”μ†Œλ“€μ΄ μ „λΆ€ 연관이 μžˆλŠ” 경우 μ‚¬μš©ν•˜κΈ°μ— μ ν•©ν•˜λ‹€κ³  ν•©λ‹ˆλ‹€ !

 

 

λ‹¨μΌν•œ μ œν’ˆμ„ 생산할 수 μžˆλŠ” νŒ©ν† λ¦¬ λ©”μ„œλ“œλŠ”

μ•„λž˜μ²˜λŸΌ ν”„λ‘œμ νŠΈμ—μ„œ μ‚¬μš©ν•˜λŠ” λ·°μ»¨μ΄λ‚˜ 코디넀이터λ₯Ό 각 ν΄λž˜μŠ€μ—μ„œ μƒμ‚°ν•˜λŠ” 것이 μ•„λ‹ˆλΌ 

각각 νŒ©ν† λ¦¬ λ©”μ„œλ“œλ₯Ό λ§Œλ“€μ–΄μ„œ λ…λ¦½μ μœΌλ‘œ 생산 μ±…μž„μ„ λ§‘κΈ°λŠ” ν˜•νƒœκ°€ κ°€λŠ₯ν•©λ‹ˆλ‹€. 

protocol RouterProtocol {

}

protocol AuthCoordinator {

}

protocol CoordinatorFactoryProtocol {
    func makeAuthCoordinatorBox(router: RouterProtocol, coordinatorFactory: CoordinatorFactoryProtocol, viewControllerFactory: ViewControllerFactory) -> AuthCoordinator
}

final class CoordinatorFactory: CoordinatorFactoryProtocol {
    func makeAuthCoordinatorBox(router: RouterProtocol, coordinatorFactory: CoordinatorFactoryProtocol, viewControllerFactory: ViewControllerFactory) -> AuthCoordinator {
        let coordinator = AuthCoordinator(router: router, coordinatorFactory: coordinatorFactory, viewControllerFactory: viewControllerFactory)

        return coordinator
    }
}

protocol AViewController {

}


class ViewControllerFactory {
    func instantiateAViewController() -> AViewController {

    }
}

 

Comments