简单工厂模式(Simple Factory Pattern)属于类的创新型模式,又叫静态工厂方法模式(Static FactoryMethod Pattern),是通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类(或者父接口)。
简单工厂模式的 UML 图:
(1)抽象产品(abstract Product)角色:简单工厂模式所创建的所有对象的父类,注意,这里的父类可以是接口也可以是抽象类,它负责描述所有实例所共有的公共接口。
(2)具体产品(Concrete Product)角色:简单工厂所创建的具体实例对象,这些具体的产品往往都拥有共同的父类。
(3)工厂(Factory Creator)角色:这是简单工厂模式的核心,由它负责创建所有的类的内部逻辑。当然工厂类必须能够被外界调用,创建所需要的产品对象。
(1)抽象产品和具体产品角色:
public interface Car {// 车的父类 public void driver();// 开车 } class Benz implements Car {// 奔驰车 public void driver() { System.out.println("今天咱开奔驰!"); } } class Bike implements Car {// 自行车 public void driver() { System.out.println("唉,现在经济危机,只能骑自行车了呀!"); } } class Bmw implements Car {// 宝马 public void driver() { System.out.println("今天开宝马吧!"); } } class Lh implements Car {// 路虎 public void driver() { System.out.println("今天路虎吧!"); } } (2)工厂角色:
public class DriverFactory { public static Car driverCar(String s) throws Exception { if (s.equalsIgnoreCase("Benz")) {// 判断传入参数返回不同的实现类 return new Benz(); } else if (s.equalsIgnoreCase("Bmw")) { return new Bmw(); } else if (s.equalsIgnoreCase("Bike")) { return new Bike(); } else { throw new Exception();// 抛出异常 } } } (3)测试类
public static void main(String[] args) { try { // Car car = DriverFactory.driverCar("Bike");// 调用方法返回车的实例 Car car = DriverFactory.driverCar("Bmw"); System.out.println("朋友,今天开什么车呀?"); car.driver();// 调用方法开车 } catch (Exception e) { System.out.println("开车出现问题......"); } } 现在我们利用反射机制实现工厂模式,可以在不修改工厂类的情况下添加任意多个子类。
修改工厂类
public static Car driverCar(String s) { Car car = null; try { car = (Car) Class.forName(s).newInstance(); //通过反射机制动态创建对象 } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return car; } 测试类:
public static void main(String[] args) { try { // Car car = DriverFactory.driverCar("com.hlx.facotry.reflect.Bike");// 调用方法返回车的实例 // Car car = DriverFactory.driverCar("com.hlx.facotry.reflect.Bmw"); Car car = DriverFactory.driverCar("com.hlx.facotry.reflect.Lh"); System.out.println("朋友,今天开什么车呀?"); car.driver();// 调用方法开车 } catch (Exception e) { System.out.println("开车出现问题......"); } }
但是有一点仍然很麻烦,就是需要知道完整的包名和类名,这里可以使用properties配置文件来完成。
配置文件car.properties
bike=com.hlx.facotry.reflect.Bike bmw=com.hlx.facotry.reflect.Bmw lh=com.hlx.facotry.reflect.Lh benz=com.hlx.facotry.reflect.Benz 测试类: public class Test { public static void main(String[] args) { try { Test test = new Test(); // String value = test.getValue("bike"); // String value = test.getValue("bmw"); String value = test.getValue("benz"); // 调用方法返回车的实例 Car car = DriverFactory.driverCar(value); System.out.println("朋友,今天开什么车呀?"); car.driver(); } catch (Exception e) { System.out.println("开车出现问题......"); } } /** * 但是有一点仍然很麻烦,就是需要知道完整的包名和类名,这里可以使用properties配置文件来完成。 加载配置文件 * * car.properties 必须放在src目录下或自己创建的目录下 * @param key * @return */ public String getValue(String key) { // 创建对象 Properties properties = new Properties(); // 输入流对象 InputStream is = this.getClass().getClassLoader().getResourceAsStream("car.properties"); // 加载这个文件 try { properties.load(is); // 获得值 return properties.getProperty(key); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } }