JS/[inflearn] TS JS 디자인패턴

생성 패턴 (Creational Pattern) _ 팩토리 메서드(Factory Method)

web_seul 2025. 1. 16. 16:57

팩토리 메서드 : 클래스와 클라이언트 사이에 팩토리라는 중간자를 두고 독립된 요소로 분리

//AbstractGrimpanFactory.ts
import Grimpan from './AbstractGrimpan';

abstract class AbstractGrimpanFactory {
  abstract createGrimpan(): Grimpan;	//추상그림판을 가져와야함 (IEGrimpan x, ChromeGrimpan x)
  //createGrimpan을 무조건 상속해서 override해야함
  };
}
export default AbstractGrimpanFactory;

* Abstract : 일반 class가 abstract class를 상속받을 수 있음, abstract가 아닌 요소도 수용해서 abstract로 활용 가능

일반 class는 abstract class를 상속받을 수 있음, 대신 abstract의 메서드를 override해서 구현해야함

//AbstractGrimpan.ts
//abstract class 활용
export default abstract class Grimpan{
  //private가 아닌 protected는 상속한 클래스가 재정의 할 수 있음
  protected static instance: Grimpan;	
  protected constructor(canvas: HTMLElement | null){
    if(!canvas || !(canvas  instanceof HTMLCanvasElement)){
      throw new Error('canvas 엘리먼트를 입력하세요.')
    }
  }
  
  abstract initialize(): void
  abstract initializeMenu(): void
  
  static getInstance(){}
}

 

//IEGrimpan.ts
import Grimpan from './AbstractGrimpan.js';

class IEGrimpan extends Grimpan {	
  protected static override instance: IEGrimpan;
  //abstract class의 Grimpan을 상속받아서 override
  
  override initialize() {}
  override initializeMenu() {}
  
  static override getInstance() {
  if (!this.instance) {
      this.instance = new IEGrimpan(document.querySelector('canvas'))
    }
    return this.instance;
  }
}
export default IEGrimpan;
//ChromeGrimpan.ts
import Grimpan from './AbstractGrimpan.js';

class ChromeGrimpan extends Grimpan {	
  protected static override instance: ChromeGrimpan;
  //abstract class의 Grimpan을 상속받아서 override
  
  override initialize() {}
  override initializeMenu() {}
  
  static override getInstance() {
  if (!this.instance) {
      this.instance = new ChromeGrimpan(document.querySelector('canvas'))
    }
    return this.instance;
  }
}
export default ChromeGrimpan;

 

//Grimpan을 import해서
import AbstractGrimpanFactory from "./AbstractGrimpanFactory.js";

//활용
class ChromGrimpanFactory AbstractGrimpanFactory{
    override createGrimpan(){
        return ChromGrimpan.getInstance();
    }
}
class IEGrimpanFactory AbstractGrimpanFactory{
    override createGrimpan(){
        return IEGrimpan.getInstance();
    }
}
//추가시 확장 가능


//클라이언트
function main(){
    const grimpan = new ChromGrimpanFactory().createGrimpan();
    grimpan.initialize();
    grimpan.initializeMenu();
}

 

장점 단점
OCP, SRP 를 지킬 수 있다. 복잡하다
   

 

Interface로 활용하기 (비권장)

//AbstractGrimpan.ts
//interface 활용
export default abstract class Grimpan{  
  initialize(): void
  initializeMenu(): void
  
  static getInstance(){}
}
//ChromeGrimpan.ts
import Grimpan from './AbstractGrimpan.js';

class ChromeGrimpan implements Grimpan {	
  protected static override instance: ChromeGrimpan;
  
  //실제 구현 위치 이동해야해서 중복됨 (그래서 abstract class 권장함)
  private constructor(canvas: HTMLElement | null){
    if(!canvas || !(canvas instanceof HTMLCanvasElement)){{
      throw new Error('canvas 엘리먼트를 입력하세요.')
    }
  }
  
  initialize() {}
  initializeMenu() {}
  
  static getInstance() {
  if (!this.instance) {
      this.instance = new ChromeGrimpan(document.querySelector('canvas'))
    }
    return this.instance;
  }
}
export default ChromeGrimpan;
반응형