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 패키지의 내용을 수정할 필요가 없음)
댓글