추상 팩토리, Kit 이라고도 불린다.
ex. IKEA 의자를 산 손님은 추가 주문 시 IKEA 소파를 사고 싶어 한다.
명시적으로 각자 상품군의 인터페이스를 선언한다. 그러면 다양한 종류의 상품을 만들어낼 수 있다.
그 다음은 생성 메소드들(createChair
, createSofa
, createCoffeeTable
)을 가진 상품 회사 Abstract Factory
를 선언하는 것이다. 이 함수들은 반드시 이전에 우리가 추출했던 인터페이스에 의해 표현된 추상 상품 타입들을 반환해야 한다. (createChar(): Chair
, createSofa(): Sofa
)
이제 각 상품 회사의 상품들의 factory class를 AbstractFactory
인터페이스를 기반으로 만들어낼 수 있다. 하나의 팩토리는 특정 종류의 상품을 리턴하는 클래스이다. 예를 들어서 IKEAFactory는 IKeaChair를 만들 수 있다.
AbstractFactory
: 개념적 제품에 대한 객체를 생성하는 연산, 인터페이스를 정의함ConcreteFactory
: 구체적인 제품에 대한 객체를 생성하는 연산을 구현함AbstractProduct
: 개념적 제품 객체에 대한 인터페이스를 정의함ConcreteProduct
: 구체적으로 팩토리가 생성할 객체를 정의한다. AbstractProduct
가 정의하는 인터페이스를 구현한다.Client
: AbstractFactory
와 AbstractProduct
클래스에 선언된 인터페이스를 사용한다.ConcreteFactory
클래스의 인스턴스 한 개가 런타임에 만들어진다. 이 구체 팩토리는 어떤 특정 구현을 갖는 제품 객체를 생성한다. 서로 다른 제품 객체를 생성하려면 사용자는 서로 다른 구체 팩토리를 사용해야 한다.AbstractFactory
는 필요한 제품 객체를 생성하는 책임을 ConcreteFactory
서브 클래스에 위임한다.interface AbstractFactory {
createChair(): AbstractChair;
createSofa(): AbstractSofa;
}
interface AbstractSofa {
sitOn(): string;
rest(): string;
legOn(collaborator: AbstractChair): string;
}
interface AbstractChair {
sitOn(): string;
putLeg(): string;
}
class IkeaFactory implements AbstractFactory {
public createChair(): AbstractChair {
return new ConcreteIkeaChair();
}
public createSofa(): AbstractSofa {
return new ConcreteIkeaSofa();
}
}
class EMartFactory implements AbstractFactory {
public createChair(): AbstractChair {
return new ConcreteEmartChair();
}
public createSofa(): AbstractSofa {
return new ConcreteEmartSofa();
}
}
class ConcreteIkeaChair implements AbstractChair {
sitOn(): string {
return `sit on Ikea chair`;
}
putLeg(): string {
return `put your leg on Ikea chair`;
}
}
class ConcreteIkeaSofa implements AbstractSofa {
sitOn(): string {
return "sit on Ikea sofa";
}
rest(): string {
return "rest on Ikea sofa";
}
legOn(collaborator: AbstractChair): string {
return `with Ikea Sofa, leg on chair: ${collaborator.putLeg()}`;
}
}
class ConcreteEmartChair implements AbstractChair {
sitOn(): string {
return `sit on Emart chair`;
}
putLeg(): string {
return `put your leg on Emart chair`;
}
}
class ConcreteEmartSofa implements AbstractSofa {
sitOn(): string {
return "sit on Emart sofa";
}
rest(): string {
return "rest on Emart sofa";
}
legOn(collaborator: AbstractChair): string {
return `with Emart Sofa, leg on chair: ${collaborator.putLeg()}`;
}
}
const clientCode = (factory: AbstractFactory) => {
const chair = factory.createChair();
const sofa = factory.createSofa();
console.log(sofa.rest());
console.log(sofa.legOn(chair));
};
clientCode(new IkeaFactory());
clientCode(new EMartFactory());
rest on Ikea sofa
with Ikea Sofa, leg on chair: put your leg on Ikea chair
rest on Emart sofa
with Emart Sofa, leg on chair: put your leg on Emart chair