工厂模式

工厂模式

工厂模式简单的说就是为屏蔽对象的实例化过程

工厂模式可以分为三种
1. 简单工厂
2. 工厂方法模式
3. 抽象工厂模式

简单工厂模式

简单工厂模式又称静态工厂方法模式。重命名上就可以看出这个模式一定很简单。如果不使用简单工厂模式,我们一般按如下的方法开发

以用户买车为例

抽象类车,他可以有很多子类比如大众,BMW或者奥迪

@ToString
public abstract class AbstractCar {
    @Getter
    protected String name="汽车";
    public AbstractCar() {

    }
}

目前用户只有很少的钱只够买一辆大众,那么代码如下

AbstractCar car = new DaZhong();
System.out.println("用户购买了一辆" + car.getName());

如果过段时间车价下降,原本买大众的钱可以买奥迪了,那么我们又得修改源代码

AbstractCar car = new AoDi();
System.out.println("用户购买了一辆" + car.getName());

我们可以通过简单工厂模式来避免上面的问题

具体的工厂类和工厂方法

public class SimpleFactory {
    public static AbstractCar getCar(int price) {
        if (price < 1000) {
            return new DaZhong();
        } else if (price < 2000) {
            return new AoDi();
        } else {
            return new BMW();
        }
    }
}

调用工厂方法只需要传入金额就可以

public void simpleFactory() {
    AbstractCar car = SimpleFactory.getCar(700);
    System.out.println(car);
}

简单工厂模式有以下优点
1. 使代码结构清晰,有效封装变化,调用者无需关注产品的实例化过程
2. 向调用者屏蔽具体的产品类

工厂方法模式

简单工厂模式仍然存在以下的问题,车型有数千中,每年又有先增车型,如果将所有车型对象实例化放在工厂中的话,简单工厂会非常臃肿,同时对于新增车型也不利于扩展

工厂方法模式可以比较好的解决这个问题,比如奥迪车厂新增了某款车型,那么只需要修改奥迪车厂就可以

工厂方法模式包含如下几种角色
1.抽象工厂角色:
这是工厂方法模式的核心,与调用者交互提供具体的产品

2.工厂实现
工厂决定实例化产品的具体逻辑

3.产品接口
定义产品的规范,产品所拥有的功能,属性

4.产品实现
实现产品规范,实现具体的产品方法

抽象工厂

案例:
这一次用户有了明确的选择就是要买一辆奥迪

首先定义工厂接口

public interface CarFactory {
    public AbstractCar createCar(int price);
}

具体的奥迪工厂的实现类

public class AoDiCarFactory implements CarFactory {
    @Override
    public AbstractCar createCar(int price) {
        if (price < 1000) {
            return new A4();
        } else if (price < 1500) {
            return new A7();
        } else {
            return new A8();
        }
    }
}

具体的用户调用过程如下

//首先选择具体的车厂
CarFactory aodiFactory=new AoDiCarFactory();
//付钱收车
AbstractCar car=aodiFactory.createCar(1000);
System.out.println(car);

Spring与工厂模式

Spring对工厂模式的支持包括两种,一种是静态工厂方法另一种是非静态工厂方法

静态工厂

public class StaticFlyInterface {

    public static Fly getInstance() {
        //返回某个接口实现类
        return new Fighter();
    }

}

在spring.xml配置文件中如下配置

<bean id="fly" class="com.spring.ioc.factory.staticfactory.StaticFlyInterface" factory-method="getInstance"/>

通过factory-method告知Spring通过StaticFlyInterface工厂类的getInstance方法构造Fly接口对象

fly接口的使用类如下

public class FlyUser {
    //需要注入一个fly接口实现类
    private Fly fly;

    public void fly() {
        System.out.println("I am going to fly");
        fly.fly();
    }

    public Fly getFly() {
        return fly;
    }

    public void setFly(Fly fly) {
        this.fly = fly;
    }
}

spring.xml声明

<bean id="flyUser" class="com.spring.ioc.factory.staticfactory.FlyUser">
    <property name="fly" ref="fly"/>
</bean>

这里引用的fly对象就是通过工厂返回的对象

非静态工厂方法

public class NonStaticFactory {
    public Fly getInstance() {
        return new Fighter();
    }
}

因为方法是非静态的所以我们得声明工厂实例,并通过调用工厂实例的非静态方法获取接口实现类

<!--声明的工厂实例-->
<bean id="flyFactory" class="com.spring.ioc.factory.staticfactory.NonStaticFactory"/>
<!--调用工厂方法获取接口实现类-->
<bean id="fly2" factory-bean="flyFactory" factory-method="getInstance"/>

FactoryBean

Spring还有一种特殊的bean也可以实现工厂模式
我们使用FactoryBean重复实现的功能

public class FlyFactoryBean implements FactoryBean<Fly> {

    @Override
    public Fly getObject() throws Exception {
        return new Fighter();
    }

    @Override
    public Class<?> getObjectType() {
        return Fly.class;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }

}

isSingleton()方法告诉容器,FlyFactoryBean对象生产的对象是否以singleton形式存在于容器中

Spring.xml配置

<!--配置FactoryBean-->
<bean id="flyFactoryBean" class="com.spring.ioc.container.FlyFactoryBean"/>
<!--
flyFactoryBean引用的FactoryBean并不是FactoryBean本身而是该FactoryBean所产生的对象
-->
<bean id="flyUser" class="com.spring.ioc.factory.staticfactory.FlyUser">
    <property name="fly" ref="flyFactoryBean"/>
</bean>

如果我们一定要取得flyFactoryBean而不是它产生的对象,我们可以在这样获取

在FactoryBean id前加上&
Object o=context.getBean("&flyFactoryBean");

Spring框架内部也大量使用了FactoryBean接口比如
- JndiObjectFactoryBean
- LocalSessionFactoryBean
- SqlMapClientFactoryBean
- ProxyFactoryBean
- TransactionProxyFactoryBean

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值