目录
前言
Spring的核心接口BeanFactory使用的是工厂方法设计模式,掌握了工厂方法设计模式可以更好的理解Spring的设计。设计模式是前辈总结的经验,本文主要讲解工厂方法设计模式出现的原因,核心就是一个工厂生成一款产品。
工厂方法模式出现的原因
使用普通方式创建对象
假如我们不使用工厂模式,而是通过new直接创建对象,代码如下
1、定义Product接口和实现类
interface Product{
void show();
}
class DefaultProduct implements Product{
@Override
public void show(){
}
}
class NewProduct implements Product{
@Override
public void show(){
}
}
2、业务方使用
public class Demo {
public static void main(String[] args) throws IOException {
Product product1 = new DefaultProduct();
// do somethings
Product product2 = new DefaultProduct();
// ......
}
}
假设Demo是业务代码,创建对象逻辑跟业务代码耦合在一起,某一天,业务改需求,这个产品我要改一下,过几天又说要改回来,再后来又要改,就跟我们的产品一样,每次都需要全局替换掉创建类的地方。如果老是改需求,谁受得了,于是工厂方法模式出现。那么我们来看一下它是怎么解决这个问题的。
使用工厂方法模式
首先我们看到Factory和Product都是接口,符合面向接口编程规范,不同的工厂实现类生成了不同的产品类。我们写一个例子来看看。
1、定义Product接口和实现类
interface Product{
void show();
}
class DefaultProduct implements Product{
@Override
public void show(){
}
}
class NewProduct implements Product{
@Override
public void show(){
}
}
2、定义Factory接口和实现类
interface Factory{
Product createProduct();
}
class DefaultFactory implements Factory{
@Override
public Product createProduct() {
return new DefaultProduct();
}
}
class NewFactory implements Factory{
@Override
public Product createProduct() {
return new NewProduct();
}
}
3、业务方使用
public class SpringDemo {
public static void main(String[] args) throws IOException {
Factory factory = getFactory(); // 使用getFactory(),业务代码更加灵活
Product product1 = factory.createProduct();
// do somethings
Product product2 = factory.createProduct();
// ......
}
public static Factory getFactory(){
return new DefaultFactory();
}
}
核心点就是:一个工厂生产一种产品。
解决两个问题
1、如果某一天生产产品的流程发生变化,那么只需要修改Factory工厂的逻辑即可;
2、如果要换一种产品,那么直接修改获取工厂的方法getFactory即可。
设计模式是被产品经常改修需求逼出来的,在工作中也可以采用这种方式来应对业务经常该需求,而很多开源框架是为了提供用户扩展而采用设计模式,提供了灵活性。
BeanFactory的实现类
接下来,我们来看看Spring的工厂,BeanFactory接口,看一下有哪些实现类。
XmlBeanFactory、JdbcBeanFactory,通过名字大致可以猜到,XmlBeanFactory是从xml读取配置信息来创建Bean,而JdbcBeanFactory是从数据库中读取配置,对于我们来说不需要知道是哪一种,只需要调用getBean方法拿到自己想要的对象就可以,无视其实现(创建对象)细节。
工厂方法模式图
总结
工厂方法设计模式的核心就是定义产品接口和工厂接口,一个工厂创建一种产品,然后封装获取工厂的行为,如果需要新增产品则实现产品接口,直接修改获取工厂的方法即可;一旦工厂生产产品的逻辑发生变化,则修改对应的工厂即可,与业务代码无关,符合开闭原则。