The Factory Pattern in JS ES6 - Lee-hyuna/33-js-concepts-kr GitHub Wiki
The Factory Pattern in JS ES6
λ²μ : https://medium.com/@SntsDev/the-factory-pattern-in-js-es6-78f0afad17e9
λλ ES6 (ES2015)μμ λͺ¨λ μλ‘μ΄ κ²λ€μ μ΅λν νμ©νλ €κ³ λ Έλ ₯νκ³ μμ΅λλ€. κ·Έλ¦¬κ³ Factoryκ° νμν κ³³μμ μλ‘μ΄ λΌμ΄λΈλ¬λ¦¬λ₯Ό μμ±νλ€. κ·Έλμ λλ λͺ¨λ μλ‘μ΄ κ²λ€μ μ΄λ»κ² νμ©ν μ μμλμ§ κΆκΈν΄νκ³ , λͺ¨λ ES5κ° ES6 μ ν¨κ» κ³μν΄μ μ μ©νκ³ μ ν¨λ€λλκ²μ μμ§ μμμ΅λλ€.
λλ μ‘°μ¬νκ³ κ΅¬κΈλ§ νλ€ μλνλ©΄ κ·Έκ³³μλ λ§€μ° λλν μ½λκ° μκΈ° λλ¬Έμ μ΄λ° μ’ λ₯μ μ§λ¬Έμνκ³ λλν λλ΅μνκΈ° λλ¬Έμ λλ€. κ²°κ³Όλ₯Ό μ»λ κ²μ μλΉν μ΄λ €μ κ³ , λ μμμ κ²°ν©ν κ²μ μ°Ύμ μ μμμ΅λλ€. ES6 + Factory-Pattern. μ΄μ©λ©΄ λꡬλ κ·Έκ²μ λν΄ κΈμ λ¨κΈ°μ§ μμκ±°λ λ λΆμΌ λͺ¨λ λ€λ₯Έ κΈ°μ μ΄λ ES5μ λν μΈκΈ° κ²μλ¬Όμ΄ μμ κ²°κ³Όμ λνλκ³ μ κ²μλ¬Όμ΄ μμ§ μμλ₯Ό μ¬λ¦¬μ§ λͺ»νκ³ μκΈ° λλ¬Έμ λ λΆμΌ λͺ¨λ μ체μ μΌλ‘ λ§μ μ°Έκ³ μλ£κ° μκΈ° λλ¬ΈμΌ μ μμ΅λλ€.
κ·Έλμ λλ νΌμμ λκ°λ₯Ό μκ°ν΄ λ΄μΌ λ§νλ€. κ·Έλ¬λ μ£Όμ λ‘ λ€μ΄κ°κΈ° μ μ, μ°λ¦¬λ "Factory ν¨ν΄"μ κ·Έ κ²μ΄ 무μμΈμ§μ λν 곡ν΅λ μ΄ν΄κ° νμν©λλ€. μ£Όμ λ₯Ό λ°κ²νλ [Rob Dodsonμ κ²μλ¬Ό] (https://robdodson.me/javascript-design-patterns-factory/)μ μ½λ κ²μ΄ μ’μ΅λλ€. κ·Έλ 3 κ°μ§ κ°λ ν©ν 리 ν¨ν΄μ λν΄ μ΄μΌκΈ°ν©λλ€.
- Simple Factory
- Factory Method
- Abstract Factory
" simple factoryλ λ€λ₯Έ κ°μ²΄μ μμ±μ μΊ‘μννλ κ°μ²΄μ λλ€." ES6μμ κ·Έκ²μ "new"μ μν΄ instathiatedλλ μμ±μκ° λ μ μμ΅λλ€.
//Definition of class
class User {
constructor(typeOfUser){
this._canEditEverything = false;
if (typeOfUser === "administrator") {
this._canEditEverything = true;
}
}
get canEditEverything() { return this._canEditEverything; }
}//Instatiation
let u1 = new User("normalGuy");
let u2 = new User("administrator");
λΉμ μ΄ λ³Ό μ μλ―μ΄ λ¨μν 곡μ₯μ λ§€μ° κ°λ¨ν©λλ€. νλμ ν΄λμ€μλ§ μ μ©λ©λλ€. λ§μ μν©μ μΆ©λΆν μ’μ΅λλ€.
"** Factory Method **λ νλμ λ©μλλ₯Ό μ μν©λλ€. μλ₯Ό λ€μ΄ createThing μ λ°ν ν νλͺ©μ κ²°μ νλ νμ ν΄λμ€μ μν΄ μ¬μ μλ©λλ€. Factoriesκ³Ό Productsμ ν΄λΌμ΄μΈνΈκ° κ·Έκ²λ€μ μ¬μ©νκΈ° μν μΈν°νμ΄μ€λ₯Ό λ°λ¦ λλ€."
μλ‘μ΄ λ©μλλ₯Ό λ§λλ λμ "new"λ₯Ό κ³μ μ¬μ©νλ©΄μ ES6μμ ν΄λμ€λ₯Ό νμ₯νμ¬ κ΅¬νν μ μμ΅λλ€.
//Class
class User {
constructor(){
this._canEditEverything = false;
}
get canEditEverything() { return this._canEditEverything; }
}//Sub-class
class Administrator extends User {
constructor() {
super();
this._canEditEverything = true;
}
}//Instatiation
let u2 = new Administrator();
u2.canEditEverything; //true
"** Abstract Factory** ν¨ν΄μ ꡬ체μ μΈ ν΄λμ€λ₯Ό μ§μ νμ§ μκ³ κ΄λ ¨ μ€λΈμ νΈ λλ μ’ μ μ€λΈμ νΈμ families μ μμ±νκΈ°μν μΈν°νμ΄μ€λ₯Ό μ 곡ν©λλ€."
μ¬κΈ°μ μ€μν μ μ "families"μ΄λΌλ λ¨μ΄μ λλ€. μ΄ μμ λ₯Ό κ³μ μ¬μ©νλ©΄ ES6μμ "μΈν°νμ΄μ€"(ν΄λμ€) λ° "ꡬ체μ μΈ ν΄λμ€"(νμ ν΄λμ€)λ‘ κ΅¬νν μ μμ΅λλ€. TypeScriptμμ (c #μμμ κ°μ΄) _interface_existsλ μ μμμ΄ (ꡬνμμ΄) ν΄λμ€κ° ꡬνν©λλ€. κ·Έλ¬λ JS (ES6 ν¬ν¨)μμλ κ·Έλ μ§ μμ΅λλ€. κ·Έλμ μ°λ¦¬λ κ·Έκ²μ νμ₯νλ ν΄λμ€μ νμ ν΄λμ€λ₯Ό μ¬μ©ν©λλ€. κ·Έλμ μ°λ¦¬λ μλΈ ν΄λμ€ "Administrator", "Editor", "Publisher"λ±μ κ°μ§ μ μμ΅λλ€.
Registering concrete objects at run-time
μ§κΈκΉμ§λ κ·Έλ κ² μ’μμ§ λ§, λλ λ μ μ©ν κ²μ νμλ‘νλ€. λ΄κ° νμν κ²μ:
- μ€ν μκ°μ μλΈ ν΄λμ€μ λ±λ‘μ νμ©νλ Factory. λ΄ κ²½μ°μλ μ½λκ° μλ‘μ΄ μ νμ μ¬μ©μ λ° μ±μ λ§λ€μ΄ μ¬μ©μ μΈν°νμ΄μ€μμ μ¬μ©ν μμκ²ν΄μΌνλ―λ‘ νμν©λλ€.
- μ΄μ μ λ±λ‘ λ λͺ¨λ μλ‘μ΄ μ μ νμ μ κ°μ§ μ¬μ©μ μ μ΄μ λͺ¨λ μΈμ€ν΄μ€μμ μ¬μ©ν μμλ ν©ν 리. μ΄κ²μ κ°λ¨ν©λλ€. Singletonμ΄λμ΄μΌν©λλ€.
κ·Έλμ ν΄λμ€μ μΈμ€ν΄μ€λ₯Ό λ±λ‘νκ³ μμ±νκΈ° μν΄ μ μ λ©μλκ°μλ ES6 ν΄λμ€λ₯Ό λ§λ€μμ΅λλ€. λ€μκ³Ό κ°μ΅λλ€.
class Factory {
constructor() {}
static register(clazzname, clazz) {
if ((!Factory._registeredTypes.has(clazzname) &&
clazz.prototype instanceof User)) {
Factory._registeredTypes.set(clazzname, clazz);
... }
else { ... }
}
static create(clazzname, ...options) {
if (!Factory._registeredTypes.has(clazzname)) {
console.error("!!!");
return null;
}
let clazz = this._registeredTypes.get(clazzname);
let instance = new clazz(...options);
return instance;
}
}
Factory._registeredTypes = new Map();
λ κ°μ§λ₯Όλ³΄μμμ€. (1) "μ μ "λ°©λ²μ μ¬μ©νκ³ (2) "Map"λ₯Ό νλ¨μ μμ±μ λ°μΈλ©ν©λλ€. ES6μμλ μ μ λ©μλ (μΈμ€ν΄μ€ν ν νμ μμ΄ μ¬μ©ν μ μμΌλ©° μΈμ€ν΄μ€μλ μ¬μ©ν μ μκ³ , μΈμ€ν΄μ€ this νλ‘νΌν°μ μ κ·Όν μ μμ)μ κ°μ§ μ μμ΅λλ€. λ°λΌμ (2)μμ κ·Έκ²λ€μ λ§λ€μ΄μΌν©λλ€.
μ΄ μμ μ μ μμ λλ€. κ·Έλ¦¬κ³ μ¬λ¬λΆ μ€ μΌλΆλ κ·Έκ²μ μμ°μ μΈ κ΅¬νμΌλ‘ μκ°ν κ²μ λλ€. κ·Έλ¬λ λλ κ·Έλ μ§ μμ΅λλ€. λλ κ·Έκ²μ΄ instatiated μμλ κ²μ²λΌ κ·Έκ²μ μ¬μ€μ μ’μνμ§ μμ. λλ μ μ λ©μλλ₯Ό μμ΄ λ²λ¦¬κ³ λΌμ΄λΈλ¬λ¦¬μμ μΈμ€ν΄μ€ννκ³ , λ Όλ¦¬λ₯Ό μΆκ°νμ¬ SingletonμΌλ‘ λ§λ€ μ μμ΅λλ€. λ€, κ·Έλ΄ μλ μμ΅λλ€.
μ€νμΌμ λ¬Έμ μΌ μλ μμ§λ§μ΄ κ²½μ°μλ ν΄λμ€ λ ν¨μμ λν κ°μ²΄λ₯Ό μ νΈν©λλ€. κ·Έλμ λ§μΉ¨λ΄ λλ λ¨μν κ°μ²΄λ₯Ό μ¬μ©νλ€.
const Factory = {
registeredTypes: new Map(),
register(clazzname, clazz) {
if (!(Factory.registeredTypes.has(clazzname) &&
clazz.prototype instanceof User)) {
Factory._registeredTypes.set(clazzname, clazz);
}
else { ... }
},
create(clazzname, ...options) {
if (!Factory.registeredTypes.has(clazzname)) {
console.error("!!!");
return null;
}
let clazz = this.registeredTypes.get(clazzName);
let instance = new clazz(...options);
return instance;
}
}
μ¦, μλ‘μ΄ ES6 λΌμ΄λΈλ¬λ¦¬μμ μ΄λ₯Ό ꡬννλ λ°©λ²μ μμ λ΄λ €κ³ 2 μΌμ΄ μ§λ νμ λλ κ½€ νμ€μ μΈ μ루μ μΌλ‘ λμμ΅λλ€!
μ΄μ μ¬λ‘λ₯Ό κΈ°κ³ μλ‘ μΌμ μμ΄λμ΄ λ ꡬνμ 곡μ νλλ‘ κΆμ ν©λλ€. λΉμ μ μ΄λ»κ² ν μ μμ΅λκΉ?
μ½κ³ μ견μ μ£Όμ μ κ°μ¬ν©λλ€!