구체적 클래스를 정의하지 않고도 서로 관련성이 있거나
독립적인 여러 객체의 군을 생성하기 위한 인터페이스 제공
정의: 추상적인 부품을 조립해서 추상적인 제품을 만드는 추상적인 공장 같은 패턴
: 클라이언트에서 구상 클래스를 지정하지 않으면서도 일군의 객체를 생성할 수 있도록 하는 패턴
활용:
1. 생성되고 구성되고 표현되는 방식과 무관하게 시스템을 독립적으로 만들고자 할 때
2. 하나 이상의 제품군들 중 하나를 선택해서 시스템을 설정해야 하고 한번 구성한 제품을
다른 것으로 대체 가능할 때
3. 관련된 객체군을 함께 사용해서 시스템을 설계하고,
이 제품이 갖는 제약사항을 따라야 할 때
4. 제품에 대한 클래스 라이브러리를 제공하고,
그들의 구현이 아닌 인터페이스를 표현하고 싶을 때
결과:
1.구체적인 클래스를 분리한다
추성클래스가 정의한 인터페이스를 통해서만 클라이언트 프로그램을 작성한다
2. 제품군을 쉽게 대체할 수 있도록 한다
3. 제품간의 일관성을 증진한다
4. 새로운 종류의 제품을 제공하기 어렵다 –
새로운 제품에 대해 추상 팩토리를 확장하는 것이 어렵다
단점: 클래스 계층이 커질 수 있다
예제코드
#include
#include
#include
#include
class AbstractProdcutA
{
public:
AbstractProdcutA () {}
virtual ~AbstractProdcutA() {}
};
class AbstractProdcutB
{
public:
AbstractProdcutB () {}
virtual ~AbstractProdcutB() {}
};
class AbstractFactory
{
public:
virtual AbstractProdcutA* CreateProductA (void) = 0;
virtual AbstractProdcutB* CreateProductB (void) = 0;
};
class ProdcutA1 : public AbstractProdcutA
{
public:
ProdcutA1()
{
std::cout << "ProdcutA1()" << std::endl;
}
};
class ProdcutA2 : public AbstractProdcutA
{
public:
ProdcutA2()
{
std::cout << "ProdcutA2()" << std::endl;
}
};
class ProdcutB1 : public AbstractProdcutB
{
public:
ProdcutB1()
{
std::cout << "ProdcutB1()" << std::endl;
}
};
class ProdcutB2 : public AbstractProdcutB
{
public:
ProdcutB2()
{
std::cout << "ProdcutB2()" << std::endl;
}
};
class ConcreteFactory1 : public AbstractFactory
{
public:
virtual AbstractProdcutA* CreateProductA (void)
{
return new ProdcutA1();
}
virtual AbstractProdcutB* CreateProductB (void)
{
return new ProdcutB1();
}
};
class ConcreteFactory2 : public AbstractFactory
{
virtual AbstractProdcutA* CreateProductA (void)
{
return new ProdcutA2();
}
virtual AbstractProdcutB* CreateProductB (void)
{
return new ProdcutB2();
}
};
class Client
{
public:
void Create (AbstractFactory *f)
{
ProdcutA_.reset( f->CreateProductA() );
ProdcutB_.reset( f->CreateProductB() );
}
private:
std::auto_ptr ProdcutA_;
std::auto_ptr ProdcutB_;
};
int _tmain(int argc, _TCHAR* argv[])
{
Client client;
std::cout << "by ConcreteFactory1" << std::endl;
client.Create ( &ConcreteFactory1() );
std::cout << std::endl;
std::cout << "by ConcreteFactory2" << std::endl;
client.Create ( &ConcreteFactory2() );
return 0;
}