工厂模式,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 方法

@CallerSensitivepublic T newInstance()  throws InstantiationException, IllegalAccessException{}
  • forName 方法

@CallerSensitivepublic 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 方法

@CallerSensitivepublic 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 方法

@CallerSensitivepublic 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 对象

@Overridepublic Object getBean(String name) throws BeansException {  return doGetBean(name, null, null, false);}
@Overridepublic <T> T getBean(String name, Class<T> requiredType) throws BeansException {  return doGetBean(name, requiredType, null, false);}
@Overridepublic 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:

  • 以上源码部分做了精简

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


更多相关文章

  1. 构造方法的参数太多,如何解决?
  2. 面试官:为什么静态方法不能调用非静态方法和变量?
  3. ConcurrentHashMap之size()方法
  4. 为什么不推荐使用finalize方法,来看看对垃圾回收有什么影响吧
  5. java8中的一个骚操作-方法引用(使代码看起来很高大上)

随机推荐

  1. php语言的优势是什么
  2. 原生 PHP 实现支付宝 App 第三方登录获取
  3. php魔术常量使用方法
  4. php怎么远程连接oracle
  5. php八大数据类型有哪些
  6. php的优势与缺点
  7. php怎么接入公众号
  8. php依赖注入的三种方式
  9. php如何获取上传文件大小
  10. php怎么换行输出