Swift

Swift - 디자인 패턴(생성 관련) - 빌더 패턴

iosos 2023. 7. 8. 17:14

* Builder pattern

- 복잡한 객체의 생성과 표현을 서로 분리해 유사한 타입을 생성하기 위해 동일한 프로세스가 사용될 수 있게 함 

- 객체 생성 과정을 단계별로 나누고, 유연하고 가독성 있는 방법으로 복잡한 객체를 생성하는 디자인 패턴

- 주로 많은 매개변수를 가진 객체를 생성하거나, 객체 생성 과정을 다양하게 구성하고자 할 때 사용 

 

- 복잡한 객체를 일관된 방식으로 생성하여 가독성 있게 만들어주고, 객체 생성 과정에 유연성 제공 

- 객체 생성에 필요한 다양한 구성 요소들을 분리하여 유지 및 확장이 용이하게 만듦 

- 선택적인 매개변수나 기본값이 있는 매개변수 등 처리하기 용이 

- 작은 규모의 객체에서는 비효율적 

 

 

* 구성요소

1. 제품(Product)

- 빌더 패턴을 통해 생성하고자 하는 복잡한 객체를 나타냄

- 일반적으로 이 객체는 여러 속성을 가지며, 이들 속성을 설정하기 위한 setter 메서드 등이 제공

 

 

2. 빌더(Builder)

- 제품의 생성 과정을 추상화한 인터페이스 제공

- 제품의 각 속성을 설정하기 위한 메서드들을 포함 

- 실제 제품을 생성하는 역할은 아님 

 

 

3. 구체적인 빌더 (Concreate Builder)

- 빌더 인터페이스를 구현하여 실제로 제품을 생성하는 역할

- 제품을 생성하기 위해 필요한 단계들을 구현, 제품의 속성들을 설정하는 메서드를 구현

 

 

4. 디렉터 (Director)

- 빌더를 사용하여 제품을 생성하는 역할 

- 빌더의 메서드를 호출하여 제품을 생성하고 조립하는 과정 제어 

 


* 빌더 패턴 활용 예시 1)

import UIKit

class BuilderPatternViewController: UIViewController {

    // Pet 구조체 설정
    struct Pet {
        var name: String? = nil
        var age : Int? = nil
    }
    
    // PetBuilder 빌더 클래스 설정
    class PetBuilder {
        
        private var pet : Pet = Pet()
        
        
        // 빌더 인스턴스 자신을 반환
        func withName(_ name : String) -> Self{
            pet.name = name
            return self
        }
        
        func withAge(_ age : Int) -> Self{
            pet.age = age
            return self
        }
        
        // 최종적으로 Pet 구조체를 생성하고 반환 
        func build() -> Pet {
            return self.pet
        }
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()

        let myPet = PetBuilder()
            .withName("야옹이")
            .withAge(10)
            .build()

       print(myPet)
    }

}

- Pet 구조체가 제품에 해당하며 name, age 속성을 가짐

- PetBuilder 클래스가 빌더에 해당하며, 제품(Pet)의 생성 과정을 추상화한 인터페이스로 제공 

- viewDidLoad() 메서드가 디렉터 역할 수행 

- 마지막에 build() 함으로써 Pet 구조체를 생성

 

 

 


예시) 

 

import UIKit

class BuilderPatternViewController: UIViewController {
 
    // Pet 구조체 설정
    struct Pet {
        var name: String? = nil
        var age : Int? = nil
        
        init() {}
        init(builder : SecondPetBuilder){      //SeconPetBuilder를 인자로 받아 해당 빌더의 속성을 사용하여 Pet 초기화
            self.name = builder.name
            self.age = builder.age
        }
    }
    
    
    class SecondPetBuilder {
        var name: String? = nil
        var age : Int? = nil
        
        typealias BuilderClosure = (SecondPetBuilder) -> ()
        
        init(buildClosure : BuilderClosure){
            buildClosure(self)
        }
    }
    
    
    
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        
        let petBuilder = SecondPetBuilder { builder in
            builder.name = "댕댕이"
            builder.age = 10
        }
        
        let mySecondPet = Pet(builder: petBuilder)
        
        print(mySecondPet)

    }

}

- init(builder : SecondPetBuilder) : SeconPetBuilder를 인자로 받아 해당 빌더의 속성을 사용하여 Pet 초기화

- viewDidLoad() -> SecondPetBuilder를 이용하여 빌더 인스턴스 petBuilder 생성

- 클로절르 통해 petBuilder의 속성 설정 

- petBuilder를 인자로 전달하여 초기화하고 Pet 객체 생성 

 

 

	typealias BuilderClosure = (SecondPetBuilder) -> ()
        
        init(buildClosure : BuilderClosure){
            buildClosure(self)
        }
    }

- 클로저를 이용하여 SecondPetBuilder의 속성을 초기화하는 부분

- typealias : 타입에 대해 별칭을 지정하는 기능

- BuilderClosure라는 새로운 이름으로 '(SecondPetBuilder) -> () ' 타입의 별칭을 정의한 것

- 이 클로저는 SecondPetBuilder를 인자로 받고 반환 값이 없는 클로저 

- BuilderClosure를 사용하여 클로저 타입을 표현할 때 해당 별칭을 사용할 수 있음 

 

- 'buildClosure(self)' : buildClosure 클로저를 실행하면서, self 인자로 전달 

- self 는 SecondPetBuilder 인스턴스를 나타냄 

- 이를 통해 클로저 내에서 SecondPetBuilder의 속성을 설정 

 

 

 

 

 

 

 

 

 

참고)

https://velog.io/@fezravien/Swift-%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4-Design-Patterns-%EC%83%9D%EC%84%B1-%ED%8C%A8%ED%84%B4-%EB%B9%8C%EB%8D%94-%ED%8C%A8%ED%84%B4Builder-pattern 

 

[Swift] 디자인 패턴 (Design Patterns) - 생성 패턴 (빌더 패턴, Builder pattern)

디자인 패턴의 생성 패턴(Creational Patterns) 중 빌더 패턴(Builder pattern)입니다 😗

velog.io

https://www.youtube.com/watch?v=tFOLV35g4Ac