1、定义
• 在简单工厂模式中,可以根据参数的不同返回不同类型的实例,简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。
2、要点
• 当客户端需要什么,只要传入一个正确的参数,即可获取需要的实例,无需知道其创建的细节
• 客户端不知道具体实现的是什么,也不知道如何实现,只知道可以通过一个工厂获取一个对象,然后通过这个对象获取想要的功能
3、何时选用单例模式
• 想完全隔离实现,让外部只能通过接口来操作封装体
• 想把对外创建对象的职责进行集中管理和控制
4、本质
• 选择实现
5、简单工厂模式实现方式
• Product接口
package com.test; /** * 接口的定义,该接口可以通过简单工厂来创建 */ public interface Product { /** * 示意,具体的功能方法的定义 * @param s 示意,需要的参数 */ public void test(String s); }
• 具体的实现类A
package com.test; /** * 接口的具体实现对象TestA */ public class ConcreteProductA implements Product{ @Override public void test(String s) { // TODO Auto-generated method stub System.out.println("ConccreteProductA:============"+s); } }
• 具体的实现类B
package com.test; /** * 接口的具体实现对象TestB */ public class ConcreteProductB implements Product{ @Override public void test(String s) { // TODO Auto-generated method stub System.out.println("ConccreteProductB:============"+s); } }
• 配置文件Properties
TestA=com.test.ConccreteProductA
• 工厂类
package com.test; import java.io.IOException; import java.io.InputStream; import java.util.Properties; /** * 工厂类,用来创造Api对象 */ public class Factory { /** * 具体的创造TestAbstract对象的方法 * @param condition 示意,从外部传入的选择条件 * @return 创造好的TestAbstract对象 */ public static Product createApi(int condition) { //应该根据某些条件去选择究竟创建哪一个具体的实现对象, //这些条件可以从外部传入,也可以从其它途径获取。 //如果只有一个实现,可以省略条件,因为没有选择的必要。 //示意使用条件 Product api = null; if(condition == 1) { api = new ConcreteProductA(); } else if(condition == 2) { api = new ConcreteProductB(); } return api; } /** * 具体的创造TestAbstract的方法,根据配置文件的参数来创建接口 * @return 创造好的TestAbstract对象 */ public static Product createApi() { //直接读取配置文件来获取需要创建实例的类 //至于如何读取Properties,还有如何反射这里就不解释了 Properties p = new Properties(); InputStream in = null; try { in = Factory.class.getResourceAsStream( "TestFactory.properties"); p.load(in); } catch (IOException e) { System.out.println( "装载工厂配置文件出错了,具体的堆栈信息如下:"); e.printStackTrace(); } finally { try { in.close(); } catch (IOException e) { e.printStackTrace(); } } //用反射去创建,那些例外处理等完善的工作这里就不做了 Product api = null; try { api = (Product)Class.forName(p.getProperty("TestA")).newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } return api; } }
说明:外部在调用工厂类进行创建对象时,主要是通过两个方法,如下
1)Product testa=Factory.createApi(1);此方法外部是通过传入参数,工厂类根据参数进行选择具体的实现,调用方只知道Product父类,以及参数
2)Product api = Factory.createApi();此方法是通过配置文件来进行选择的,调用端不知道具体实现,也不知道参数,只知道返回的是一个Product对象,选择则是通过配置文件来完成
3)有人可能会说,工厂类中用到了new,知道了具体的实现的,但是注意工厂类的位置,工厂类是于product在同一个包中的,即地位是相同的,都属于内部,而工厂类是内部提供给外部使用的,因此工厂类知道具体实现是OK的