개발이슈/디자인패턴
팩토리 메소드 패턴2 (factory method pattern)
kalkin
2022. 8. 29. 13:42
구체적으로 어떤 인스턴스를 만들건지는 하위 클래스에서 정한다.
예를들어, 추상클래스에서 기본 비지니스 로직을 정한 후 변경될수 있는 소지가 다분한 메소드나 기능은
하위클래스에서 만들수 있도록 추상메서드를 이용한다.
대표적인 팩토리 메서드 패턴을 가진 Calendar class를 한번 보자.
java.util.Calendar.class 내의 Factory Method Pattern 의 예
private static Calendar createCalendar(TimeZone zone,
Locale aLocale)
{
CalendarProvider provider =
LocaleProviderAdapter.getAdapter(CalendarProvider.class, aLocale)
.getCalendarProvider();
if (provider != null) {
try {
return provider.getInstance(zone, aLocale);
} catch (IllegalArgumentException iae) {
// fall back to the default instantiation
}
}
Calendar cal = null;
if (aLocale.hasExtensions()) {
String caltype = aLocale.getUnicodeLocaleType("ca");
if (caltype != null) {
switch (caltype) {
case "buddhist":
cal = new BuddhistCalendar(zone, aLocale);
break;
case "japanese":
cal = new JapaneseImperialCalendar(zone, aLocale);
break;
case "gregory":
cal = new GregorianCalendar(zone, aLocale);
break;
}
}
}
if (cal == null) {
// If no known calendar type is explicitly specified,
// perform the traditional way to create a Calendar:
// create a BuddhistCalendar for th_TH locale,
// a JapaneseImperialCalendar for ja_JP_JP locale, or
// a GregorianCalendar for any other locales.
// NOTE: The language, country and variant strings are interned.
if (aLocale.getLanguage() == "th" && aLocale.getCountry() == "TH") {
cal = new BuddhistCalendar(zone, aLocale);
} else if (aLocale.getVariant() == "JP" && aLocale.getLanguage() == "ja"
&& aLocale.getCountry() == "JP") {
cal = new JapaneseImperialCalendar(zone, aLocale);
} else {
cal = new GregorianCalendar(zone, aLocale);
}
}
return cal;
}
case 문을 이용하여
파라메터에 맞는 달력 class (BuddhistCalendar, JapaneseCalendar, GregorianCalendar)등으로
분기처리해주는 모습을 볼수 있다.
자 , 테스트를 한번 해보자.
package factorymethod;
import java.util.Calendar;
import java.util.Locale;
public class TestCalendar {
public static void main(String[] args) {
System.out.println(Calendar.getInstance().getClass());
System.out.println(Calendar.getInstance(Locale.forLanguageTag("th-TH-x-lvariant-TH")).getClass());
System.out.println(Calendar.getInstance(Locale.forLanguageTag("ja-JP-x-lvariant-JP")).getClass());
}
}
Locale 구분에 따라, 추상클래스를 구현한 서브클래스가 다르게 공급받는다.
1. 장점
인터페이스나 추상클래스 등을 이용하여 OCP 에 준수하여 개발할수 있다. (객체간 느슨한 결합)
new로 객체 생성하지않고 주입을 사용함. (DI)
2. 단점.
클래스가 늘어남, (복잡해보일수 있음)
확장에 열려있고, 변경에 닫혀 있는 객체 지향원칙 ( OCP )
- 기존코드를 변경하지않으면서 새로운 기능을 확장 할 수 있어야함.
자바8에 추가된 default 메서드.
- java8 이전에는 interface에는 추상메서드만 정의 할 수있었음
추상클래스에서 하던일을 interface에서도 사용할 수 있게됨.