빌더 패턴
Coddy C++ 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 104개 중 93번째.
Builder 패턴은 복잡한 객체의 구축 과정과 표현을 분리하여, 다양한 configuration을 단계별로 생성할 수 있게 합니다. 이는 객체에 많은 선택적 매개변수가 있거나 특정한 구축 순서가 필요한 경우 특히 유용합니다.
많은 매개변수를 사용하는 생성자(복잡해지는)가 아니라, Builder는 각 구성 옵션에 대해 명확하고 이름이 지정된 메서드를 제공합니다:
#include <iostream>
#include <string>
class Pizza {
public:
std::string dough;
std::string sauce;
std::string topping;
bool cheese;
void describe() const {
std::cout << dough << " dough, " << sauce << " sauce, "
<< topping << (cheese ? ", with cheese" : "") << "\n";
}
};
class PizzaBuilder {
private:
Pizza pizza;
public:
PizzaBuilder& setDough(const std::string& d) {
pizza.dough = d;
return *this;
}
PizzaBuilder& setSauce(const std::string& s) {
pizza.sauce = s;
return *this;
}
PizzaBuilder& setTopping(const std::string& t) {
pizza.topping = t;
return *this;
}
PizzaBuilder& addCheese() {
pizza.cheese = true;
return *this;
}
Pizza build() { return pizza; }
};
int main() {
Pizza margherita = PizzaBuilder()
.setDough("thin")
.setSauce("tomato")
.setTopping("basil")
.addCheese()
.build();
margherita.describe();
}각 setter 메서드는 builder에 대한 참조(return *this)를 반환하여 유창한 인터페이스를 위한 메서드 체이닝을 가능하게 합니다. build() 메서드는 완성된 객체를 반환합니다.
선택적 구성 요소가 많은 객체를 생성할 때, 읽기 쉬운 생성 코드를 원할 때 또는 동일한 생성 프로세스로 서로 다른 표현을 만들어야 할 때 Builder를 사용하세요.
챌린지
쉬움사용자가 맞춤형 PC를 단계별로 구성할 수 있는 Computer Builder 시스템을 만들어 보겠습니다. 이는 Builder 패턴을 적용하기에 완벽한 시나리오입니다. computer에는 선택적 components가 많으며, 다양한 configuration을 깔끔하고 읽기 쉬운 방식으로 조립하고자 하기 때문입니다.
코드를 세 개의 파일로 구성합니다.
Computer.h: 완전히 구성된 computer를 나타내는 product class를 정의합니다.Computerclass는 다음 components를 private 멤버로 저장해야 합니다:cpu(string),ram(string),storage(string),gpu(string),hasWifi(boolean).hasWifi는false로 초기화하고, 문자열은 기본적으로 empty로 초기화합니다.computer의 configuration을 표시하는
showSpecs()라는 public 메서드를 추가합니다. 설정된 각 component(비어 있지 않은 문자열)는 한 줄에 하나씩 출력합니다. wifi 기능은 Enable된 경우에만 출력해야 합니다.ComputerBuilder.h: fluent interface를 사용하여 computer를 생성하는 builder class를 Create합니다.ComputerBuilderclass에는 build 대상인 privateComputer멤버가 있어야 합니다. 다음 메서드를 Implement하며, 각 메서드는 method chaining을 Enable하기 위해 builder에 대한 reference를 반환해야 합니다.setCPU(const std::string& cpu)setRAM(const std::string& ram)setStorage(const std::string& storage)setGPU(const std::string& gpu)addWifi(): wifi 기능을 enables
또한 완성된
Computerobject를 반환하고, builder를 potential reuse를 위해 reset하는build()메서드도 Implement합니다.main.cpp: 모든 요소를 함께 사용하여 맞춤형 computer를 build합니다.네 개의 inputs를 읽습니다.
- CPU model (string)
- RAM specification (string)
- Storage specification (string)
- wifi를 include할지 여부:
yes또는no
제공된 CPU, RAM, storage를 사용하여 computer를 구성하려면
ComputerBuilder를 사용합니다. wifi input이yes이면addWifi()도 call합니다. 이 configuration에는 GPU가 지정되지 않았다는 점에 유의하세요. builder는 선택적 components를 자연스럽게 처리해야 합니다.build한 후 결과 computer에서
showSpecs()를 call하여 configuration을 표시합니다.
showSpecs() 메서드는 다음 형식으로 output해야 합니다(설정된 components만 표시).
CPU: [value]
RAM: [value]
Storage: [value]
GPU: [value]
Wifi: Enabled예를 들어 inputs가 Intel i7-12700K, 32GB DDR5, 1TB NVMe SSD, yes인 경우:
CPU: Intel i7-12700K
RAM: 32GB DDR5
Storage: 1TB NVMe SSD
Wifi: Enabledinputs가 AMD Ryzen 5 5600X, 16GB DDR4, 512GB SSD, no인 경우:
CPU: AMD Ryzen 5 5600X
RAM: 16GB DDR4
Storage: 512GB SSDBuilder 패턴이 construction process를 얼마나 읽기 쉽고 유연하게 만드는지 확인해 보세요. components를 쉽게 추가하거나 건너뛸 수 있으며, method chaining을 통해 명확하고 self-documenting한 code가 만들어집니다. GPU를 한 번도 설정하지 않았기 때문에 GPU line은 나타나지 않습니다. 이는 builder가 optional components를 자연스럽게 처리하는 방식을 보여 줍니다.
직접 해보기
#include <iostream>
#include <string>
#include "ComputerBuilder.h"
using namespace std;
int main() {
// 입력 읽기
string cpu, ram, storage, wifiChoice;
getline(cin, cpu);
getline(cin, ram);
getline(cin, storage);
getline(cin, wifiChoice);
// TODO: ComputerBuilder 인스턴스 생성
// TODO: 메서드 체이닝을 사용하여 CPU, RAM, storage 설정
// TODO: wifiChoice가 "yes"이면 addWifi()도 호출
// TODO: build()를 호출하여 Computer 객체 가져오기
// TODO: 빌드된 컴퓨터에서 showSpecs()를 호출하여 구성 표시
return 0;
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
직접 연습해 보세요: 온라인 C++ 컴파일러