[목차]
1. Factory Method Pattern - 팩토리 메소드 패턴이란?
2. Factory Method Pattern은 왜 사용하는 것일까?
3. 구현하기 전에 알아보자!
4. 팩토리 메소드 구현방법(예제 활용)
5. 결론
| Factory Method Pattern - 팩토리 메소드 패턴이란?
The factory method pattern is a creational pattern that uses factory methods to deal with the problem of
creating objects without having to specify the exact class of the object that will be created. This is done by creating objects by calling a factory method—either specified in an interface and implemented by child classes, or implemented in a base class and optionally overridden by derived classes—rather than by calling a constructor. - Wikipedia
팩토리 메서드 패턴은 Factory method는 부모(상위) 클래스에 알려지지 않은 구체 클래스를 생성하는 패턴이며. 자식(하위) 클래스가 어떤 객체를 생성할지를 결정하도록 하는 패턴이기도 하다. 부모(상위) 클래스 코드에 구체 클래스 이름을 감추기 위한 방법으로도 사용한다.
- 팩토리 메소드 패턴은 생성 패턴(Creational Pattern)에 속하는 패턴입니다.
- Template Method Pattern을 사용하며 추상클래스, 인터페이스를 활용하여 객체를 만들어내는 부분을 서브 클래스에 위임하는 패턴입니다.(템플릿 메소드 패턴에 대해서는 추후 포스팅 할 계획입니다.)
- 팩토리 메소드라는 용어에서 알 수 있듯이, 객체를 만들어내는 공장을 만드는 패턴이라고 이해할 수 있습니다.
| Fatory Method Pattern은 왜 사용하는 것일까?
- SOLID 원칙중 O -> OCP 원칙을 기억하시나요?! OCP 즉, Open Closed Principle을 의미하며 확장에 있어서는 열려 있어야 하고 수정에 있어서는 닫혀 있어야 한다는 뜻입니다.
수정에 있어서 닫혀있어야 한다는 말은 곧 코드를 수정하지 않아도 모듈의 기능을 확장 및 변경할 수 있어야 한다는 의미입니다. 그러므로 수정이 발생할 부분과 수정이 발생하지 않은 부분을 분리하여 결합도를 줄여야 하며 이러한 목표는팩토리 메소드 패턴을 이용하여 달성할 수 있습니다.
- 객체 서로간의 결합도를 느슨하게 하여 확장 및 유지보수에 용이합니다.
- DI(Dependency Inversion Principle)(의존 관계 역전 원칙)을/를 성립하게 됩니다.
[Factory Method Pattern의 단점]
- 팩토리 메소드 패턴을 구현하기 위해 많은 서브 클래스를 도입하는 과정에서 코드가 복잡해질 수 있습니다.
| 여기서 잠깐! 구현 방법을 보기 전에 이것만큼은 간략히 알고 가자!
팩토리 메소드 패턴의 예제를 구현해보기 전에 앞서 설명드린 개념 혹은 추후 사용할 개념에 대해 간략하게만 짚고 넘어가겠습니다!
- 생성 패턴이란?
- 객체 생성과 관련된 패턴입니다. 특정 객체가 변경하더라도 프로그램 구조에 영향을 최소화할 수 있도록 유연성을 가지고 있습니다.
- 결합도가 높은 경우
- 결합도가 높은 경우, 아래 그림의 Car 클래스의 init() 메소드의 생성자가 변했을 때 강하게 결합하고 있는 Benz,BMW,Audi 객체의 Car 객체의 생성자를 모두 변경해줘야 합니다. 한 두개가 강하게 결합하고 있을 경우에는 수정이 힘들지 않을 수도 있지만, 만약 더 많은 여러개의 클래스가 의존하고 있다면 어떨까요?
-> 코드를 수정하기 위해서 하나하나 찾아서 수정해야하므로 효율적이지 못합니다. 그러므로 팩토리 메소드 패턴을 적용시키면 보다 결합도를 낮춰 느슨하게 연결할 수 있습니다.
- 결합도가 높은 경우, 아래 그림의 Car 클래스의 init() 메소드의 생성자가 변했을 때 강하게 결합하고 있는 Benz,BMW,Audi 객체의 Car 객체의 생성자를 모두 변경해줘야 합니다. 한 두개가 강하게 결합하고 있을 경우에는 수정이 힘들지 않을 수도 있지만, 만약 더 많은 여러개의 클래스가 의존하고 있다면 어떨까요?
- Factory Method Pattern 구조
| 팩토리 메소드 패턴의 구현 방법
- Vehicle이라는 추상클래스를 만들었으며 브랜드와 연식에 대한 getter() 메소드를 만들었습니다.
public abstract class Vehicle {
public abstract String getBrand();
public abstract String getYear();
@Override
public String toString() {
return this.getBrand() + "회사의 " + this.getYear() + "년식 모델입니다.";
}
}
- 서브 클래스로 Car와 Motorcycle을 만들었습니다. 이 두 서브클래스 모두 Vehicle이라는 추상클래스를 상속합니다. 그러므로, getBrand() 메소드와 getYear()메소드를 재정의했습니다.
public class Car extends Vehicle {
private String brand;
private String year;
public Car(String brand, String year) {
this.brand = brand;
this.year = year;
}
@Override
public String getBrand() {
return this.brand;
}
@Override
public String getYear() {
return this.year;
}
}
public class Motorcycle extends Vehicle {
private String brand;
private String year;
public Motorcycle(String brand, String year) {
this.brand = brand;
this.year = year;
}
@Override
public String getBrand() {
return this.brand;
}
@Override
public String getYear() {
return this.year;
}
}
- 이번에는 Vehicle에 대한 팩토리 클래스를 만들어보겠습니다. 타입을 비교해서 해당하는 인스턴스를 생성합니다.
public class VehicleFactory {
public static Vehicle getVehicle(String type, String brand, String year) {
if (type.equalsIgnoreCase("car")) {
return new Car(brand, year);
} else if (type.equalsIgnoreCase("motorcycle")) {
return new Motorcycle(brand, year);
}
return null;
}
}
- 이제 한번 실제로 실행해보겠습니다!
public class Main {
public static void main(String[] args) {
Vehicle car = VehicleFactory.getVehicle("car", "BMW", "2021");
Vehicle motorcycle = VehicleFactory.getVehicle("motorcycle", "Ducati", "2017");
System.out.println(car.toString());
System.out.println(motorcycle.toString());
}
}
- 결과에서 보여지듯이 인스턴스가 생성되는 메인 메소드에서는 서브클래스인 Car,Motorcycle에 대한 정보는 모르지만, 정상적으로 인스턴스를 생성할 수 있습니다.
| Conclusion
Factory Method Pattern이란?
- 객체를 생성하기 위한 인터페이스를 정의하는데, 어떤 클래스의 인스턴스를 만들지는 서브 클래스에서 결정하게 만드는 패턴이다
왜 Factory Method Pattern을 사용하는가?
- 객체간 결합도를 낮추며 느슨하게 하여 확장 및 유지보수를 용이하게 하기 위함입니다.
Factory Method Pattern 구현 방법
- 클래스의 인스턴스 만드는 시점을 서브 클래스로 미루는 형식으로 구현합니다.
- 인터페이스 혹은 추상클래스를 이용해 객체 생성과 관련한 메소드를 사전에 정의합니다.
Factory Method Pattern을 공부하며
- 최근에 이와 관련한 실습을 해본 경험이 있어서 이해하는데 어렵지 않았습니다. 또한 그러한 경험덕분인지 공부가 더 잘되었다고 생각합니다.
확실히, 짧은 실습 예제를 통해서 추후에 잘 활용한다면 코드를 수정할 때 더 효율적인 부분이 있다는 것을 체감했습니다. 또한, 프로젝트에 임하거나 혼자 공부할 때 적용시켜보면 좋은 공부가 될 것 같습니다.
(추가) - JDK 내부에도 팩토리 메소드 패턴이 존재하는데 java.util.ResourceBundle , java.text.NumberFormat 등이 존재한다는 것을 알게 되었습니다.
(참고)
'Develop > JAVA' 카테고리의 다른 글
DTO(VO), DAO , Entity에 대해서 알아보자! (0) | 2021.09.04 |
---|---|
Java 디자인 패턴 다섯번째 이야기 - 전략 패턴(Strategy Pattern) (0) | 2021.08.16 |
Java 디자인 패턴 세번째 이야기 - 빌더 패턴(Builder Pattern) (0) | 2021.08.13 |
Java 디자인 패턴 두번째 이야기 - 프록시 패턴(Proxy Pattern) (0) | 2021.08.10 |
Java 디자인 패턴 첫번째 이야기 - 싱글톤 패턴(Singleton Pattern) (0) | 2021.08.07 |