본문 바로가기
공부(~2016)/디자인패턴

Factory Method 패턴

by soy; 2014. 7. 7.

Factory Method 패턴

템플릿메소드패턴을 인스턴스 생성에 적용한 전형적인 예. 팩토리(인스턴스를 생성하는 공장)를 템플릿메소드 패턴으로 구성한 것이 팩토리메소드 패턴이다.

- 인스턴스를 만드는 방법을 상위클래스측에서 결정, 구체적인 이름까지는 결정하지 않음. 

- 구체적인 내용은 하위클래스측에서 구현함으로써 인스턴스 생성을 위한 골격과 실제 인스턴스 생성에 사용되는 클래스를 분리함.


구현 예시

package framework;
 
public abstract class Product {
    public abstract void use();
}

product(인스턴스)가 가져야 할 인터페이스(API)를 추상메소드 선언으로 규정하고, 구현은 하위클래스에게 위임함.

 

package framework;
 
public abstract class Factory {
    public final Product create(String owner) {
        Product p = createProduct(owner);
        registerProduct(p);
        return p;
    }
    protected abstract Product createProduct(String owner);
    protected abstract void registerProduct(Product product);
}

공장에서는 제품을 생성할 때 생성->등록->반환 순으로 처리된다는 골격을 규정하고 생성과 등록의 구현은 하위클래스에게 하도록 위임한다.

상위클래스는 createProduct를 호출하면 Product 인스턴스가 생성되어 반환된다는 정보만 알 뿐 createProduct 메소드의 세부 구현 내용은 몰라도 됨.

-> new를 사용하여 Product 인스턴스를 생성하지 않고, 인스턴스 생성을 위한 메소드를 호출함으로서 구체적인 클래스 이름에 의한 속박에서 상위 클래스를 자유롭게 만듬.


createProduct 메소드의 구현 방법 세 가지

package idcard;
import framework.*;
 
public class IDCard extends Product {
    private String owner;
    IDCard(String owner) {
        System.out.println(owner + "의 카드를 만듭니다.");
        this.owner = owner;
    }
    public void use() {
        System.out.println(owner + "의 카드를 사용ㄱ합니다.");
    }
    public String getOwner() {
        return owner;
    }
}

제품


package idcard;
import framework.*;
import java.util.*;
 
public class IDCardFactory extends Factory {
    private List owners = new ArrayList();
    protected Product createProduct(String owner) {
        return new IDCard(owner);
    }
    protected void registerProduct(Product product) {
        owners.add(((IDCard)product).getOwner());
    }
    public List getOwners() {
        return owners;
    }
}

하위클래스는 상위클래스의 추상메소드들을 그 목적에 맞게 구현함.

제품을 사용-use, 제품을 등록-registerProduct, 제품을 생성하여 반환-createProduct한다는 본래의 목적에 맞도록 구현하되, 사용 / 생성 / 등록을 어떤 방법으로 할지 등은 완전히 하위클래스가 결정하게 됨.


import framework.*;
import idcard.*;
 
public class Main {
    public static void main(String[] args) {
        Factory factory = new IDCardFactory();
        Product card1 = factory.create("홍길동");
        Product card2 = factory.create("이순신");
        Product card3 = factory.create("강감찬");
        card1.use();
        card2.use();
        card3.use();
    }
}

- framework 패키지(Factory, Product)는 idcard 패키지(IDCardFactory, IDCard)에 의존하지 않음. (idcard 패키지에 대한 정보를 전혀 가지고 있지 않음)

- framework 패키지를 상속받아 구현하기만 하면, 다른 어떤 product들도 같은 방법으로 사용될 수 있음. (이 때 framework 패키지의 내용을 수정할 필요가 없음)



댓글