1 분 소요


img1

Factory Method Pattern이란?

  • 팩토리 메서드 패턴에서는 객체를 생성하기 위한 인터페이스를 정의하고, 어떤 클래스의 인스턴스를 만들지는 서브 클래스에서 결정하게 하는 패턴이다.
  • 팩토리 메서드는 객체를 생성, 반환하는 메서드이다.
  • 팩토리 클래스는 하위 클래스에서 팩토리 메서드를 오버라이딩해서 객체를 반환하게 하여 상위 클래스와 하위 클래스가 분리되게 함으로써 결합을 느슨하게 한다.
  • DIP를 활용한다.



팩토리 패턴은 왜 나왔는가?

객체 지향 디자인 패턴의 기본 원칙 중 하나인 OCP를 생각해보자. OCP는 확장에는 열려있고, 수정에는 닫혀 있어야 한다는 의미이다.

코드를 수정하지 않고 모듈의 기능을 확장할 수 있다는 것인데, 이를 위해서는 수정이 일어날 부분과 그렇지 않은 부분을 분리하는 것이 바람직하다.

객체를 생성하는 부분은 변경될 가능성이 높기 때문에 따로 떼어내서 관리하는게 좋다. 이를 위해 팩토리 패턴이 등장했다.



장점

  • 코드를 리펙토링할 때 한 곳만 고치면 되서 유지 보수성이 증가된다.
  • 객체간의 결합도를 낮출 수 있다.
  • SRP를 따른다. 실행 코드에서 생성자 코드를 분리함으로써 코드를 더욱 간결하게 만든다.
  • OCP를 따른다. 기존 클라이언트의 코드를 바꾸지 않고도 새로운 타입으로 바꿀 수 있다.


단점

  • 패턴 구현을 위해 많은 서브 클래스가 도입되어야 하기 때문에 코드가 복잡해진다.



팩토리 패턴 구현 예시 (simple Factory pattern)

  1. interface 생성
public interface Animal {
    public void speak();
    //type은 String보다는 Enum으로 해주면 더 좋다.
    public String getType(); 
}


  1. 하위 클래스를 구분해 주는 클래스 생성 (Enum 이 더 좋음)
public class Type {
    public static final String DOG = 'dog';
    public static final String CAT = 'cat';
}


  1. interface를 상속 받아 구현할 하위 클래스
public class Cat implements Animal {
    @Override
    public void speak() {
        System.out.println("먀먀");
    }
    @Override
    public void getType() {
        return Type.CAT;
    }
}

public class Dog implements Animal {
    @Override
    public void speak() {
        System.out.println("멍멍");
    }
    @Override
    public void getType() {
        return Type.DOG;
    }
}


  1. 타입에 따라 객체를 생성해 줄 Factory 클래스 생성
@Component
public class AnimalFactory {
    public Animal getAnimal(String animalType) {
        if (animalType.equal(Type.CAT)){
            return new Cat();
        } else if (animalType.eqaul(Type.DOG)) {
            return new Dog();
        } else {
            return null;
        }
    }
}


  1. Factory 클래스를 사용하는 Client
@Service
public class Client {
    @Autowired
    private AnimalFactory factory;

    @Override
    public void use() {
        Aniaml dog = factory.getAnimal(Type.DOG);
        Aniaml cat = factory.getAnimal(Type.CAT);

        dog.speak();
        cat.speak();
    }
}