疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

工厂模式结合反射技术的应用


 

       工厂模式简介:

  工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽,达到提高灵活性的目的。工厂模式共有三种,简单工厂(simple factory),多态工厂(factory method),抽象工厂(abstract factory).

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

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

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

  [java] view plaincopy

  package factory;

  public interface Car

  {

  public void drive();

  }

  实现类1:

  [java] view plaincopy

  package factory;

  public class CarImpl01 implements Car

  {

  @Override

  public void drive()

  {

  // TODO 自动生成的方法存根

  System.out.println("this is a benz car");

  }

  }

  实现类2:

  [java] view plaincopy

  package factory;

  public class CarImpl02 implements Car

  {

  @Override

  public void drive()

  {

  // TODO 自动生成的方法存根

  System.out.println("this is a bmw car");

  }

  }

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

  [plain] view plaincopy

  carImplName = factory.CarImpl01

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

  [java] view plaincopy

  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 = "srcfactoryCarImpl.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;

  }

  }

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

  [java] view plaincopy

  package factory;

  public class Main

  {

  public static void main(String[] args)

  {

  // TODO 自动生成的方法存根

  Car car = Factory.getInstance().buildCar();//要先获取Factory的实例对象!

  car.drive();

  }

  }

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

  [plain] view plaincopy

  #carImplName = factory.CarImpl01

  carImplName = factory.CarImpl02