a.k.a 가상 생성자
공장에서 상품을 생산하듯이 팩토리 메소드로 비슷한 형태의 (공통의 성질을 가진) 객체들을 찍어낸다
객체를 생성할 때 어떤 클래스의 인스턴스를 만들 지 서브클래스에서 결정함
부모 클래스: 인터페이스
자식 클래스: 인터페이스를 바탕으로 클래스를 구현하여 객체의 유형을 변경할 수 있음
자바스크립트에서는 인터페이스라는 개념이 존재하지 않지만 알아두면 나쁠 건 없다!
인터페이스는 클래스의 틀이다.
클래스가 어떤 속성을 갖고 어떤 메소드를 구현해야 하는지 지정은 해주지만 직접 구현은 하지 못한다.
예시)
Interface Transport {
type: String,
route: String,
deliver: Function
}
(작동하는 코드 아님)
Transport라는 인터페이스를 만들어서 type, route가 String 타입으로 존재해야 하고, deliver라는 메소드가 구현되어야 한다.
class Ship extends Transport {
type: "ship",
route: "ocean",
deliver: function () {
console.log("I am " + transportation + " and deliver by " + route);
}
}
Ship이라는 클래스는 Transport 인터페이스를 구현한다.
이 때 필수로 있어야 하는 transportation, route, deliver를 각각 정의한다.
가정)
1. 물류 관리 앱의 첫 번째 버전: 트럭 운송만 처리 (Truck 클래스 생성 / 구현)
class Truck {
constructor(type) {
this.type: type,
this.route: "land",
this.deliver: function () {
console.log(`${this.type}: delivers by ${this.route}.`)
}
}
}
class Ship {
constructor(type) {
this.type: type,
this.route: "ocean",
this.deliver: function () {
console.log(`${this.type}: delivers by ${this.route}.`)
}
}
}
생성자 함수의 직접 호출을 팩토리 메소드에 대한 호출로 대체.
* 제품: 팩토리 메소드에서 반환된 객체
// 1
class Factory {
constructor() {
// 2
this.createTransport = function (type) {
let transport;
// 2-1
if (type === "truck") {
transport = new Truck();
} else if (type === "ship") {
transport = new Ship();
} else if (type === "plane") {
transport = new Plane();
}
// 2-2
transport.type = type;
// 2-3
transport.deliver = function () {
console.log(`${transport.type}: delivers by ${transport.route}.`);
}
return transport;
}
}
}
// 3
class Truck {
constructor() {
this.route = "land";
}
}
// 3
class Ship {
constructor() {
this.route = "ocean";
}
}
// 3
class Plane {
constructor() {
this.route = "sky";
}
}
let transports = [];
const factory = new Factory();
transports.push(factory.createTransport("truck"));
transports.push(factory.createTransport("ship"));
transports.push(factory.createTransport("plane"));
for (var i = 0, len = transports.length; i < len; i++) {
transports[i].deliver();
}
공장에서 truck, ship, plane 운송수단을 찍어내서 transports라는 배열에 담는다.
배열의 각 요소에는 객체가 들어있을 것이고 deliver를 호출하면 객체마다 다른 출력을 한다.
truck: delivers by land.
ship: delivers by ocean.
plane: delivers by sky.
팩토리 메소드의 핵심 목표는 확장성이다.
공통적인 성질을 가진 객체들을 다룰 때 주로 사용한다.
클라이언트는 원하는 객체를 받되 공장에 어떤 객체들이 또 있는지 알게 하면 안된다.
객체의 생성(인스턴스화)는 클라이언트에게 위임하되 인스턴스화할 유형에 대한 제어는 공장이 유지한다.
제품(클래스)가 많아질수록 코드가 길어지고 복잡해진다.
가장 좋은 방법은 크리에이터 클래스(공장)의 기존 계층구조에 패턴을 도입하는 것이다.