Factory Method Pattern
팩토리 메소드 패턴에 대해서 알아보겠습니다.
Factory Method Pattern 이란?
인터페이스를 어떻게 구현할지에 대한 결정 없이, 새로운 인스턴스를 생성할 수 있게 하는 방법입니다.
쉽게 말해 factory class 에서 생성할 클래스의 정보를 구분할 수 있는 타입이나 문자열등의 인자를 받아서, 스위치나 조건문 등등으로 분기해 클래스를 생성하여 반환합니다. 그래서 객체를 생성할때 해당 클래스의 내부를 몰라도 클래스 생성이 가능합니다.
또한 메인에서 직접적으로 객체를 생성하거나 하지 않고, 서브 클래스에 위임하여 생성하기 때문에 보다 안전하고, 관련된 객체를 한곳에서 관리하기 때문에 확장성있는 코드 관리가 가능합니다.
예시
책 자바스크립트 디자인 패턴 - Factory Method Pattern 편의 예제를 각색 하고 코드를 수정했습니다.
1. 신에게 기도를 할 수 있습니다.
2. 신의 종류에는 watery (물의 신), ancient (고대 신) 등이 있습니다.
3. 원하는 신이 없을 때는 defaultGod (기본신)에게 기도를 할 수 있습니다.
먼저 기본이 되는 God Class 입니다.
abstract class God {
public abstract pray();
}
신에게는 꼭 기도를 해야합니다. 그래서 abstract class 로 정의 하였습니다.
그리고 여러종류의 신이 있습니다. 물을 다스리는 WateryGod, 뭐하는지 모르는 고대신 AncientGod,
마지막으로 원하는 신이 없지만 기도는 드리고 싶을때 선택 가능한 기본 신 DefaultGod이 있습니다.
class WateryGod extends God {
public pray() {
console.log('홍수가 나지 않게 해주세요.')
}
}
class AncientGod extends God {
public pray() {
console.log('나라가 망하지 않게 해주세요.')
}
}
class DefaultGod extends God {
public pray() {
console.log('건강하게 살도록 해주세요.')
}
}
이러한 신들을 모두 모아놓고, 간편하게 객체를 만들고 싶습니다.
하지만 괜히 내가 const jaceyWateryGod = new WateryGod() 처럼 직접 생성하고 싶지도 않습니다. 깔끔하고 안전하게 할 수 있는 방법이 없을까요?
그럴때 Factory Method Pattern을 사용하면 됩니다.
class GodFactory {
public Build(godName?: string) {
if (godName === 'watery') return new WateryGod();
if (godName === 'ancient') return new AncientGod();
return new DefaultGod();
}
}
신의 이름 (godName)만 넣으면 해당 신을 알아서 연결해줍니다. 그리고 능력을 다스리는 신이 많아진다면 이 팩토리에 계속 정의해서 사용하면 되겠죠? 이렇게 객체의 생성을 위임할 수 있습니다. 이 예제에서는 string 값으로 분기처리를 했지만 특정 타입을 넘겨서 처리하는게 더 나아보입니다.
그러면 신에게 기도를 해봅시다.
const god = new GodFactory();
god.Build('watery').pray(); // 홍수가 나지 않게 해주세요.
god.Build().pray(); // 건강하게 살도록 해주세요.
물의 신에게 기도를 하고 싶으면 watery string을 인자로 넘겨서 물의 신에게 기도를 드릴 수 있습니다.
원하는 신이 없다면 인자를 넘기지 않는 것으로 기본 신에게 기도를 드릴 수 있게 됩니다.
관련 객체들을 한곳에 모아두고 생성을 위임하는게 아주 간결해보입니다.
하지만 뭐든지 적당한게 좋은 법. 팩토리에 생성 가능한 객체들이 너무 많이 쌓이지 않도록 유의하며, 너무 많이 쌓인다면 그것을 해소할 수 있는 다른 방법을 찾는게 좋아 보입니다.