前言
今天来和小伙伴们分享下设计模式中的 工厂模式 啦
一、 工厂模式
我们都知道,设计模式有 23 种,按照功能和使用场景可以分为三大类:
- 创建型模式
- 结构型模式
- 行为型模式
工厂设计模式(Factory Pattern)呢,就是一种很常见的设计模式,属于 创建型模式 的,主要作用就是来 创建对象 的~
原理图
先来看一个小栗子
二、简单工厂模式(非23种)
原理图
例子的话,感觉也挺多的 比如各种品牌的电脑呀,手机呀,家具呀……
比如笔记本电脑的例子
抽取公共接口
这里就只提供一个返回品牌的接口
public interface ILaptop { | |
String brand(); | |
}.2.3. |
接口实现类
这里就举两个例子~
public class HuaWeiLaptop implements ILaptop{ | |
@ Override | |
public String brand() { | |
return "HuaWei"; | |
} | |
} | |
| |
public class MacLaptop implements ILaptop { | |
public String brand() { | |
return "Mac"; | |
} | |
}.2.3.4.5.6.7.8.9.10.11.12.13. |
工厂类
最主要的就是这个工厂类了,我们把创建对象的能力将给它~
public class LaptopFactory { | |
| |
public static ILaptop createLaptop(String brand){ | |
switch (brand){ | |
case "HuaWei": | |
return new HuaWeiLaptop(); | |
case "Mac": | |
return new MacLaptop(); | |
default: | |
return null; | |
} | |
} | |
}.2.3.4.5.6.7.8.9.10.11.12.13. |
测试
就这样,我们就简单的完成了一个工厂模式的应用了~ ,以后创建对象就直接调用工厂的方法就可以了
public class LaptopMain { | |
public static void main(String[] args) { | |
ILaptop hw = LaptopFactory.createLaptop("HuaWei"); | |
String brand = hw.brand(); | |
System.out.println(brand); | |
} | |
}.2.3.4.5.6.7. |
当然,这个是最简单的工厂模式例子了,也叫做 简单工厂模式
当然这个也有很明显的弊端,所以我们再来看看这个 工厂方法模式
三、工厂方法模式
原理图
想想简单工厂的写法,将创建对象的所有操作都封装在一个工厂里,是不合理的,所以我们要进一步 解耦
抽取工厂公共接口
public interface ILaptopFactory { | |
ILaptop createLaptop(); | |
}.2.3. |
工厂实现类
public class HuaweiLaptopFactory implements ILaptopFactory{ | |
public ILaptop createLaptop() { | |
return new HuaWeiLaptop(); | |
} | |
}.2.3.4.5.6. |
测试
简单改动上面测试案例的前两句代码即可
HuaweiLaptopFactory huaweiLaptopFactory = new HuaweiLaptopFactory(); | |
ILaptop mac = huaweiLaptopFactory.createLaptop();.2. |
是不是很简单的就完成了这个工厂模式了
四、 抽象工厂模式
原理图
那么工厂嘛,肯定不止一条生产线,它肯定有其他的业务,比如手机呀,其他电器啥的。
所以我们再重复上面笔记本产品的例子,再建一些其他类,然后也通过工厂类去创建它即可。
抽象工厂
先定义一个抽象工厂
public abstract class AbstractFactory { | |
public abstract IPhone createPhone(); | |
public abstract ILaptop createLaptop(); | |
}.2.3.4. |
工厂实现类
也就多了一个而已呀~
public class HuaweiFactory extends AbstractFactory{ | |
public IPhone createPhone() { | |
return new HuaWeiPhone(); | |
} | |
| |
public ILaptop createLaptop() { | |
return new HuaWeiLaptop(); | |
} | |
}.2.3.4.5.6.7.8.9.10.11. |
五、小结
在使用工厂模式时,我们可以发现从 简单工厂(非23种) ——》 工厂方法 ——》 抽象工厂
这是一个不断 扩展,解耦 的过程,我们可以在项目种根据需要进行选择~
比如 产品多的话就选抽象工厂,单一的话就直接用工厂或者简单工厂就可以了
至此,我们了解到工厂模式是属于23中设计模式中的 创建型模式 ,主要用途就是 创建对象 ,同时方便程序解耦。
接着,我们再来想想 Spring 中和 工厂模式 有关的
说到这里,你想到什么了呢?
不知道的话,就默念 Factory,Factory,Factory,哈哈哈~
是不是脑海中一下子浮现出来了这两货
- BeanFactory
- FactoryBean
从名字就可以看出这两货和工厂有关 (分别通过 getBean 和 getObject 获取对象)
那么我们先来介绍下他们叭
六、BeanFactory
源码 的第一句话
可以发现它是 非常核心的组件 。
遵循严格的 生命周期
可以发现,通过 BeanFactory 创建一个 Bean 要经过非常严格的流程处理,很繁琐。
方法
方法有很多,比如 获取别名呀,类型呀,是否是单例,原型等
通过 getBean 去获取对象
主要作用
根据 BeanDefinition 生成相应的 Bean 对象。
七、FactoryBean
源码
可以发现就这么三个方法,一个小工厂
通过 getObject 方法来返回一个对象
获取对象时:
- 如果 beanName 没有加 & 号,则获取的是 泛型T 的对象。
- 如果添加了 & 号,获取的是实现了 FactoryBean 接口本身的对象,如 EhCacheFactoryBean
而正因为它的小巧,它也被广泛的应用在 Spring内部 ,以及 Spring与第三方框架或组件 的整合过程中。
八、BeanFactory 和 FactoryBean 的区别是什么?
- BeanFactory 是一个大工厂,是IOC容器的根基,有繁琐的 bean 生命周期处理过程,可以生成出各种各样的 Bean
- FactoryBean 是一个小工厂,它自己也是一个 Bean ,但是可以生成其他 Bean
最后一个问题
九、Spring中工厂模式的使用
既然都和工厂有关,那么我们就挑个软柿子捏一下
FactoryBean工厂模式图
可以发现和我们上面介绍的工厂方法模式一样,公共接口和不同的实现类,通过具体的工厂获取对象。
BeanFactory 也是类似的,就不画啦
十、总结
画个图总结下啦