1. 팩토리 메서드 패턴이란?
- 객체 생성을 위한 패턴
- 객체 생성에 필요한 과정을 템플릿처럼 정해 놓고 각 과정을 다양하게 구현이 가능
- 객체 생성에 대한 인터페이스와 구현의 분리
- 구체적으로 생성할 클래스를 유연하게 정할 수 있음
팩토리 메서드 패턴은 객체 생성을 Factory 클래스로 캡슐화하여 대신 생성하게 하는 '생성' 디자인 패턴이다.
클라이언트가 직접 new 연산자를 통해 객체를 생성하는 것이 아닌 객체 생성을 도맡는 Factory 클래스를 만들고, 이를 상속하는 서브 Factory 클래스에서 여러 타입의 객체 생성을 책임지는 것이다.
또한 Factory에서 객체 생성시의 전처리 혹은 후처리를 통해 생성 과정을 유연하게 처리 할 수 있다.
위키피디아에 나와 있는 UML 다이어그램으로는 팩토리 메서드 패턴이 어떤 디자인 패턴인지에 대한 감이 오지 않는다.
좀더 직관적인 클래스 다이어그램과 그 구현을 살펴보자.
2. 팩토리 메서드 패턴 구현
Factory는 추상클래스로써, 객체 생성 절차를 명시한다.
ItemFactory는 추상클래스의 구현클래스로써, 추상메서드를 실질적으로 구현하는 역할을 한다.
Sword, Shield, Bow는 Item 인터페이스의 구현 클래스이다.
ItemFactory는 Item 인터페이스의 구현 클래스 객체를 생성하는 역할을 하게 된다.
위 클래스 다이어그램은 필요한 시점에 Sword, Shield, Bow객체를 만들며, 제한 갯수가 존재하는 제약조건이 있다.
public interface Item {
void use();
}
public class Sword implements Item {
@Override
public void use() {
System.out.println("칼로 베었다.");
}
}
public class Bow implements Item {
@Override
public void use() {
System.out.println("활을 쐇다.");
}
}
public class Shield implements Item {
@Override
public void use() {
System.out.println("방패로 막았다.");
}
}
객체 생성 기능을 정의한 Factory 추상 클래스
public abstract class Factory {
// 생성하고자 하는 Item을 문자열로 받고, 생성 가능 여부를 판단한다
// 생성이 가능할 겨우 CreateItem() 메서드로 객체를 생성한다.
public Item create(String name) {
boolean bCreatable = this.isCreatable(name);
if(bCreatable) {
Item item = this.createItem(name);
postProcessItem(name);
return item;
}
return null;
}
public abstract boolean isCreatable(String name);
public abstract Item createItem(String name);
public abstract boolean postProcessItem(String name);
}
Factory 추상 클래스를 구현한 ItemFactory
public class ItemFactory extends Factory{
private class ItemData {
int maxCount;
int currentCount;
ItemData(int maxCount) {
this.maxCount = maxCount;
}
}
private HashMap<String, ItemData> repository;
public ItemFactory() {
repository = new HashMap<String, ItemData>();
repository.put("sword", new ItemData(3));
repository.put("shield", new ItemData(2));
repository.put("bow", new ItemData(1));
}
@Override
public boolean isCreatable(String name) {
ItemData itemData = repository.get(name);
if(itemData == null) {
System.out.println(name + "은 알 수 없는 아이템입니다.");
return false;
}
if(itemData.currentCount >= itemData.maxCount) {
System.out.println(name + "은 품절 아이템입니다.");
return false;
}
return true;
}
@Override
public Item createItem(String name) {
Item item = null;
if("sword".equals(name)) item = new Sword();
if("shield".equals(name)) item = new Shield();
if("bow".equals(name)) item = new Bow();
return item;
}
@Override
public void postProcessItem(String name) {
ItemData itemData = repository.get(name);
if(itemData != null) itemData.currentCount++;
}
}
위 코드의 내용을 살펴보자.
Item 인터페이스를 Sword, Shield, Bow 클래스가 각각 구현하고 있으며 해당 클래스들은 Factory 클래스에 의해 생성될 '제품' 객체이다.
Factory 클래스에서는 create() 메서드를 통해 객체 생성 과정을 명시(생성 가능 여부 판단, 객체 생성후 갯수 카운트 증가)하고 있으며 이에 필요한 기능은 추상 메서드로 정해 두었다.
ItemFactory 클래스는 Factory 추상 클래스의 구현 클래스로써, Factory 추상 클래스에 명시된 추상 메서드의 기능을 구현하는 역할을 한다.
Factory factory = new ItemFactory();
형태로 생성된 Factory 객체는 Factory 클래스의 create() 메서드에 정의된 객체 생성 순서와, ItemFactory 클래스에 구현된 기능에 따라 객체가 생성된다.
위 코드는 Factory 추상 클래스를 구현한 다른 서브클래스를 통해 더욱 다양한 객체의 생성이 가능하도록 확장 할 수 있다.
ex. BreadFactory, MilkFactory
'Software Engineering' 카테고리의 다른 글
[디자인 패턴] 빌더(Builder) 패턴 (0) | 2024.04.15 |
---|---|
[디자인패턴] 어댑터(Adapter) 패턴 (0) | 2024.04.12 |
[디자인패턴] 전략(Strategy) 패턴 (0) | 2024.04.10 |