개요

 FactoryMethod 패턴의 핵심은 인스턴스의 생성 방식과 실제 인스턴스 생성 과정을 분리하는 것이다. 상위 클래스는 인스턴스를 생성하는 방법(일종의 인터페이스)를 정의하지만 구체적인 내용은 하위 클래스에서 정의한다. 인스턴스를 생성하는 기본적인 틀을 Framework라 보면 되고, 실제 인스턴스 생성을 개발자가 작성하는 클래스로 보면 된다.

 이미 스프링을 사용해 본 사람이라면 자연스럽게 FactoryMethod를 경험하게 되는데 바로 BeanFactory 방식이다.

 상위 클래스와 하위 클래스의 구현은 이전에 포스팅한 Template Method 패턴을 따르게 된다.

 

역할

Product 열할

 상위 클래스로 Framework에 포함된다. 인스턴스의 기본 틀이라고 보면 된다. 예제에서는 Product 클래스.

 

Creator 역할

 상위 클래스로 Framework에 포함된다. 인스턴스를 생성하는 틀이라고 보면 된다. 예제에서는 Factory클래스.

 

ConcreteProduct 역할

 Product클래스를 상속하는 실제 인스턴스 클래스이다. Product 클래스가 정의한 기본 틀을 따르며 실제 인스턴스에 대한 내용을 정의한다. 예제에서는 IDCard 클래스.

 

ConcreteCreator 역할

 Creator클래스를 상속하며 실제 인스턴스가 생성되는 내용을 포함한다. 예제에서는 IDCardFactory 클래스.

 

이득 및 유의사항

Framework가 되는 Product와 Creator는 동일하고, 이를 이용한 ConcreteProduct와 ConcreteCreator는 새로운 클래스를 만든다고 생각하면 사용자는 Framework에서 정의해놓은 틀만으로도 새로운 클래스의 인스턴스를 생성해서 사용할 수 있는 것이다. 또한 개발자 간에도 동일한 Framework를 따르고 있다면 다른 개발자의 코드를 얼마나 접하든 Framework를 이해하고 있는 것만으로도 기본적인 틀을 이해할 수 있기 때문에 협업과 유지보수 비용을 줄일 수 있다.

 

예제 코드

//Product
package factoryMethod.framework;

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


//Creator
package factoryMethod.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);
}


//ConcreteProduct
package factoryMethod.idcard;

import factoryMethod.framework.Product;

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;
	}

}


//ConcreteCreator
package factoryMethod.idcard;

import java.util.ArrayList;
import java.util.List;

import factoryMethod.framework.Factory;
import factoryMethod.framework.Product;

public class IDCardFactory extends Factory{

	private List<String> owners = new ArrayList<>();
	
	protected Product createProduct(String owner) {
		return new IDCard(owner);
	}
	
	protected void registerProduct(Product product) {
		owners.add(((IDCard)product).getOwner());
	}
	
	public List<String> getOwners() {
		return owners;
	}
}


//Tester
package factoryMethod;

import factoryMethod.framework.Factory;
import factoryMethod.framework.Product;
import factoryMethod.idcard.IDCardFactory;

public class Main {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Factory factory = new IDCardFactory();
		Product card1 = factory.create("홍길동");
		Product card2 = factory.create("이순신");
		Product card3 = factory.create("강감찬");
		
		card1.use();
		card2.use();
		card3.use();
		
		
	}

}

'디자인 패턴' 카테고리의 다른 글

6. Prototype 패턴  (0) 2020.12.03
5. Singleton 패턴  (0) 2020.12.02
3. Template Method 패턴  (0) 2020.11.30
2. Adapter 패턴  (0) 2020.11.29
1. Iterator 패턴  (0) 2020.11.28

+ Recent posts