구체적인 클래스를 지정하지 않고, 관련성을 갖는 객체들의 집합을 생성하거나 서로 독립적인 객체들의 집합을 생성할 수 있는 인터페이스를 제공하는 패턴이다.
구현 예제는 Web App 을 구성하는 객체를 만드는 과정을 Abstract Factory 패턴을 이용하여 구현하였습니다.
예제의 구조는 다음와 같습니다.
💡 **AbstractFactory**: WebAppFactory **ConcreteFactory**: WebApp_version_1, WebApp_version_2 **AbstractProduct**: FrontEnd, BackEnd **ConcreteProduct**: FrontEndStructure, BackEndStructure ... **Client**: createWebApp// AbstractFactory
// 팩토리 인터페이스로, 만들고자 하는 객체를 생성하는 연산을 정의한다.
interface WebAppFactory {
createFrontEnd() : FrontEnd;
createBackEnd() : BackEnd;
}
// ConcreteFactory
// AbstractFactory 인터페이스를 구현하는 클래스로, 구체적인 요소가 들어간다.
class WebApp_version_1 implements webAppFactory {
public createFrontEnd(): FrontEnd {
return new FrontEndStructure();
}
public createBackEnd(): BackEnd {
return new BackEndStructure();
}
}
// AbstractProduct
// AbstractFactory 에서 만들고자 했던 객체에 대한 인터페이스를 정의한다.
interface FrontEnd {
setFrameWork(): string;
}
interface BackEnd {
setDataBase(): string;
}
// ConcreteProduct
// 팩토리에서 생성할 실제 객체를 정의하고, AbstractProduct의 인터페이스를 정의한다.
class FrontEndStructure implements FrontEnd {
public setFrameWork(frameWork: string): string {
return `사용 할 프레임워크는 ${frameWork} 입니다`;
}
}
class BackEndStructure implements BackEnd {
public setDataBase(dataBase: string): string {
return `사용 할 데이터베이스는 ${dataBase} 입니다`;
}
}
// Client
// 생성된 객체를 인터페이스만 이용하여 사용한다.
const createWebApp = (factory: WebAppFactory, frameWork: string, db: string) => {
const frontEnd = factory.createFrontEnd();
const backEnd = factory.createBackEnd();
console.log(frontEnd.setFramework(frameWork));
console.log(backEnd.setDataBase(db));
}
// Client 호출
createWebApp(new WebApp_version_1(), 'React', 'Redis');
// 결과
// '사용 할 프레임워크는 React 입니다'
// '사용 할 데이터베이스는 Redis 입니다'
// ================================================================
// 새로운 객체를 만들 땐, ConcreteFactory와 ConcreteProduct를 추가 한다.
// ConcreteFactory
class WebApp_version_2 implements WebAppFactory {
public createFrontEnd(): FrontEnd {
return new OtherFrontEndStructure();
}
public createBackEnd(): BackEnd {
return new OtherBackEndStructure();
}
}
// ConcreteProduct
class OtherFrontEndStructure implements FrontEnd {
public setFrameWork(frameWork: string): string {
return `변경 할 프레임워크는 ${frameWork} 입니다`;
}
}
class OtherBackEndStructure implements BackEnd {
public setDataBase(dataBase: string): string {
return `변경 할 데이터베이스는 ${dataBase} 입니다`;
}
}
// Client 호출
createWebApp(new WebApp_version_2(), 'Angular', 'MySQL');
// 결과
// '변경 할 프레임워크는 Angular 입니다'
// '변경 할 데이터베이스는 MySQL 입니다'