透过源码学习设计模式3—BeanFactory、FactoryBean和工厂模式

1、简单工厂模式:

简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类,简单工厂是“固定的”,因为只有一个实现,没有子类。它不属于23种设计模式之一,但在实际应用中却比较常见,当使用构造器构造时太复杂时可以用这种方式。先看个简单例子:

public class FruitFactory {
  public static Fruit get(String fruitType) {
    if ("apple".equals(friutType)) {
      return new Apple();
    } else if ("orange".equals(friutType)) {
     return new Orange();
    }
  }
}
FruitFactory.get("apple")

简单工厂有静态工厂和实例工厂,上面属于静态工厂,下面看下实例工厂:

public class FruitFactory {
  public  Fruit get(String fruitType) {
    if ("apple".equals(friutType)) {
      return new Apple();
    } else if ("orange".equals(friutType)) {
      return new Orange();
    }
  }
}
FruitFactory fruitFactory = new FruitFactory();
fruitFactory.get("")

静态工厂利用静态方法定义一个简单的工厂,相较而言,静态工厂不需要使用创建对象的方法来实例化对象,但不能通过继承改变创建对象的行为。

以上两种简单工厂在Spring中都有其配置方式,静态工厂xml配置如下:

<bean id=“apple" class="...FruitFactory" factory-method="get">
<constructor-arg>
<value>apple</value> 
</constructor-arg>
</bean>

非静态工厂xml配置如下:

<bean id=“fruitFactory" class="...FruitFactory”/>
<bean id=“apple”factory-bean="...fruitFactory" factory-method="get">
<constructor-arg>
<value>apple</value> 
</constructor-arg>
</bean>

个人认为以上xml配置方式,包括后面的FactoryBean接口实现类的配置,都可以用spring后面出的@Bean代替。不需要factory-method,factory-bean这类标签。

Spring中的BeanFactory就是简单工厂模式的体现,根据传入一个唯一的标识来获得Bean对象,但是否是在传入参数后创建还是传入参数前创建这个要根据具体情况来定。BeanFactory接口是含有许多bean定义的对象实现的,每个bean都由一个字符串名称作为惟一标识。根据bean定义,工厂将返回对象的独立实例(prototype模式),或者单个共享实例(替代singleton模式,其实例是工厂范围内的单例)。API是相同的,返回哪种类型的实例取决于bean工厂配置。从Spring 2.0开始,可以根据具体的应用程序上下文使用更多的scope(如web环境的request和session scope)

2、工厂方法模式

定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。其使用场景通常是类中有一些通用的处理流程,但希望更改实际使用的具体对象类型。

public abstract class FruitProducer {
  protected abstract Fruit makeFruit();
  public void produceFruit() {
    private final Fruit f = makeFruit(); // The fruit we will work on..
    //省略代码,创建fruit后执行的公共功能
  }
}

然后,通过在子类中实现工厂方法,可以重用FruitProducer.produceFruit()中的公共功能:

class OrangeProducer extends FruitProducer {
  @Override
  protected Fruit makeFruit() {
    return new Orange();
  }
}

原来简单工厂是一个对象负责所有具体类的实例化,而工厂方法模式是定义一个用于创建对象的接口,由一群子类负责实例化,简单工厂不具备工厂方法的弹性。

Spring中的FactoryBean就是典型的工厂方法模式。如下图:

FactoryBean接口由BeanFactory中配置的对象实现,这些对象本身就是用于创建对象的工厂。如果一个bean实现了这个接口,那么它就是创建对象的工厂bean,即FactoryBean,而不是bean实例本身。我们常用的ProxyFactoryBean就是基于FactoryBean实现的。FactoryBean接口如下,其实现类源码大家可以自己查阅。

public interface FactoryBean <T> {
  T getObject() throws java.lang.Exception;
  java.lang.Class<?> getObjectType();
  boolean isSingleton();
}

工厂模式体现了一个非常重要的设计原则,即依赖倒置原则,参照前面的例子,假如在FruitProducer的makeFruit方法内部直接通过new Apple(),new Orange()方式创建水果对象的,而不委托给工厂,那就意味着FruitProducer作为一个高层的组件,直接依赖的低层的组件,依赖于具体的水果对象,这些实现类改变了,FruitProducer也要同步改变,而且每增加一个水果类型,FruitProducer就要增加一个依赖。

低层模块的修改会直接影响到高层模块,这样高层模块很难在不同的环境里复用,因此高层模块不能依赖于低层模块,不管是高层还是低层模块,都要依赖于抽象,即上面代码中的Fruit抽象类,通过这样的“依赖倒置”,减少了高层模块对低层模块的依赖,提高了高层模块的可复用性。工厂模式正是实现这一原则的重要武器。

java达人

ID:drjava

(长按或扫码识别)

BeanFactory是Spring框架中的一个接口,它是工厂模式的一种实现。工厂方法模式是一种创建型设计模式,它定义了一个创建对象的接口,但具体的实例化过程由实现这个接口的类来决定。在工厂方法模式中,用户只需要关心所需产品对应的工厂,无需关心创建细节。而BeanFactory是Spring框架中用于创建和管理对象的工厂接口,它提供了一种灵活的方式来创建和配置对象。通过BeanFactory,我们可以利用反射机制解决工厂方法中存在大量工厂类的问题,并且可以支持单例和多例对象的创建,懒加载以及一些额外的初始化方法。因此,BeanFactory可以看作是工厂方法模式的一种实现方式。 #### 引用[.reference_title] - *1* [设计模式--1.1工厂模式BeanFactory)](https://blog.csdn.net/weixin_38982636/article/details/88835602)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [从工厂模式理解Spring中BeanFactory](https://blog.csdn.net/CSDN_WYL2016/article/details/119702281)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值