工厂模式的分类
在使用工厂之前,先来简单了解一下什么是工厂模式。
-
简单工厂
- 第一种实现方法,每次调用都会产生一个新的对象
/** * 创建配置类 */ public class ConfigFactory { public static Config createConfig(){ return new Config(); } }
- 第二种实现方法,缓存对象,调用的时候直接返回
/** * 创建配置类 */ public class ConfigFactory { private static final Map<String, Config> cachedParsers = new HashMap<>(); public static final String CACHE_KEY = "CACHE"; static { // 根据自己的逻辑初始化 cachedParsers.put(CACHE_KEY,new Config()); } public static Config createConfig(){ return cachedParsers.get(CACHE_KEY); } }
-
工厂方法
工厂方法能够比较简洁的去除掉代码中复杂的if分支逻辑。
//典型实现
public abstract class Factory {
public abstract Config createConfig();
}
public class ConfigFactory implements Factory {
@Override
public Config createConfig(){
return new Config();
}
}
这样当我们新增一种 parser 的时候,只需要新增一个实现了 ConfigFactory 接口的 Factory 类即可。
tip: 这种实现方式,目前还没有解决问题,因为仍然需要不同if分支来新建对应的工厂,如ConfigFactory。想要比较好的解决问题,还需要引入另外一个工厂,即工厂的工厂。
public class FactoryFactory{
public static final Map<String, Factory> cachedFactories = new HashMap<>();
public static final String CACHE_KEY = "CONFIG";
static {
cachedFactories.put(CACHE_KEY,new ConfigFactory());
}
/**
* 根据逻辑来创建工厂
* @return
*/
public static Factory createFactroy(String type){
if(StringUtils.isBlank(type)){
//throw new NullPointerException();
return null;
}
return cachedFactories.get(type);
}
}
- 抽象工厂 抽象工厂可以使用的情景比较少,主要用于一些对于待生产对象特别复杂的工厂。让一个工厂复杂创建不同类型的对象。
public abstract class Factory {
public abstract Config createFileConfig();
public abstract Config createClassConfig();
}
public class ConfigFactory implements Factory {
@Override
public Config createFileConfig(){
return new FileConfig();
}
public Config createClassConfig(){
return new ClassConfig();
}
}
一般情况下使用不到!~
工厂模式的使用
前面介绍了三种工厂模式的实现,下面就就可以来看看我们该在什么情况下来进行使用。
- 代码中存在大段的 if-else 分支判断,动态地根据不同的类型创建不同的对象。可以考虑使用工厂模式。将if-else创建对象的代码抽离出来,放到工厂类中。
- 单个对象本身的创建过程比较复杂,比如前面提到的要组合其他类对象,做各种初始化操作,将对象的创建过程封装到工厂类中。
Spring中的工厂模式
- 工厂(最小原型设计)
public interface ApplicationContext extends ... {
AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;
}
// 工厂方法--不同的实现
public abstract class AbstractApplicationContext extends ... {
public AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException {
return getBeanFactory();
}
@Override
public final ConfigurableListableBeanFactory getBeanFactory() {
synchronized (this.beanFactoryMonitor) {
if (this.beanFactory == null) {
throw new IllegalStateException("BeanFactory not initialized or already closed - " +
"call 'refresh' before accessing beans via the ApplicationContext");
}
return this.beanFactory;
}
}
}
public class GenericApplicationContext extends ...{
@Override
public AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException {
//Assert that this context's BeanFactory is currently active
assertBeanFactoryActive();
return this.beanFactory;
}
}
- 工厂的工厂,DefaultSingletonBeanRegistry
public class DefaultSingletonBeanRegistry extends... {
// 初始化容器
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
/** Cache of singleton factories: bean name to ObjectFactory. */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
/** Cache of early singleton objects: bean name to bean instance. */
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
/** Set of registered singletons, containing the bean names in registration order. */
private final Set<String> registeredSingletons = new LinkedHashSet<>(256);
/** Map between containing bean names: bean name to Set of bean names that the bean contains. */
private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<>(16);
/** Map between dependent bean names: bean name to Set of dependent bean names. */
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);
/** Map between depending bean names: bean name to Set of bean names for the bean's dependencies. */
private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<>(64);
@Override
public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
//注册bean
Assert.notNull(beanName, "Bean name must not be null");
Assert.notNull(singletonObject, "Singleton object must not be null");
synchronized (this.singletonObjects) {
Object oldObject = this.singletonObjects.get(beanName);
if (oldObject != null) {
...
}
addSingleton(beanName, singletonObject);
}
}
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
// 获取Bean对象,如果没有的话就创建
...
}
}
这里我们为了跟设计模式对应的更加清晰,将部分源码忽略,这样可以更加清晰。