一、定义
Simple Factory Pattern,又叫做静态工厂方法模式。简单来说,简单工厂模式有一个具体的工厂类,可以生成多个不同的产品。
二、应用场景
对于产品种类相对较少的情况,考虑使用简单工厂模式可以很方便地创建所需产品。使用简
单工厂模式的客户端只需要传入工厂类的参数,不需要关心如何创建对象的逻
三、通用写法
以下是简单工厂模式的通用写法。
public class Client {
public static void main(String[] args) {
new SimpleFactory().makeProduct(1);
}
//抽象产品
public interface IProduct
void doSomething();
}
//具体产品:ProductA
static class Product implements IProduct{
public void doSomething(){
System.out.println("I am Product A");
}
//具体产品:ProductB
static class Product implements IProduct{
public void doSomething(){
System.out.println("I am Product B");
}
//具体产品:Productc
static class Product implements IProduct{
public void doSomething()
System.out.println("I am Product C");
}
}
final class Const{
static final int PRODUCT A = 0;
static final int PRODUCT _B = 1;
static final int PRODUCT_C = 2;
}
static class SimpleFactory {
public static Product makeProduct (int kind) {
switch (kind) {
case Const. PRODUCT A:
return new ProductA();
case Const.PRODUCT_B:
return new ProductB();
case Const.Product_C:
return new ProductC();
}
return null;
}
}
}
四、框架源码中的应用
简单工厂模式在 JDK 源码中无处不在,例如 Calendar 类,看 Calendar.getinstance0方法。下
面打开的是 Calendar 的具体创建类。
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;
}
在LoggerFactory中有多个重载的方法getLogger
public static Logger getLogger(String name) {
ILoggerFactory iLoggerFactory = getILoggerFactory();
return iLoggerFactory.getLogger(name);
}
public static Logger getLogger(Class<?> clazz) {
Logger logger = getLogger(clazz.getName());
if (DETECT_LOGGER_NAME_MISMATCH) {
Class<?> autoComputedCallingClass = Util.getCallingClass();
if (autoComputedCallingClass != null && nonMatchingClasses(clazz, autoComputedCallingClass)) {
Util.report(String.format("Detected logger name mismatch. Given name: \"%s\"; computed name: \"%s\".", logger.getName(), autoComputedCallingClass.getName()));
Util.report("See http://www.slf4j.org/codes.html#loggerNameMismatch for an explanation");
}
}
return logger;
}