목적
Factory Method는 생성 패턴 중 하나로서, object를 만들어 내는 interface를 상위 클래스에서 제공하고, 하위 클래스에서 만들어지는 object의 타입을 바꿀 때 사용함
- 슈퍼클래스 코드에서는 서브클래스에서 구현할 메소드를 호출해서 필요한 타입의 오브젝트를 가져와 사용함. 주로 인터페이스 타입으로 오브젝트를 리턴하므로 서브클래스에서 정확히 어떤 클래스의 오브젝트를 만들어 리턴할지 슈퍼클래스에서 알지 못하고 관심도 없음.
OCP(개방 폐쇄 원칙) - 수정에는 닫혀 있고 확장에는 열려 있다. 라는 원칙이 딱 적용되는 패턴 인듯함
상황
- 배송을 관리하는 어플리케이션을 만드는 데 처음에는 운송을 트럭으로만 해서
Truck
class 안에 많은 로직들이 들어 있음
- 그 후, 배를 통해서 운송을 관리해 달라는 요청이 들어옴
- 그러나 지금 상황은 모든 코드가
Truck
클래스와 매우 깊게 연관이 되어 있기 때문에Ship
클래스를 추가 하기 위해서는 전체 코드를 다 엎어야 함 ;;
- 그 후, 또 새로운 운송 수단을 추가하기 위해서는 이러한 뒤엎음을 또 한번 더 감행해야 함
해결법
- Factory Method는 간단하게 말해서 new로 만들 클래스(
Truck
)를 Factory method(special factory method) 안으로 넣어서 활용하는 기법 ⇒ 하위 클래스에서 method override를 통해 다른 product를 반환할 수 있음
- 아래 그림에서 createTransport() 이것이 Factory method임
- 이렇게 만듦으로 해서, 새로운 운송 수단이 추가 될 때마다,
Transport
를 구현하는 새로운 운송 수단과, 해당 운송 수단을 관리하는*Logistics
를 추가해서 기존의 코드를 수정하지 않고 확장을 가능케 해줌


코드
Logistics
public abstract class Logistics { public void planDelivery(){ Transport t = createTransport(); t.deliver(); } abstract Transport createTransport(); }
extends Logistics
public class RoadLogistics extends Logistics{ @Override Transport createTransport() { return new Truck(); } } public class SeaLogistics extends Logistics{ @Override Transport createTransport() { return new Ship(); } }
클라이언트 코드
public static void main(String[] args) { doDeliveryBy(LogisticType.Road); doDeliveryBy(LogisticType.Sea); } private static void doDeliveryBy(LogisticType logisticType){ if (logisticType == LogisticType.Road){ new RoadLogistics().planDelivery(); } else new SeaLogistics().planDelivery(); }