L-j-h-c / TIL

CS, Swift, Java, C++, 개발 관련 공부한 내용 정리
11 stars 0 forks source link

[Design Pattern] Facade Pattern #18

Closed L-j-h-c closed 2 years ago

L-j-h-c commented 2 years ago

Facade Pattern(퍼사드 패턴)

소스코드 출처

정의

퍼사드 패턴은 여러 API가 존재할 때 , 기능등을 통합한 간소화고자 하는 목적을 가진 패턴이다. 함께 동작하는 여러 API를 사용하기 쉽도록 가공할 수 있다. 퍼사드란 '건물의 정면'이라는 의미인데, 그 뜻 그대로 전체 건물이 아니라 정면부분을 노출시켜서 볼 수 있다는 느낌으로 생각하면 될 것 같다.

샘플 코드

아래는 Project라는 클래스와 Client, ProductManager, Designer, Develop 등의 클래스를 조합하여 OrderFacade 클래스를 구성한 예시이다.

class Project {
    let title: String
    let description: String
    var deadline: Date?

    init(title: String, description: String) {
        self.title = title
        self.description = description
    }
}

클래스에 채택해줄 프로토콜들을 선언한다.

protocol ClientResponsibilities: class {
    func createProposal(for project: Project)
    func sendPayment()
}
protocol ProductManagerResponsibilities: class {
    func setDeadline(date: Date)
    func ...
    ...
}
protocol DesignerResponsibilities: class { }
protocol DeveloperResponsibilities: class { }

프로토콜을 채택해주는 클래스들이다.

class Client: ClientResponsibilities {
    let name: String

    init(name: String) {
        self.name = name
    }

    func createProposal(for project: Project) {
        // Client creates a proposal
    }

    func sendPayment() {
        // Client sends payment to a company
    }
}
class ProductManager: ProductManagerResponsibilities { }
class Designer: DesignerResponsibilities { }
class Developer: DeveloperResponsibilities { }

다양한 클래스들을 조합하여 아래의 OrderFacade 클래스를 정의한다.

class OrderFacade {
    let client: Client
    let productManager: ProductManager
    let designer: Designer
    let developers: [Developer]

    init(client: Client,
         productManager: ProductManager,
         designer: Designer,
         developers: [Developer]) {

        self.client = client
        self.productManager = productManager
        self.developers = developers
        self.designer = designer
    }

    public func placeOrder(project: Project) {
        client.createProposal(for: project)
        designer.createSketch()
        productManager.acceptSketch()
        productManager.setDeadline(date: Date())
        designer.createFinalDesign()
        productManager.acceptFinalDesign()
        client.sendPayment()

        developers.forEach {
            $0.startDevelopment()
        }
    }
}

아래와 같이 인스턴스를 생성하고 placeOrder하면 클래스들에 존재하는 일련의 메서드들이 실행된다.

let client = Client(name: "Some Large Company")
let project = Project(title: "New Big Project", description: "Confidential")
let productManager = ProductManager(name: "Steve", project: project)
let designer = Designer(name: "Johny", project: project)
let developer1 = Developer(name: "Steve", project: project)
let developer2 = Developer(name: "Craig", project: project)

let orderFacade = OrderFacade(client: client,
                              productManager: productManager,
                              designer: designer,
                              developers: [developer1, developer2])
orderFacade.placeOrder(project: project)