# 설명
팩토리(Factory) 패턴에서 팩토리는 말그대로 공장을 뜻한다. 어떠한 인스턴스를 만들어주는 곳이다.
앞서 추상팩토리 패턴을 공부했었다. 추상 팩토리에서는 MySQL에 관련된 인스턴스와 Oracle과 관련된 인스턴스를 한번에 생성해줄 수 있었다. 하나의 군(집단)을 이루는 인스턴스를 묶어서 생성할 수 있게 도와주는 것이 팩토리 패턴이었다.
이번 팩토리 메소드패턴에서는 객체생성을 팩토리에서 해주지만, 여러 Concrete Product를 팩토리내에서 생성하게 해주는 패턴이다.
즉, Car라는 abstract Product가 존재한다. Concrete Product로는 Sonata, santafe, grandeur과 같은 Car를 상속받는 세부적인 차종을 구현한다. 이제 Sonata, santafe, grandeur라는 차종이 존재하고 이를 Factory내에서 만들어 객체를 반환시켜주는 것이다.
이제 CarFactory의 기능을 알려줄 abstract Creator를 만들어 준다. 구체적인 차의 생성과정은 하위 클래스에게 위임하고 CarFactory가 가져야할 동작들을 정의해준다. 또한 CarFactory에서는 템플릿메소드 패턴을 적용할 수 있다.
CarFactory에서 구현 명세를 만들었다면, 이를 HyundaiCarFactory에서 상속받아 구현을 진행해주자.
서두에서 팩토리(Factory)라는 것이 무엇인지에 대해서 간략히 적었다. 팩토리라는 단어가 "공장"이라는 뜻을 가지고 있지만 뭔가 직관적이게 나에게 다가오지 않아서 이해가 힘들었다. 이번 예제와 저번 예제를 학습하면서, Factory는 어떠한 인스턴스를 생성해주는 곳이라는 것을 확실히 알 수 있었다. 그리고 팩토리패턴이 활용되는 곳에서는 Factory를 상속받는 하위 SubFactory클래스에서 생성(create)에 관한 세부적인 내용을 구현해줌을 알 수 있었다.
- 즉 CarFactory -> 차를 생성하기 위한 명세를 적은 추상 클래스
- HyundaiCarFactory -> 실질적으로 차를 생성해주는 클래스, 구현부가 적혀있음.
# 코드
## Proudct 관련
// Product 해당 부
public abstract class Car {
public String carType;
@Override
public String toString() {
return carType;
}
}
// Concrete Product
public class Sonata extends Car{
public Sonata(){
carType = "sonata";
}
}
// Concrete Product
public class Grandeur extends Car{
public Grandeur(){
carType = "grandeur";
}
}
## Factory
// Creator
public abstract class CarFactory {
public abstract Car createCar(String name);
public abstract Car reCallCar(String name);
// 아래 기능들은 CarFactory안에서 구현해도 상관 없다.
public abstract void washCar();
public abstract void numbering();
public abstract void lightOn();
public abstract void lightOff();
// 템플릿 메서드에 해당됨. 순서를 미리 정해줌
final public void beforeSellCar(String name){
System.out.println("@@@@===자동차 생산 및 테스트===@@@@");
createCar(name);
washCar();
numbering();
lightOn();
lightOff();
System.out.println("@@@@===자동차를 출고합니다!!===@@@@");
}
}
// Concrete Creator
public class HyundaiCarFactory extends CarFactory{
HashMap<String,Car> carMap = new HashMap<>();
@Override
public Car createCar(String name) {
Car car = null;
// 여기서 객체 인스턴스(차)를 만들어주는 행위
if ( name.equals("sonata")) {
car = new Sonata();
} else if (name.equals("grandeur")) {
car = new Grandeur();
}
return car;
}
@Override
public Car reCallCar(String name) {
Car car = carMap.get(name);
// reCall할 차가 없는 경우 차를 새로 만들어 준다.
if ( car == null) {
if ( name.equals("hojun")){
car = new Sonata();
} else if (name.equals("tom")) {
car = new Grandeur();
}
carMap.put(name,car);
}
return car;
}
@Override
public void washCar() {
System.out.println("현대 블루링크에서, 세차를 진행합니다.");
}
@Override
public void numbering() {
System.out.println("현대 블루링크에서, 자동차 번호를 부여합니다.");
}
@Override
public void lightOn() {
System.out.println("현대 블루링크에서, 상향등 테스트를 시작합니다.");
}
@Override
public void lightOff() {
System.out.println("현대 블루링크에서, 상향등 테스트를 종료합니다.");
}
}
# 테스트
public class Test {
public static void main(String[] args) {
CarFactory factory = new HyundaiCarFactory();
Car myCar = factory.createCar("sonata");
System.out.println(myCar.carType);
Car fatherCar = factory.createCar("grandeur");
System.out.println(fatherCar.carType);
factory.beforeSellCar("sonata");
// 자동차 ReCall
Car hCar = factory.reCallCar("hojun");
Car hCar2 = factory.reCallCar("hojun");
System.out.println(hCar.carType);
System.out.println(hCar2.carType);
System.out.println(hCar == hCar2);
}
}
팩토리 패턴을 활용해서 손쉽게 여러 종류의 인스터스를 factory를 이용해 생성해낼 수 있는 것을 볼 수 있다. 또한 reCallCar라는 메서드를 활용해서 이미 같은 인스턴스가 존재하면 그 인스턴스를 반환해주는 singleton과 유사한 기능이 정상 작동함을 볼 수 있다.
'• 독서 > Design Pattern' 카테고리의 다른 글
[디자인패턴] 브릿지 패턴(Bridge Pattern) (0) | 2022.09.22 |
---|---|
[디자인패턴] 전략패턴 (Strategy Pattern) (1) | 2022.09.21 |
[디자인패턴-위임패턴] 템플릿 메서드 패턴(Template Method) (0) | 2022.09.18 |
[디자인패턴-생성패턴] 빌더 패턴(Builder Pattern) (2) | 2022.09.17 |
[디자인패턴-생성패턴] 추상팩토리 패턴(Abstract-Factory pattern) (0) | 2022.09.17 |