memostack
article thumbnail
블로그를 이전하였습니다. 2023년 11월부터 https://bluemiv.github.io/에서 블로그를 운영하려고 합니다. 앞으로 해당 블로그의 댓글은 읽지 못할 수 도 있으니 양해바랍니다.
반응형

Factory Method Pattern

팩토리 메소드 패턴은 '객체'와 '객체 생성 클래스'를 따로 분리하는 디자인 패턴이다.

  • 객체 생성 클래스가 따로 분리되어 있어서, 객체 생성 변화에 유연하게 대비할 수 있다.
팩토리 메소드 패턴을 이용하기 위해서는 Strategy Pattern과 Template Pattern의 개념을 아는 것이 좋다. (자주 사용됨)

 

예제

요구사항

  1. 게임 아이템을 만드는 아이템 생성자를 만든다.
    1. 아이템의 정보는 DB에 있다.
    2. 아이템 불법 생성을 막기 위해, 아이템 생성 로그를 남긴다.
  2. 아이템을 상속받아 여러개의 세부 아이템(물약, 검, 갑옷 등등)을 구현한다.

 

아이템 생성자

public abstract class ItemCreator {

    public Item create() {
        // Template Method Pattern을 이용

        // Step 1. DB에서 아이템 정보를 가져온다.
        final Map<String, String> itemInfo = getItemInfo();

        // Step 2. 아이템을 생성한다.
        final Item item = createItem(itemInfo);

        // Step 3. 아이템 생성 로그를 남긴다.
        log(itemInfo.get("name"));

        return item;
    }

    // DB에서 아이템 정보 조회
    protected abstract Map<String, String> getItemInfo();

    // 아이템을 생성하는 알고리즘
    protected abstract Item createItem(Map<String, String> itemInfo);

    // 로그
    private void log(String itemName) {
        System.out.println(new Date() + " - " + itemName + " - 아이템 생성됐습니다.");
    }
}

아이템 생성은 3가지 단계로 이루어짐

  1. DB 조회
  2. 아이템 생성
  3. 생성 로그 남김

HP 물약을 생성하는 객체 생성

public class HpPotionCreator extends ItemCreator {
    @Override
    protected Map<String, String> getItemInfo() {
        System.out.println("DB에서 아이템 정보를 가져온다.");

        final Map<String, String> itemInfo = new HashMap<>();
        itemInfo.put("name", "체력 회복약");
        itemInfo.put("category", "potion");
        // ...

        return itemInfo;
    }

    @Override
    protected Item createItem(Map<String, String> itemInfo) {
        System.out.println("HP 물약 생성.");
        return new HpPotion(itemInfo);
    }
}
  • DB에서 가져왔다고 가정. (위 예제에서는 하드코딩으로 정보를 입력하여 반환)

'검' 생성하는 객체 생성

public class SwordCreator extends ItemCreator {
    @Override
    protected Map<String, String> getItemInfo() {
        System.out.println("DB에서 아이템 정보를 가져온다.");

        final Map<String, String> itemInfo = new HashMap<>();
        itemInfo.put("name", "전설의 검");
        itemInfo.put("category", "weapon");
        // ...

        return itemInfo;
    }

    @Override
    protected Item createItem(Map<String, String> itemInfo) {
        System.out.println("검 생성.");
        return new Sword(itemInfo);
    }
}

 

아이템 생성

public interface Item {
    void use();
}

 

세부 아이템 구현

public class HpPotion implements Item {

    private String name;
    private String category;

    public HpPotion(Map<String, String> itemInfo) {
        this.name = itemInfo.get("name");
        this.category = itemInfo.get("category");
    }

    public String getName() {
        return name;
    }

    public String getCategory() {
        return category;
    }

    @Override
    public void use() {
        System.out.println("'" + getName() + "' 사용하여 체력 회복.");
    }
}
public class Sword implements Item {

    private String name;
    private String category;

    public Sword(Map<String, String> itemInfo) {
        this.name = itemInfo.get("name");
        this.category = itemInfo.get("category");
    }

    public String getName() {
        return name;
    }

    public String getCategory() {
        return category;
    }

    @Override
    public void use() {
        System.out.println("'" + getName() + "' 장착했습니다.");
    }
}
  • Item을 implements해서 각 아이템 속성에 맞게 구현

 

Main 함수 구현

public class Main {

    public static void main(String[] args) {
        final ItemCreator hpc = new HpPotionCreator();
        final HpPotion hpPotion = (HpPotion) hpc.create();
        hpPotion.use();

        final ItemCreator sc = new SwordCreator();
        final Sword sword = (Sword) sc.create();
        sword.use();
    }
}
DB에서 아이템 정보를 가져온다.
HP 물약 생성.
Sun Jun 07 22:45:40 KST 2020 - 체력 회복약 - 아이템 생성됐습니다.
'체력 회복약' 사용하여 체력 회복.
DB에서 아이템 정보를 가져온다.
검 생성.
Sun Jun 07 22:45:40 KST 2020 - 전설의 검 - 아이템 생성됐습니다.
'전설의 검' 장착했습니다.

 

클래스 다이어그램

클래스다이어그램

반응형
블로그를 이전하였습니다. 2023년 11월부터 https://bluemiv.github.io/에서 블로그를 운영하려고 합니다. 앞으로 해당 블로그의 댓글은 읽지 못할 수 도 있으니 양해바랍니다.
profile

memostack

@bluemiv_mm

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!