工厂模式在开源代码中的应用

工厂模式,GoF 的《设计模式》中分为工厂方法和抽象工厂,如果再细一点可以加上简单工厂。

下面看一下源码中的工厂模式的使用。

实例一

JDK 中 java.util.Calendar 类 getInstance 方法使用了简单工厂

public static Calendar getInstance()
{
	return createCalendar(TimeZone.getDefault(), Locale.getDefault(Locale.Category.FORMAT));
}

public static Calendar getInstance(TimeZone zone)
{
    return createCalendar(zone, Locale.getDefault(Locale.Category.FORMAT));
}

public static Calendar getInstance(Locale aLocale)
{
    return createCalendar(TimeZone.getDefault(), aLocale);
}

public static Calendar getInstance(TimeZone zone, Locale aLocale)
{
    return createCalendar(zone, aLocale);
}

private static Calendar createCalendar(TimeZone zone, Locale aLocale)
{
	CalendarProvider provider =
		LocaleProviderAdapter.getAdapter(CalendarProvider.class, aLocale)
							 .getCalendarProvider();
...
	return cal;
}

实例二

JDK 中反射相关的类也使用了简单工厂

  • java.lang.Class 类的 newInstance 方法
@CallerSensitive
public T newInstance()
	throws InstantiationException, IllegalAccessException
{
}
  • forName 方法
@CallerSensitive
public static Class<?> forName(String className)
			throws ClassNotFoundException {
	Class<?> caller = Reflection.getCallerClass();
	return forName0(className, true, ClassLoader.getClassLoader(caller), caller);
}
  • java.lang.reflect.Array 类的 newInstance 方法
public static Object newInstance(Class<?> componentType, int length)
	throws NegativeArraySizeException {
	return newArray(componentType, length);
}
  • java.lang.reflect.Constructor 类的 newInstance 方法
@CallerSensitive
public T newInstance(Object ... initargs)
	throws InstantiationException, IllegalAccessException,
		   IllegalArgumentException, InvocationTargetException
{
	if (!override) {
		if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
			Class<?> caller = Reflection.getCallerClass();
			checkAccess(caller, clazz, null, modifiers);
		}
	}
	if ((clazz.getModifiers() & Modifier.ENUM) != 0)
		throw new IllegalArgumentException("Cannot reflectively create enum objects");
	ConstructorAccessor ca = constructorAccessor;   // read volatile
	if (ca == null) {
		ca = acquireConstructorAccessor();
	}
	@SuppressWarnings("unchecked")
	T inst = (T) ca.newInstance(initargs);
	return inst;
}
  • java.lang.reflect.Proxy 类的 newProxyInstance 方法
@CallerSensitive
public static Object newProxyInstance(ClassLoader loader,
									  Class<?>[] interfaces,
									  InvocationHandler h) throws IllegalArgumentException
{
}

实例三

JDK 中8 种基本类型的包装类 Integer、Long、Short、Character、Byte、Float、Double、Boolean 的 valueOf 方法使用了简单工厂,可以根据参数创建不同的对象。如 Integer 的 valueOf 方法

public static Integer valueOf(String s, int radix) throws NumberFormatException {
	return Integer.valueOf(parseInt(s,radix));
}

实例四

JDK 中 java.util.Collection 接口的 iterator() 方法运用了抽象工厂模式,Collection 的子接口 List、Set 的子类接口的 iterator() 方法可以创建一系列的迭代器 Iterator
List、Set 的 iterator() 方法就可以理解为运用了工厂方法,子类决定了生成什么样的迭代器 Iterator

实例五

Spring 中 BeanFactory 运用了抽象工厂,它的子类或子接口的 getBean 方法提供了一系列获取 bean 对象的方法

public interface BeanFactory {
    Object getBean(String name) throws BeansException;
    <T> T getBean(String name, Class<T> requiredType) throws BeansException;
    <T> T getBean(Class<T> requiredType) throws BeansException;
    Object getBean(String name, Object... args) throws BeansException;
    <T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
}

BeanFactory 的子接口 ConfigurableBeanFactory 接口运用了工厂方法,将 getBean 方法获取对象延迟到 ConfigurableBeanFactory 子类中实现。

AbstractBeanFactory 类的 getBean 方法,可以理解为简单工厂,根据不同参数获取不同的 bean 对象

@Override
public Object getBean(String name) throws BeansException {
	return doGetBean(name, null, null, false);
}

@Override
public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
	return doGetBean(name, requiredType, null, false);
}

@Override
public Object getBean(String name, Object... args) throws BeansException {
	return doGetBean(name, null, args, false);
}

public <T> T getBean(String name, Class<T> requiredType, Object... args) throws BeansException {
	return doGetBean(name, requiredType, args, false);
}

@SuppressWarnings("unchecked")
protected <T> T doGetBean(
		final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
		throws BeansException {

	final String beanName = transformedBeanName(name);
	Object bean;



	return (T) bean;
}

PS:

  • 以上源码部分做了精简
  • 工厂方法定义了创建对象的接口,把类的实例化推迟到子类;抽象工厂提供一个创建产品族的接口,其每个子类可以生产一系列相关的产品,本文按照这个理解进行区分。

【Java学习资源】整理推荐


【Java面试题与答案】整理推荐

猜你喜欢

转载自blog.csdn.net/meism5/article/details/107395233