본문 바로가기

생성 디자인 패턴 - 추상 팩토리 본문

OOP 디자인 패턴/생성패턴

생성 디자인 패턴 - 추상 팩토리

개발자로 거듭나기 2023. 4. 30. 23:20
반응형

추상 팩토리 패턴 (Abstract Factory)

  • 추상 팩토리는 관련 객체들의 구상 클래스들을 지정하지 않고도 관련 객체들의 모음을 생성할 수 있도록 하는 생성패턴입니다다.

추상 팩토리 구성요소

  1. 추상 공장 인터페이스 : 공장에서 생산할 수 있는 제품들을 정의합니다.
  2. 추상 제품 인터페이스 : 제품들이 가져야할 메서드를 정의합니다.
  3. 구체적인 공장 클래스 : Korean 제품을 생산하는 공장, USA 제품을 생산하는 공장등 각 제품들의 하나의 variant(변형)을 생산하는 공장클래스 입니다.
  4. 구체적인 제품 클래스 : 제품 인터페이스를 상속받아서 메서드를 구현합니다. 의자면 sitOn(앉을 수 있다) 등.
  5. 클라이언트 코드 : 구체적인 공장을 하나 인수로 받아 제품들을 생성하고, 비즈니스 로직을 수행합니다.

요약

  • 추상팩토리 메서드는 객체의 생성을 담당하는 추상팩토리 클래스와 단일 제품클래스를 분리합니다.
  • 추상팩토리 클래스는 한가지의 변형을 담당하는 공장이고, 같은 추상팩토리에서 생성된 제품들은 같은 변형을 공유합니다. 예를들어 한국식, 미국식 이렇게요.
  • 클라이언트는 어떤 한국식이던 미국식이던 의자는 sitOn 메서드를 가진다는것만 인지하고 있습니다.
  • 새로운 변형의 UI 요소를 앱에 추가할 때마다 클라이언트 코드를 수정할 필요가 없어집니다. 이 요소들을 생성하는 새로운 팩토리 클래스를 만든 후 앱의 초기화 코드를 그 팩토리 클래스를 선택하도록 약간 수정하기만 하면 됩니다.
  • 따라서 또 다른 변형을 가진 제품을 생산한다면 추상팩토리를 상속하는 또다른 공장을 추가해서 제품을 생성하게 하면 됩니다.
반응형

코드

/**
 * 추상팩토리는 다른 제품의 같은 (단일) 변형, 테마, 개념을 생산합니다, 이를 family라고 부릅니다.
 * 예를들면 이 추상공장은 의자와 책상을 생산할 수 있습니다.
 * 이 추상공장 인터페이스를 상속하는 ConcreteFactory1은 다른 제품들 (의자, 책상)을 만들겠지만
 * '한국식 스타일'을 만듭니다. === family
 */
interface AbstractFactory {
  createChair(): Chair;

  createDesk(): Desk;
}

/**
* 구체적인 공장은 구체적인 variant 만 취급하는 제품들만 만듭니다.
* 예를들면 한국식, 미국식 이렇게요
*/
class KoreanFactory implements AbstractFactory {
  public createChair(): Chair {
    return new KoreanChair();
  }

  public createDesk(): Desk {
    return new KoreanDesk();
  }
}

class USAFactory implements AbstractFactory {
  public createChair(): Chair {
    return new USAChair();
  }

  public createDesk(): Desk {
    return new USADesk();
  }
}

/**
* 의자 제품이 가져야할 소양을 정의합니다. 의자끼리 family가 달라도 이 메서드 만큼은 갖고있습니다.
*/
interface Chair {
  sitOn(): string;
}

/**
* 이 구체 제품은 팩토리에 의해 만들어집니다.
*/
class KoreanChair implements Chair {
  public sitOn(): string {
    return 'Sit on Korean chair';
  }
}

class USAChair implements Chair {
  public sitOn(): string {
    return 'Sit on USA chair';
  }
}

interface Desk {
  study(): string;

  // 의자 제품과 상호작용 할 수 있는 메서드입니다.
  collaboWithChair(collaborator: Chair): string;
}

class KoreanDesk implements Desk {

  public study(): string {
    return 'I"m in study with KoreanDesk';
  }

  public collaboWithChair(collaborator: Chair): string {
    const result = collaborator.sitOn();
    return `${result} and Study in Korean desk`;
  }
}

class USADesk implements Desk {
  public study(): string {
    return 'I"m in study with USADesk';
  }

  public collaboWithChair(collaborator: Chair): string {
    const result = collaborator.sitOn();
    return `${result} and Study in USA desk`;
  }
}

// 클라이언트 코드에서는 특정 공장 하나를 받아서 제품을 만듭니다.
// 여기서 미국공장은 미국제품만, 한국공장은 한국제품만 생산하겠죠?
// desk.collaboWithChair 메서드를 이용해서 같은 한국제품끼리 상호작용할 수 있습니다.
function clientCode(factory: AbstractFactory) {
  const chair = factory.createChair(); // 의자
  const desk = factory.createDesk(); // 책상

  console.log(desk.study());
  console.log(desk.collaboWithChair(chair));
}

console.log('Client: 한국식 제품들을 만들어볼까요?');
clientCode(new KoreanFactory());

console.log('');

console.log('Client: 미국식 제품들을 만들어볼까요?');
clientCode(new USAFactory());

결과


출처

https://refactoring.guru/ko/design-patterns/abstract-factory

 

반응형
Comments