[Pattern] Factory Method

팩토리 메서드 패턴이란?

팩토리 매서드 패턴은 객체를 생성하는 공장을 만드는 것으로서 어떤 객체를 만드는 지는 자식 클래스에서 결정하게 하는 디자인 패턴이다.

  • 객체를 생성하기 위해 인터페이스를 정의하지만, 어떤 클래스의 인스턴스를 생성할지에 대한 결정은 서브 클래스가 내리도록 하는 패턴
  • 하위 클래스에서 팩토리 매서드를 override해서 객체를 반환하게 하는 패턴이다.

왜 사용하는가?

  • 어떤 클래스가 자신이 생성해야 하는 객체의 클래스를 예측할 수 없을 때
  • 생성할 객체를 기술하는 책임을 자신의 서브클래스가 지정했으면 할 때
  • 객체 생성의 책임을 몇 개의 보조 서브클래스 가운데 하나에게 위임하고, 어떤 서브클래스가 위임자인지에 대한 정보를 국소화 시키고 싶을 때

팩토리 메서드 구조

Product

  • 팩토리 매서드가 생성하는 객체의 인터페이스를 정의한다.

ConcreteProduct

  • Product 클래스에 정의된 인터페이스를 실제로 구현하는 클래스

Creator

  • Product 타입의 객체를 반환하는 팩토리 매서드를 선언하는 클래스
  • 팩토리 매서드를 기본적으로 구현, ConcreteProduct 객체를 반환한다.
  • Product 객체의 생성을 위해 팩토리 매서드를 호출한다.

ConcreteCreator

  • 팩토리 메서드를 재정의하여 ConcreteProduct의 인스턴스를 반환

구현시 고려할 점

팩토리 매서드 패턴의 구현 방법은 크게 두가지가 있다

  • Creator를 추상 클래스로 정의하고, 팩토리 매서드는 abstract로 선언하는 방법
  • Creator를 구체 클래스이고, 팩토리 메서드의 기본 구현을 제공하는 방법

팩토리 매서드의 인자를 통해 다양한 Product를 생성하게 된다.

  • 팩토리 매서드에 잘못된 인자가 들어올 경우의 런타임 에러 처리에 대해 고민할 것
  • Enum 등을 사용하는 것도 고려할 필요가 있다.

장점과 단점

장점

  • 객체 생성에 관련한 코드와 동작 코드를 분리할 수 있다.

예시

궁수전사
시작 힘/민첩100/100100/100
레벨업 시 증가하는 힘/민첩10/3030/10
  • 궁수와 전사 캐릭터가 있습니다.
  • 레벨업시 두 직업간의 차이가 계속 생길 것을 대비하여, 다른 클래스를 통해 두 개의 클래스를 생성합니다.
    • 이러한 과정에서 신규캐릭터를 인스턴스화 하는 경우, 팩토리 패턴을 사용하여 이를 구성하겠습니다.

GOF설명our class
Creator추사클래스이며 구체클래스의 부모클래스로,
Product 타입을 반환하는 팩토리매서드 (abstract method)를 가지고 있습니다.
CharacterCreator
ConcreteCreator팩토리 매서드를 재정의하여 구체 클래스(ConcreteProduct)를 리턴합니다.WarriorCreator
ArcherCreator
Product팩토리 매서드가 리턴하는 클래스의 추상클래스입니다.Character
ConcreteProductProduct 클래스에 정의된 매서드가 구현된 구체 클래스입니다.Warrior
Archer

코드

Character.java

package Velog;

public abstract class Character {

    protected int STR;
    protected int DEX;

    public abstract void levelUp();

    public int getSTR() {
        return STR;
    }

    public void setSTR(int STR) {
        this.STR = STR;
    }

    public int getDEX() {
        return DEX;
    }

    public void setDEX(int DEX) {
        this.DEX = DEX;
    }
}

Archer.java

package Velog;

public class Archer extends Character {
    @Override
    public void levelUp() {
        this.STR += 10;
        this.DEX += 30;
    }
}

Warrior.java

package Velog;

public class Warrior extends Character {

    @Override
    public void levelUp() {
        this.STR += 30;
        this.DEX += 10;
    }
}

CharacterCreator.java

package Velog;

public abstract class CharacterCreator {

    public Character CharacterCreator() {
        final Character character = character();

        character.setDEX(100);
        character.setSTR(100);

        return character;
    }


    protected abstract Character character();
}

ArcherCreator.java

package Velog;

public class ArcherCreator extends CharacterCreator{
    @Override
    protected Character character() {
        return new Archer();
    }
}

warriorCreator.java

package Velog;

public class WarriorCreator extends CharacterCreator{
    @Override
    protected Character character() {
        return new Warrior();
    }
}

좋은 웹페이지 즐겨찾기