【设计模式】工厂模式结合反射技术的简单应用

工厂模式简介:

工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽,达到提高灵活性的目的。工厂模式共有三种,简单工厂(simple factory,多态工厂(factory method),抽象工厂(abstract factory.大家如果对工厂模式不熟悉的话,可以参考另一篇博文(http://blog.csdn.net/rowandjj/article/details/8785050)。

 

下面进入本次主题:

在我们实际项目开发时,可能对于某一接口有不同的实现方式,或者说,项目需求发生改变时,我们需要对接口重新实现以满足新的需求。这时我们可以充分利用多态的特性使引用指向新的实现类,这样只需修改几行代码即可,但是我们想象一下,当项目足够大,代码达到几万行,而且不止一处需要修改时,我们的工作将会变得很麻烦,而且还容易出现失误。所以我们并不建议修改源代码。那如何才能保证在尽量少的修改代码的前提下完成这项工作呢?我们想到了反射可以通过类名构建一个类的实例,我们可以把类名放在一个配置文件中作为一个键值对存储,当需要修改实现类时,只需要修改该键所对应的的值即可,是不是很酷呢?

下面通过一个简单的例子实现之。

首先我们定义一个接口和它的两个实现类(实际情况可能有多个实现类):

package factory;

public interface Car
{
	public void drive();
}


实现类1:

package factory;

public class CarImpl01 implements Car
{
	@Override
	public void drive()
	{
		// TODO 自动生成的方法存根
		System.out.println("this is a benz car");
	}
}


实现类2:

package factory;

public class CarImpl02 implements Car
{
	@Override
	public void drive()
	{
		// TODO 自动生成的方法存根
		System.out.println("this is a bmw car");
	}
}


 

下面重点来了,我们在项目下新建一个配置文件CarImpl.properties,文件中定义这样一个键值对:

carImplName = factory.CarImpl01


 

接下来,我们创建一个工厂类用来制造汽车:

package factory;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

public class Factory
{
	private static Car car = null;
	private static Factory instance = new Factory();
//	上面两行代码位置不可以互换,否则会抛出空指针异常(联系类的初始化顺序)
	private Factory()//单例
	{
		String filename = "src\\factory\\CarImpl.properties";
		InputStream inStream = null;
		try
		{
			inStream = new FileInputStream(new File(filename));
			Properties prop = new Properties();
			prop.load(inStream);
			String className = prop.getProperty("carImplName");
			car = (Car)Class.forName(className).newInstance();
		}
		catch (FileNotFoundException e)
		{
			// TODO 自动生成的 catch 块
			e.printStackTrace();
/*
这里异常处理过于简单,实际开发需要针对不同业务逻辑编写不同的异常处理方式
*/
		}
		catch (IOException e)
		{
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
		catch (InstantiationException e)
		{
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
		catch (IllegalAccessException e)
		{
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
		catch (ClassNotFoundException e)
		{
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
		
	}
	public static Factory getInstance()
	{
		return instance;
	}
	
	public Car buildCar()
	{
		return car;
	}
}


 

好了,大功告成,我们测试一下功能吧。

package factory;

public class Main
{
	public static void main(String[] args) 
	{
		// TODO 自动生成的方法存根
		Car car = Factory.getInstance().buildCar();//要先获取Factory的实例对象!
		car.drive();
		
	}

}


 

现在我们想生成CarImpl02对象,不必更改代码,只需注释掉刚才配置文件,像这样:

#carImplName = factory.CarImpl01

carImplName = factory.CarImpl02

是不是很方便呢?

 

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值