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 일이 μ§€λ‚œ 후에 λ‚˜λŠ” κ½€ ν‘œμ€€μ μΈ μ†”λ£¨μ…˜μœΌλ‘œ λ‚˜μ™”μŠ΅λ‹ˆλ‹€!

이전 사둀λ₯Ό 기고자둜 μ‚Όμ•„ 아이디어 λ‚˜ κ΅¬ν˜„μ„ κ³΅μœ ν•˜λ„λ‘ κΆŒμœ ν•©λ‹ˆλ‹€. 당신은 μ–΄λ–»κ²Œ ν•  수 μžˆμŠ΅λ‹ˆκΉŒ?

읽고 μ˜κ²¬μ„ μ£Όμ…”μ„œ κ°μ‚¬ν•©λ‹ˆλ‹€!