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

생성 패턴 (Creational Pattern) _ 추상 팩토리(Abstract Factory)

web_seul 2025. 1. 17. 18:59

추상 팩토리 : 여러 객체가 묶인 세트의 생성에 대한 패턴, 추가되어도 기존것들을 수정하지 않음

//메뉴 세트
//기본 메뉴를 override해서 해당 브라우저 메뉴 생성
//기존 코드를 수정하지 않음! : OCP 지킴
//GrimpanMenu.ts
import Grimpan from "./AbstractGrimpan.js";
import IEGrimpan from "./IEGrimpan.js";
import ChromeGrimpan from "./ChromeGrimpan.js";

export abstract class GrimpanMenu {
  grimpan: Grimpan;
  protected constructor(grimpan: Grimpan) {
    this.grimpan = grimpan;
  }

  abstract initialize(): void

  static getInstance() {}
}

//IE
export class IEGrimpanMenu extends GrimpanMenu{
  private static instance: IEGrimpanMenu;
  
  //abstract class에 override
  override initailize(): void {}
  
  //싱글턴
  static override getInstance(grimpan: IEGrimpan): IEGrimpanMenu{
    if(!this.instance){
      this.instance = new IEGrimpanMenu(grimpan)
    }
    return this.instance;
  }
}

//Chrome
export class ChromeGrimpanMenu extends GrimpanMenu{
  private static instance: IEGrimpanMenu;
  override initailize(): void {}
  
  static override getInstance(grimpan: ChromeGrimpanMenu): IEGrimpanMenu{
    if(!this.instance){
      this.instance = new ChromeGrimpanMenu(grimpan)
    }
    return this.instance;
  }
}

 

 

//브라우저별 그림판 공장에서 해당 그림판, 메뉴, history를 호출하여 하나의 객체를 만듦
//GrimpanFactory.ts
import ChromeGrimpan from './ChromeGrimpan.js';
import IEGrimpan from './IEGrimpan.js';
import { ChromeGrimpanMenu, IEGrimpanMenu } from './GrimpanMenu.js'
import { ChromeGrimpanHistory, IEGrimpanHistory } from './GrimpanHistory.js'
import Grimpan from './AbstractGrimpan.js';

//abstract factory method
//두개 이상의 객체 생성
export abstract class AbstractGrimpanFactory {
  static createGrimpan() {
    throw new Error('하위 클래스에서 구현하셔야 합니다.');
  };
  static createGrimpanMenu(grimpan: Grimpan) {
    throw new Error('하위 클래스에서 구현하셔야 합니다.');
  };
  static createGrimpanHistory(grimpan: Grimpan) {
    throw new Error('하위 클래스에서 구현하셔야 합니다.');
  };
}

export class ChromeGrimpanFactory extends AbstractGrimpanFactory {
  static override createGrimpan() {
    return ChromeGrimpan.getInstance()
  }
  static override createGrimpanMenu(grimpan: ChromeGrimpan) {
    return ChromeGrimpanMenu.getInstance(grimpan)
  }
  static override createGrimpanHistory(grimpan: ChromeGrimpan) {
    return ChromeGrimpanHistory.getInstance(grimpan)
  }
}

export class IEGrimpanFactory extends AbstractGrimpanFactory {
  static override createGrimpan() {
    return IEGrimpan.getInstance()
  }
  static override createGrimpanMenu(grimpan: IEGrimpan) {
    return IEGrimpanMenu.getInstance(grimpan)
  }
  static override createGrimpanHistory(grimpan: ChromeGrimpan) {
    return IEGrimpanHistory.getInstance(grimpan)
  }
}
//기본 history를 override해서 해당 브라우저 history 생성
//GrimpanHistory.ts
import Grimpan from "./AbstractGrimpan.js";
import IEGrimpan from "./IEGrimpan.js";
import ChromeGrimpan from "./ChromeGrimpan.js";

export abstract class GrimpanHistory {
  grimpan: Grimpan;
  protected constructor(grimpan: Grimpan) {
    this.grimpan = grimpan;
  }

  abstract initialize(): void

  static getInstance(grimpan: Grimpan) {}
}

export class IEGrimpanHistory extends GrimpanHistory {
  private static instance: IEGrimpanHistory;
  override initialize(): void {
    
  }
  static override getInstance(grimpan: IEGrimpan): IEGrimpanHistory {
    if (!this.instance) {
      this.instance = new IEGrimpanHistory(grimpan)
    }
    return this.instance;
  }
}

export class ChromeGrimpanHistory extends GrimpanHistory {
  private static instance: ChromeGrimpanHistory;
  override initialize(): void {
    
  }
  static override getInstance(grimpan: ChromeGrimpan): ChromeGrimpanHistory {
    if (!this.instance) {
      this.instance = new ChromeGrimpanHistory(grimpan)
    }
    return this.instance;
  }
}

 

 

//index.ts
import { ChromeGrimpanFactory } from './GrimpanFactory.js';

function main() {
  const factory = ChromeGrimpanFactory;
  const grimpan = factory.createGrimpan();
  const grimpanMenu = factory.createGrimpanMenu(grimpan);
  const grimpanHistory = factory.createGrimpanHistory(grimpan);
  grimpan.initialize();
  grimpanMenu.initialize();
  grimpanHistory.initialize();
}

main();
반응형