工厂模式(Factory Pattern)是java中最常用的设计模式之一。该设计模式属于创建型模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们创建对象时不会对客户端暴露创建的逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
那么工厂模式主要是用来干嘛的呢?
工厂模式主要的意图是定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。主要解决接口的选择问题。
工厂模式怎么实现呢?
让其子类实现工厂接口,返回的也是一个抽象的产品。创建过程在其子类中执行。
优点:
- 一个调用者想要创建一个对象,只需要知道其名字就可以了。
- 扩展性高,想要增加产品,只需要扩展一个工厂类就行了。
- 屏蔽了产品的具体实现,调用者只需要关心产品的接口就行了。
缺点:
- 每增加一个产品的时候,都需要增加一个具体类和对象实现工厂,系统中的类会越来越多
- 类的增多加大了相关依赖
常用的使用场景:
- 日志记录器:记录可能记录到本地硬盘、系统事件、远程服务等
- 数据库访问,当用户不知道最后系统采用哪一类数据库,以及数据库可能有变化时。
实现过程:
首先我们先创建一个对外的接口 FactoryInterFace 和它的两个实现类 FactoryBeanOne、
FactoryBeanTwo,如下:
public interface FactoryInterFace {
void factoryMethod();
}
public class FactoryBeanOne implements FactoryInterFace{
@Override
public void factoryMethod() {
System.out.println("Inside::factoryMethod() beanOne");
}
}
public class FactoryBeanTwo implements FactoryInterFace{
@Override
public void factoryMethod() {
System.out.println("Inside::factoryMethod() beanTwo");
}
}
现在我们有了2个产品了(FactoryBeanOne和FactoryBeanTwo),那么怎么通过工厂来生产他们呢?首先我们先得有一个工厂Factory
public class Factory {
/**
* 根据bean名称获取对应的产品对象
* @param beanName 产品名称
* @return 对应的产品名称
*/
public FactoryInterFace getFactoryBean(String beanName){
if(beanName == null){
return null;
}
// 获取factoryBeanOne
if(("factoryBeanOne").equals(beanName)){
return new FactoryBeanOne();
}
// 获取factoryBeanTwo
if(("factoryBeanTwo").equals(beanName)){
return new FactoryBeanTwo();
}
return null;
}
}
现在我们有了一个工厂Factory,工厂里有了2个产品FactoryBeanOne和FactoryBeanTwo,那么接下来就是怎么使用工厂来获取需要的产品对象了。
public class Test {
public static void main(String[] args) {
// 创建一个工厂
Factory factory = new Factory();
// 根据名字从工厂中获取一个factoryBeanOne对象,并使其进行工作
FactoryInterFace factoryBeanOne = factory.getFactoryBean("factoryBeanOne");
factoryBeanOne.factoryMethod();
// 根据名字从工厂中获取一个factoryBeanTwo对象,并使其进行工作
FactoryInterFace factoryBeanTwo = factory.getFactoryBean("factoryBeanTwo");
factoryBeanTwo.factoryMethod();
}
}
从上面的代码可以看到,我们根本不用关系FactoryBeanOne和FactoryBeanTwo是如何new的,我们只需要告诉工厂Factory我们需要的产品名称,工厂就会创建好对应的产品对象返回给我们来使用。
假如我们现在需要第三个产品FactoryBeanThree来满足我们的业务需求,那么我们这个时候只需要再创建工厂的扩展类FactoryBeanThree,
public class FactoryBeanThree implements FactoryInterFace{
@Override
public void factoryMethod() {
System.out.println("Inside::factoryMethod() beanThree");
}
}
并把它加入到工厂中即可
public class Factory {
/**
* 根据bean名称获取对应的产品对象
* @param beanName 产品名称
* @return 对应的产品名称
*/
public FactoryInterFace getFactoryBean(String beanName){
if(beanName == null){
return null;
}
// 获取factoryBeanOne
if(("factoryBeanOne").equals(beanName)){
return new FactoryBeanOne();
}
// 获取factoryBeanTwo
if(("factoryBeanTwo").equals(beanName)){
return new FactoryBeanTwo();
}
// 获取factoryBeanThree
if(("factoryBeanThree").equals(beanName)){
return new FactoryBeanThree();
}
return null;
}
}