** 팩토리 패턴이란? **
🌟 정의
객체를 생성할 때 그 객체의 생성자를 직접 호출하지 않고, 객체 생성을 담담하는 팩토리에 요청하는 구조를 뜻한다.
🌟 장점
1. 객체를 생성하는 코드가 프로그램의 이곳저곳에 산만하게 흩어지지 않고 객체를 생성하는 기능을 한 곳에 모아둘 수 있다.
2. 클래스 타입을 정확히 몰라도 클래스 계층에 맞게 객체를 생성할 수 있다.
3. 팩토리는 클래스 계층에 따라 실행할 수 있다.
4. 객체를 정확한 순서로 생성하려면 복잡한 단계가 필요하거나, 생성된 객체를 항상 다른 객체와 일정한 방식으로 연결해야 할 때 팩토리를 사용하면 편하다.
** 팩토리 종류 **
🌟 정적 팩터리 메서드 (static factory method)
객체를 생성해서 리턴하는 함수.
class Point
{
// use a factory method
Point(float x, float y) : x(x), y(y){}
public:
float x, y;
friend class PointFactory;
};
class PointFactory
{
static Point NewCartesian(float x, float y)
{
return Point{ x,y };
}
static Point NewPolar(float r, float theta)
{
return Point{ r*cos(theta), r*sin(theta) };
}
};
🔸 여기서 잠깐 !! 🔸
* 팩토리 함수에 static을 사용하는 이유는 뭘까 ?
객체를 생성하지 않고 static 메서드에 접근이 가능하기 때문이다. static을 사용하면 클래스가 메모리에 올라갈때 이미 자동적으로 생성되기 때문에 인스턴스들이 공통적으로 값을 유지해야할 때 사용한다. 인스턴스가 필요없기 때문에 메서드 호출이 짧아지기 때문에 효율이 올라가는 장점이 있다.
* 메서드란?
어떤 클래스의 멤버함수를 의미한다.
🌟 팩터리
객체를 생성하는 함수들을 별도의 클래스에 몰아넣은 클래스를 팩터리라고 한다.
🌟 내부 팩터리
생성할 타입의 내부 클래스로서 존재하는 간단한 팩터리를 말한다. friend 키워드에 해당하는 문법이 없는 프로그래밍 언어들에서는 내부 팩터리를 흔하게 사용하며, 팩터리가 생성해야 할 클래스가 단 한 종일 때 유용하다.
생성할 타입의 내부 클래스이기 때문에 private멤버들에 자동적으로 자유로운 접근 권한을 가진다는 점이 있다. 내부 클래스를 보유한 외부 클래스도 내부 클래스의 private 멤버들에 접근할 수 있다.
🌟 추상 팩터리
여러 종류의 연관 객체들을 생성해야 할 경우사용한다.
class CarFactory
{
public:
virtual ~CarFactory() = default; //항상 가상 소멸자로 정의한다.
std::unique_ptr<Car> requestCar();
size_t getNumberOfCarsProduced() const;
protected:
virtual std::unique_ptr<Car> createCar() = 0;
private:
size_t mNumberOfCarsProduced = 0;
};
class FordFactory : public CarFactory
{
protected:
virtual std::unique_ptr<Car> createCar() override;
};
class ToyotaFactory : public CarFactory
{
protected:
virtual std::unique_ptr<Car> createCar() override;
};
//---------------------------------------------------------------------//
std::unique_ptr<Car> CarFactory::requestCar()
{
++mNumberOfCarsProduced;
return createCar();
}
size_t CarFactory::getNumberOfCarsProduced() const
{
return mNumberOfCarsProduced;
}
std::unique_ptr<Car> FordFactory::createCar()
{
return std::make_unique<Ford>();
}
std::unique_ptr<Car> ToyotaFactory::createCar()
{
return std::make_unique<Toyota>();
}
//---------------------------------------------------------------------//
class LeastBusyFactory : public CarFactory
{
public:
explicit LeastBusyFactory(vector<unique_ptr<CarFactory>>&& factories);
// explicit 자신이 설정한 방식으로만 객체를 만드려고 할때.
// 여러 공장을 갖는 LeastBusyFactory 인스턴스를 생성한다.
protected:
virtual unique_ptr<Car> createCar() override;
private:
vector<unique_ptr<CarFactory>> mFactories;
};
LeastBusyFactory::LeastBusyFactory(vector<unique_ptr<CarFactory>>&& factories)
: mFactories(std::move(factories))
{
if (mFactories.empty())
throw runtime_error("No factories provided.");
}
unique_ptr<Car> LeastBusyFactory::createCar()
{
CarFactory* bestSoFar = mFactories[0].get();
for (auto& factory : mFactories) {
if (factory->getNumberOfCarsProduced() <
bestSoFar->getNumberOfCarsProduced()) {
bestSoFar = factory.get();
}
}
return bestSoFar->requestCar();
}
🌟 함수형 팩터리
클래스 대신 함수의 형태로 존재하는 팩터리
class DrinkWithVolumeFactory
{
map<string, function<unique_ptr<HotDrink>()>> factories;
public:
DrinkWithVolumeFactory()
{
factories["tea"] = [] {
auto tea = make_unique<Tea>();
tea->prepare(200);
return tea;
};
factories["Coffee"] = [] {
auto coffee = make_unique<Coffee>();
coffee->prepare(10);
return Coffee;
};
}
unique_ptr<HotDrink> make_drink(const string& name);
};
inline unique_ptr<HotDrink> DrinkWithVolumeFactory::make_drink(const string& name)
{
return factories[name]();
}

** 출처 **
1. 모던 c++ 디자인 패턴 / 드미트리 네스터룩 지음 / 출판사 : 깃벗
2. 전문가를 위한 c++ (개정 4판) : C++17 / 마크 그레고리 지음 / 출판사 : 한빛 미디어
'👨🏻💻 programming > ◽ 디자인 패턴' 카테고리의 다른 글
[디자인 패턴] 생성 패턴 - 2. 싱글턴 (singleton) (4) | 2023.08.23 |
---|
안 하는 것 보다 낫겠지
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!