본문 바로가기
IT 개인 공부/디자인패턴

팩토리 메서드 패턴(Factory Method Pattern)

by Libi 2021. 7. 26.
반응형

팩토리 메서드 패턴은 생성(Creational) 패턴 중 하나로써 상위 클래스에게 알려지지 않은 구체 클래스를 생성하는 패턴이며, 하위 클래스가 어떤 객체를 생성할지를 결정하도록 하는 패턴이다.

간단하게 얘기하면 상위 클래스에서 객체를 직접 생성하지 않고, 팩토리(공장)라는 하위 클래스에게 위임하여 객체를 생성하도록 하는 디자인 패턴이다.

팩토리는 결국 비슷한 기능을 수행하는 객체를 만들어내기 때문에 템플릿 메서드 패턴을 활용할 수 있다.

팩토리 메서드 패턴의 구조는 다음과 같다.

  • Product : 팩토리 메서드로 생성할 객체의 공통 인터페이스
  • ConcreteProduct : 생성할 객체를 구현하는 클래스
  • Creator : 팩토리 메서드를 정의하는 추상 클래스
  • ConcreteCreator : 팩토리 메서드의 기능을 구현하는 클래스, ConcreteProduct 객체를 생성

간단한 예시를 통해 팩토리 메서드 패턴을 이해해 보자.

Truck과 Van 두 종류의 자동차(객체)를 생산하는 자동차 공장이 있다고 하자. 팩토리 메서드 패턴을 적용시켜 코드로 구현해보자.

먼저 Product 부분이다. 자신이 누군지를 나타내는 메서드를 가지는 interface Car를 구현한다.

package framework;

public interface Car {
	void whoAmI();
}

다음으로 Creator 부분이다. Product인 자동차를 생산하는 방법인 CreatorCar 추상 클래스를 구현하고 팩토리 메서드를 정의해준다. 자동차를 생성하는 과정은 비슷하기 때문에 우리는 이전에 배운 템플릿 메서드 패턴을 활용할 수 있다.

package framework;

public abstract class CreatorCar {

	//FactoryMethod -> Template Method Pattern 활용한 것을 볼 수 있음
	public Car createCar() {
		readyTemplate();
		assembleParts();
		return complete();
	}
	
    //operation1
	abstract protected void readyTemplate();

    //operation2
	private void assembleParts() { System.out.println("2. 부품 조립"); }
	
    //operation3
	abstract protected Car complete();
}

 

다음으로 ConcreteProduct 부분이다. 자동차 종류인 Truck과 Van 객체를 구현해준다.

package concrete;

import framework.Car;

public class Truck implements Car {
	@Override
	public void whoAmI() {
		System.out.println("I'm Truck!");
	}
}

public class Van implements Car {
	@Override
	public void whoAmI() {
		System.out.println("I'm Van!");
	}
}

 

다음으로 ConcreteCreator 부분이다. Truck과 Van를 생성하는 팩토리 메서드를 재정의해준다.

package concrete;

import framework.Car;
import framework.CreatorCar;

public class TruckCreator extends CreatorCar {

	@Override
	protected void readyTemplate() {
		System.out.println("1. Truck 틀을 준비");
	}

	@Override
	protected Car complete() {
		System.out.println("3. Truck 완성!");
		return new Truck();
	}
}

public class VanCreator extends CreatorCar {

	@Override
	protected void readyTemplate() {
		System.out.println("1. Van 틀을 준비");
	}
	
	@Override
	protected Car complete() {
		System.out.println("3. Van 완성!");
		return new Van();
	}
}

 

마지막으로 자동차 객체를 생성해줄 Factory 클래스를 구현해준다.

package concrete;

import framework.Car;

public class Factory {
	public Car createCar(Car car) {
		if (car instanceof Truck) {
			return new TruckCreator().createCar();
		} else if (car instanceof Van) {
			return new VanCreator().createCar();
		}
		return null;
	}
}

 

Main 클래스에서 이를 실행한 결과는 다음과 같다.

import concrete.Factory;
import concrete.Truck;
import concrete.Van;
import framework.Car;

public class Main {

	public static void main(String[] args) {
		Factory factory = new Factory();
		Car car = factory.createCar(new Truck());
		car.whoAmI();
		System.out.println("-----------------");
		car = factory.createCar(new Van());
		car.whoAmI();
	}
}

 

팩토리 메서드 패턴을 적용시켜 Main 클래스에서 자동차 객체를 직접 생성하지 않고 factory 클래스를 통해 객체를 생성하도록 하였다.

이렇게 구현한다면 객체 간의 결합도가 낮아지고 유지 보수가 용이해지는 장점이 있다.

 

반응형

댓글