자식 클래스가 어떤 객체를 생성할지를 결정하도록 하는 패턴
예시
UML
product -> coffee
concreteProduct -> americano, mocha
#include<iostream>
#include<string>
using namespace std;
class Coffee{
public:
virtual string Operation() = 0;
};
class Americano : public Coffee{
public:
string Operation() {
return "Americano";
}
};
class Mocha : public Coffee{
public:
string Operation() {
return "Mocha";
}
};
class Creator {
public:
virtual Coffee* FactoryMethod() = 0;
string create() {
Coffee* product = this->FactoryMethod();
string result = product->Operation();
delete product;
cout << result << endl;
return result;
}
};
class AmericanoCreator : public Creator {
public:
Coffee* FactoryMethod() {
return new Americano();
}
};
int main() {
Creator* creator = new AmericanoCreator();
creator->create();
delete creator;
return 0;
}
복합 객체의 생성 과정과 표현 방법을 분리하여 동일한 생성 절차에서 서로 다른 표현 결과를 만들수 있다!
예시
UML
#include<iostream>
#include<vector>
using namespace std;
class Product {
vector<string> parts;
public:
void put(string s) { parts.push_back(s); }
void print() {
for (int i = 0; i < parts.size(); i++) {
if (parts[i] == parts.back())
cout << parts[i];
else
cout << parts[i] << ", ";
}
cout << endl;
}
};
class Builder {
public:
virtual void Espresso() = 0;
virtual void Water() = 0;
};
class Builder1 : public Builder {
private:
Product* product;
public:
Builder1() { product = new Product(); }
void Espresso() { product->put("Espresso"); }
void Water() { product->put("Water"); }
Product* GetProduct() {
Product* result = this->product;
this->product = new Product();
return result;
}
};
class Director {
private:
Builder* builder;
public:
void set_builder(Builder* builder) {
this->builder = builder;
}
void BuildEspresso() {
this->builder->Espresso();
}
void BuildAmericano() {
this->builder->Espresso();
this->builder->Water();
}
};
int main() {
Director* director = new Director();
Builder1* builder = new Builder1();
Product* coffee = NULL;
director->set_builder(builder);
cout << "Making Americano" << endl;
director->BuildAmericano();
coffee = builder->GetProduct();
coffee->print();
cout << endl;
cout << "Making Espresso" << endl;
director->BuildEspresso();
coffee = builder->GetProduct();
coffee->print();
return 0;
}
다양한 구성 요소 별로 객체의 집합을 생성해야 하는 경우 상황에 알맞는 객체 생성이 가능하다
예시
UML
#include<iostream>
#include<string>
using namespace std;
class AbstractProductA {
public:
string coffee;
virtual void make() = 0;
};
class CoffeeProduct1 : public AbstractProductA {
public:
void make() {
cout << "Americano created" << endl;
}
};
class CoffeeProduct2 : public AbstractProductA {
public:
void make() {
cout << "latte created" << endl;
}
};
class AbstractProductB {
public:
string food;
virtual void make() = 0;
};
class FoodProduct1 : public AbstractProductB {
public:
void make() {
cout << "Sandwich created" << endl;
}
};
class FoodProduct2 : public AbstractProductB {
public:
void make() {
cout << "macaron created" << endl;
}
};
class AbstractFactory {
public:
virtual AbstractProductA* CreateProductA() = 0;
virtual AbstractProductB* CreateProductB() = 0;
};
class ConcreteFactory1 : public AbstractFactory {
public:
AbstractProductA* CreateProductA() {
return new CoffeeProduct1();
}
AbstractProductB* CreateProductB() {
return new FoodProduct1();
}
};
class ConcreteFactory2 : public AbstractFactory {
public:
AbstractProductA* CreateProductA() {
return new CoffeeProduct2();
}
AbstractProductB* CreateProductB() {
return new FoodProduct2();
}
};
int main() {
ConcreteFactory1* f1 = new ConcreteFactory1();
AbstractProductA* product_a = NULL;
AbstractProductB* product_b = NULL;
product_a = f1-> CreateProductA();
product_b = f1-> CreateProductB();
product_a->make();
product_b->make();
ConcreteFactory2* f2 = new ConcreteFactory2();
product_a = f2-> CreateProductA();
product_b = f2-> CreateProductB();
product_a->make();
product_b->make();
return 0;
}
생성할 객체들의 타입이 프로토타입인 인스턴스로부터 결정되도록 하며, 인스턴스는 새 객체를 만들기 위해 자신을 복제하게 된다(복사 생성자)
예시
UML
#include<iostream>
#include<string>
using namespace std;
class Prototype {
protected:
string _size = "";
string _color = "";
public:
virtual Prototype* clone() = 0;
void print() { cout << _size << "\t" << _color << endl; }
};
class ConcretePrototype1 : public Prototype {
public:
ConcretePrototype1(string size, string color) {
_size = size;
_color = color;
}
Prototype* clone() {
return new ConcretePrototype1(*this);
}
};
class ConcretePrototype2 : public Prototype {
public:
ConcretePrototype2(string size) {
_size = size;
}
Prototype* clone() {
return new ConcretePrototype2(*this);
}
};
int main() {
Prototype* prototype1 = new ConcretePrototype1("tall", "black");
Prototype* copy1 = prototype1->clone();
prototype1->print();
copy1->print();
Prototype* prototype2 = new ConcretePrototype2("venti");
Prototype* copy2 = prototype2->clone();
prototype2->print();
copy2->print();
return 0;
}
클래스에 인스턴스가 하나만 있는지 확인하고 이에 대한 전역 접근을 제공합니다
예시
UML
#include<iostream>
#include<string>
using namespace std;
class Singleton {
public:
static Singleton* getInstance();
void print() {
cout << val << endl;
}
void inc() { val++; }
private:
static Singleton* _instance;
Singleton() { val = 3; }
int val;
};
Singleton* Singleton::_instance = 0;
Singleton* Singleton::getInstance() {
if (_instance == 0)
_instance = new Singleton;
return _instance;
}
int main() {
Singleton *s = Singleton :: getInstance();
s->print();
Singleton* y = Singleton::getInstance();
y->print();
y->inc();
s->print();
return 0;
}