设计模式之工厂模式

 一 工厂模式

        工厂模式可以分为三种,分别是简单工厂模式,工厂方法,抽象工厂,下面我们将分别介绍一下这三种设计模式,

     1 简单工厂

           我们先通过一个实例来说明一下什么是简单工厂模式:某一天小张同志要去加油站加油,加油站的工作人员会按照一下步骤来完成加油的动作,先打开汽车的油箱盖,然后再选择
小张同志需要加的型号的汽油(92, 95, 98),然后将汽油注入到汽车的油箱中,最后盖上
油箱盖子。那么按照如下的流程,我们一般的代码流程如下所示:
           1先定义一个抽象的汽油类,

public abstract class Gasoline {
	
	public abstract String getGasoline();

}

          2 再定义3个子类(92汽油,95汽油,98汽油)

public class Gasoline92 extends Gasoline{

	@Override
	public String getGasoline() {
		return "92";
	}
	
}
public class Gasoline95 extends Gasoline {

	@Override
	public String getGasoline() {
		return "95";
	}
	
}
public class Gasoline98 extends Gasoline {

	@Override
	public String getGasoline() {
		return "98";
	}

}

       3 定义一个加油站,然后提供一个加油的方法

public class GasStation {
	
	public void addGasoline(String type){
		Gasoline gasoline = null;
		if("92".equals(type)){
			gasoline = new Gasoline92();
		}else if("95".equals(type)){
			gasoline = new Gasoline95();
		}else if("98".equals(type)){
			gasoline = new Gasoline98();
		}
		openFuelTankCap();
		injectGasoline(gasoline);
		closeFuelTankCap();
	}
	
	private void openFuelTankCap(){
		System.out.println("打开邮箱盖");
	}
	
	private void injectGasoline(Gasoline gasoline){
		System.out.println("注入了汽油"+ gasoline.getGasoline());
	}
	
	private void closeFuelTankCap(){
		System.out.println("盖上邮箱盖");
	}

}

         4 编写一个测试类

public class GasolineTest {
	
	public static void main(String[] args){
		GasStation gasStation = new GasStation();
		gasStation.addGasoline("92");
	}

}

//输出结果如下:
打开邮箱盖
注入了汽油92
盖上邮箱盖

       按照需求这个代码就实现了相对应的功能。但是随着以后的发展,万一将来又出现了一个99号的汽油,那么这个时候该怎么办?只能再创建一个99号汽油的类,然后再到GasStation的addGasoline方法中添加一个99号的汽油的判断,这个时候便修改到了addGasoline这个方法的逻辑了。为了不修改这个方法里面的代码,于是就有了简单工厂。这个时候我们可以创建一个工厂的类,如下所示:

public class GasolineFactory {
	
	public static Gasoline createGasoline(String type){
		Gasoline gasoline = null;
		if("92".equals(type)){
			gasoline = new Gasoline92();
		}else if("95".equals(type)){
			gasoline = new Gasoline95();
		}else if("98".equals(type)){
			gasoline = new Gasoline98();
		}
		return gasoline;
	}

}

然后修改加油站的加油方法为:

public class GasStation {
	
	public void addGasoline(String type){
		Gasoline gasoline = GasolineFactory.createGasoline(type);
		openFuelTankCap();
		injectGasoline(gasoline);
		closeFuelTankCap();
	}
	
	private void openFuelTankCap(){
		System.out.println("打开邮箱盖");
	}
	
	private void injectGasoline(Gasoline gasoline){
		System.out.println("注入了汽油"+ gasoline.getGasoline());
	}
	
	private void closeFuelTankCap(){
		System.out.println("盖上邮箱盖");
	}

}

         这样如果新增99号汽油,我们就可以不用去修改GasStation的addGasoline方法了,只需要在GasolineFactory类的createGasoline再添加一个判断即可。这种方式就是简单工厂。但是这种方式还是需要去修改GasolineFactory类的方法代码,从而违背了对修改关闭的这一原则。

那么如何解决这个问题呢?下面我们再来介绍一个抽象工厂的设计模式。

     2 工厂方法

           在工厂方法的模式里,我们还是有一个汽油类,然后一个92汽油类,一个95汽油类,一个98汽油类,跟上面的简单工厂一样。然后再将GasStation定义成一个抽象类,然后再提供一个createGasoline的抽象方法,如下所示:

public abstract class GasStation {
	
	public void addGasoline(){
		Gasoline gasoline = createGasoline();
		openFuelTankCap();
		injectGasoline(gasoline);
		closeFuelTankCap();
	}
	
	public abstract Gasoline createGasoline();
	
	private void openFuelTankCap(){
		System.out.println("打开邮箱盖");
	}
	
	private void injectGasoline(Gasoline gasoline){
		System.out.println("注入了汽油"+ gasoline.getGasoline());
	}
	
	private void closeFuelTankCap(){
		System.out.println("盖上邮箱盖");
	}

}

  然后再定义3个加油站的类继承GasStation类,实现 createGasoline的方法。如下所示:

