반응형
Factory Method?
- 팩토리 메서드 : 메서드의 호출에 대한 반환값으로 객체를 생산하는 디자인 패턴
너무나 간단하죠?
왜 쓸까요?
- 어떠한 데이터를 가지고 객체를 생산해야 되는데, 어떤 객체인지 예상이 불가능할 때!
- 공통 분모를 가지는 부모 클래스 혹은 추상화된 인터페이스를 데이터를 바탕으로 구성할 때!
- 복잡한 객체를 인스턴스화 하는 논리적인 로직을 따로 분리할 때!
사용 예시
우선은 공통 분모를 가지는 인터페이스를 만들어보았습니다!
package designpattern.factorymethod;
public interface Car {
String getCarName();
}
1. Car 인터페이스 구현
다음으로, 현대차와 기아차를 직접 실체화하였습니다!
package designpattern.factorymethod;
public class HyundaiCar implements Car {
@Override
public String getCarName() {
return "Hyundai";
}
}
2. HyundaiCar 클래스 구현
package designpattern.factorymethod;
public class KiaCar implements Car {
@Override
public String getCarName() {
return "Kia";
}
}
3. KiaCar 클래스 구현
그래서, CarFactory를 구현하고자 합니다!
차이름이 입력값 주어진다면, 해당 차 이름에 따라서 객체를 생산하게끔 설정하는 로직입니다!
package designpattern.factorymethod;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Supplier;
public class CarFactory {
private static Map<String, Supplier<Car>> cars;
static {
cars = new HashMap<>();
cars.put("Kia", KiaCar::new);
cars.put("Hyundai", HyundaiCar::new);
}
public static Car create(final String carName) {
try {
return cars.get(carName).get();
} catch (NullPointerException e) {
throw new IllegalArgumentException("해당하는 차가 없습니다!");
}
}
}
4. CarFactory 클래스 구현
HashMap을 사용했을 때, 직접적으로 KeySet을 순회하게 되면 성능의 이슈가 있으므로
조회(get)를 통해서 Null이 발생한다면 NPE 대신 IAE로 대신 던져주는 모습입니다!
Java8에 새롭게 추가된 Supplier는 Lambda함수의 일종으로,
인자가 없고, 리턴값이 있는 Lambda함수입니다!
물론, 저는 TDD를 기반으로 Production Code를 작성했기 때문에, 실제 Test Code부터 작성하고 시작했었습니다!
package designpattern.factorymethod;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
class CarFactoryTest {
@Test
void 현대차를_제대로_생산하는지_테스트() {
/* Then */
assertThat(CarFactory.create("Hyundai").getCarName()).isEqualTo("Hyundai");
}
@Test
void 기아차를_제대로_생산하는지_테스트() {
/* Then */
assertThat(CarFactory.create("Kia").getCarName()).isEqualTo("Kia");
}
@Test
void 차가_없을때_예외인지_테스트() {
assertThrows(IllegalArgumentException.class, () -> {
CarFactory.create("Tesla");
});
}
}
5. CarFactoryTest 클래스 구현
무난하게 테스트가 통과되는 모습입니다!
Abstract Factory Pattern와의 차이점은 여기에 기술해놓았으니 확인해주세요!
요약
- 정말 많이 쓰는 디자인 패턴중의 하나이므로, 반드시 숙지하자
- 비교적 간단한 디자인 패턴이기에, 프로그래머의 상황과 입맛에 따른 다양한 구현이 가능하다!
- switch case 보다는 더 좋은 방법이 없을까? 생각하는 습관은 좋다!
참고
팩토리 메서드 패턴
반응형
'Developer > Design Pattern' 카테고리의 다른 글
Command Pattern - 커맨드 패턴 (2) | 2019.10.19 |
---|---|
Adapter Pattern - 어댑터 패턴 (0) | 2019.06.23 |
Abstract Factory Pattern - 추상팩토리 패턴 (0) | 2019.06.18 |
Template Method Pattern - 템플릿 메소드 패턴 (0) | 2019.06.09 |
Observer Pattern - 옵저버 패턴 (0) | 2019.06.09 |