1、定义
父类定义了创建对象的接口,由子类来具体实现。
工厂模式让类把实例化的动作推迟到了子类当中。
2、详解
// 这是一个网页爬虫类,它利用HttpClient来获取数据并分析
public abstract class WebCrawler {
// 爬取网页数据
public WebResult getWebInfo(String url) {
HttpClient c = getClient();
HtmlResult res = c.getPage(url);
return processHtml(res);
}
// HttpClient是接口或者抽象类,下文统称为接口
private HttpClient getClient() {
// 如果缓存中不存在client则创建
HttpClient c = getFromCache();
if (c == null) {
c = createClient();
}
// 创建之后对client进行初始化
initClient(c);
}
// 提供一个抽象让子类来实现创建client
// 这个抽象方法就是“工厂方法”
protected abstract HttpClient createClient();
}
// A和B类型两种client工厂都不需要关心创建client前的逻辑判断以及创建后的流程处理,他们只关心创建对象
class ATypeCrawler extends WebCrawler {
HttpClient createClient() {
return new ATypeClient();
}
}
class BTypeCrawler extends WebCrawler {
HttpClient createClient() {
return new BTypeClient();
}
}
工厂模式使得WebCrawler不必关心HttpClient 的具体类型,因为这些具体的HttpClient 是由子类具体创建的,WebCrawler根本不知道到底有哪些HttpClient类型,它只关心使用。
同样的,各个子类也只管着创建HttpClient 的实例,至于这些实例被拿去做什么事情,什么时候做,它们并不知情。
按理说,高层组件应该依赖于低层组件,低层组件为高层组件提供一些最基础的服务,但是工厂模式倒置了这一依赖现象,让低层组件反而要依赖于统一的抽象接口。
工厂模式让高层组件(WebCrawler)和低层组件(ATypeClient|BTypeClient|……)都依赖于共同的接口(HttpClient),这倒置了原本的依赖模型,解除了高层组件和低层组件之间的强依赖关系
3、Spring实例
AbstractFactoryBean继承了FactoryBean,工厂Bean的主要作用是为了实现getObject()返回Bean实例。
public abstract class AbstractFactoryBean<T> implements FactoryBean<T>, BeanClassLoaderAware, BeanFactoryAware, InitializingBean, DisposableBean {
// 定义了获取对象的前置判断工作,创建对象的工作则交给了一个抽象方法
public final T getObject() throws Exception {
// 判断了Bean是否单例并且是否已经被加载过
return this.isSingleton()?(this.initialized?this.singletonInstance:
this.getEarlySingletonInstance()):this.createInstance();
}
// 由子类负责具体创建对象
protected abstract T createInstance() throws Exception;
}