[디자인패턴] 팩토리 패턴
Factory Method Pattern이란?
팩토리 메서드 패턴
에서는 객체를 생성하기 위한 인터페이스를 정의하고, 어떤 클래스의 인스턴스를 만들지는 서브 클래스에서 결정하게 하는 패턴이다.- 팩토리 메서드는 객체를 생성, 반환하는 메서드이다.
- 팩토리 클래스는 하위 클래스에서 팩토리 메서드를 오버라이딩해서 객체를 반환하게 하여 상위 클래스와 하위 클래스가 분리되게 함으로써 결합을 느슨하게 한다.
- DIP를 활용한다.
팩토리 패턴은 왜 나왔는가?
객체 지향 디자인 패턴의 기본 원칙 중 하나인 OCP를 생각해보자. OCP는 확장에는 열려있고, 수정에는 닫혀 있어야 한다는 의미이다.
코드를 수정하지 않고 모듈의 기능을 확장할 수 있다는 것인데, 이를 위해서는 수정이 일어날 부분과 그렇지 않은 부분을 분리하는 것이 바람직하다.
객체를 생성하는 부분은 변경될 가능성이 높기 때문에 따로 떼어내서 관리하는게 좋다. 이를 위해 팩토리 패턴이 등장했다.
장점
- 코드를 리펙토링할 때 한 곳만 고치면 되서 유지 보수성이 증가된다.
- 객체간의 결합도를 낮출 수 있다.
SRP
를 따른다. 실행 코드에서 생성자 코드를 분리함으로써 코드를 더욱 간결하게 만든다.OCP
를 따른다. 기존 클라이언트의 코드를 바꾸지 않고도 새로운 타입으로 바꿀 수 있다.
단점
- 패턴 구현을 위해 많은 서브 클래스가 도입되어야 하기 때문에 코드가 복잡해진다.
팩토리 패턴 구현 예시 (simple Factory pattern)
- interface 생성
public interface Animal {
public void speak();
//type은 String보다는 Enum으로 해주면 더 좋다.
public String getType();
}
- 하위 클래스를 구분해 주는 클래스 생성 (Enum 이 더 좋음)
public class Type {
public static final String DOG = 'dog';
public static final String CAT = 'cat';
}
- 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;
}
}
- 타입에 따라 객체를 생성해 줄 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;
}
}
}
- 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();
}
}