public class GasStation92 extends GasStation{

	@Override
	public Gasoline createGasoline() {
		return new Gasoline92();
	}

}
public class GasStation95 extends GasStation{

	@Override
	public Gasoline createGasoline() {
		return new Gasoline95();
	}

}
public class GasStation98 extends GasStation{

	@Override
	public Gasoline createGasoline() {
		return new Gasoline98();
	}

}

再编写一个测试类,如下所示:

public class GasolineTest {
	
	public static void main(String[] args){
		GasStation gasStation = new GasStation95();
		gasStation.addGasoline();
		gasStation = new GasStation92();
		gasStation.addGasoline();
		gasStation = new GasStation98();
		gasStation.addGasoline();
	}

}

//输出结果如下所示
打开邮箱盖
注入了汽油95
盖上邮箱盖
打开邮箱盖
注入了汽油92
盖上邮箱盖
打开邮箱盖
注入了汽油98
盖上邮箱盖

       至此抽象工厂的模式已经完毕,如果以后需要99号汽油的话,那么也只需要再创建一个GasStation99即可,也不会修改到原来的代码,从而满足了对扩展开放,对修改关闭的这一原则。

       如果后续加油站购买了一些机器人,有时候是人工加油,有的时候是机器加油,那么这个代码又改如何进行呢?接下来,我们将通过这种情况来介绍一下抽象工厂的设计模式。

     3 抽象工厂

          抽象工厂的模式里,还是跟上面的案例一样,定义一个汽油类,然后一个92汽油类,一个95汽油类,一个98汽油类。然后定义一个接口,然后定义一个加油,打开盖子等方法,代码示例如下所示:

public interface GasStationFactory {
	
	public void addGasoline(Gasoline gasoline);
	public void openFuelTankCap();
	public void injectGasoline(Gasoline gasoline);
	public void closeFuelTankCap();
	
}

   定义两个子类HumanStationFactory和MachineStationFactory。代码如下所示:

public class HumanStationFactory implements GasStationFactory{

	@Override
	public void addGasoline(Gasoline gasoline) {
		// TODO Auto-generated method stub
		openFuelTankCap();
		injectGasoline(gasoline);
		closeFuelTankCap();
	}

	@Override
	public void openFuelTankCap() {
		System.out.println("人工打开邮箱盖");
	}

	@Override
	public void injectGasoline(Gasoline gasoline) {
		System.out.println("人工注入了汽油"+ gasoline.getGasoline());
	}

	@Override
	public void closeFuelTankCap() {
		System.out.println("人工盖上邮箱盖");
	}

}
public class MachineStationFactory implements GasStationFactory{

	@Override
	public void addGasoline(Gasoline gasoline) {
		// TODO Auto-generated method stub
		openFuelTankCap();
		injectGasoline(gasoline);
		closeFuelTankCap();
	}
	@Override
	public void openFuelTankCap(){
		System.out.println("机器打开邮箱盖");
	}
	@Override
	public void injectGasoline(Gasoline gasoline){
		System.out.println("机器注入了汽油"+ gasoline.getGasoline());
	}
	@Override
	public void closeFuelTankCap(){
		System.out.println("机器盖上邮箱盖");
	}

}

修改GasStation类,如下所示:

public abstract class GasStation {
	
	private GasStationFactory gasStationFactory;
	
	public GasStation(GasStationFactory gasStationFactory){
		this.gasStationFactory = gasStationFactory;
	}
	
	public void addGasoline(){
		Gasoline gasoline = createGasoline();//获取哪种汽油由工厂方法的模式去完成
		gasStationFactory.addGasoline(gasoline);//添加汽油是由抽象工厂的模式去完成
	}
	
	public abstract Gasoline createGasoline();
	
}

编写测试类

public class GasolineTest {
	
	public static void main(String[] args){
		GasStation gasStation = new GasStation95(new HumanStationFactory());
		gasStation.addGasoline();
		gasStation = new GasStation92(new MachineStationFactory());
		gasStation.addGasoline();
		gasStation = new GasStation98(new MachineStationFactory());
		gasStation.addGasoline();
	}

}
//输出结果
人工打开邮箱盖
人工注入了汽油95
人工盖上邮箱盖
机器打开邮箱盖
机器注入了汽油92
机器盖上邮箱盖
机器打开邮箱盖
机器注入了汽油98
机器盖上邮箱盖

    至此,工厂模式的示例已经介绍完成。

      4 总结

                简单工厂:简单工厂模式就是把变化的部分抽取出来,然后通过一个工厂类来生                      成对应的对象。严格意义上来说这种方法并不属于设计模式。
                工厂方法模式:定义一个创建对象的接口,但是具体实例化哪个类由其子类来实现。
        工厂方法让类的实例化推到了子类上。
                抽象工厂模式:提供一个接口,用于创建相关或者依赖的对象家族,而不需要指定是具          体是哪个类。
                

       
       

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值