官方定义的好处:    

工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式。著名的Jive论坛 ,就大量使用了工厂模式,工厂模式在Java程序系统可以说是随处可见。因为工厂模式就相当于创建实例对象的new,我们经常要根据类Class生成实例对象,如A a=new A() 工厂模式也是用来创建实例对象的,所以以后new时就要多个心眼,是否可以考虑使用工厂模式,虽然这样做,可能多做一些工作,但会给你系统带来更大的可扩展性和尽量少的修改量。

个人理解:解耦!!!

下面利用反射机制自定义一个较为实用的工厂模式:

    如果我们有老师,学生两种角色,他们都有说话的行为。很明显,可以定义父类或接口使之继承

package com.self.project;

/**
 * 人类接口
 * say():说话行为
 * @author BreakingBad_
 *
 */
public interface Person {
	
	/**
	 * 说话方法
	 */
	public abstract void say();
}

具体实现的子类:

package com.self.project;

/**
 * 学生
 * @author BreakingBad_
 *
 */
public class Student implements Person{

	/**
	 * 学生说话的具体方法
	 */
	@Override
	public void say() {
		System.out.println("好的,老师");
	}
	
}
package com.self.project;

/**
 * 老师
 * 
 * @author BreakingBad_
 *
 */
public class Teacher implements Person {

	/**
	 * 老师说话的具体方法
	 */
	@Override
	public void say() {
		System.out.println("同学们我们做游戏啦");
	}

	/**
	 * 老师报出数字
	 */
	public void sayNumbers(int[] numbers) {
		System.out.println("同学们我报出的数是" +
	numbers[1] + "\t" + numbers[2] + "\t" + numbers[3]);
	}
}

之后,我们建立type.properties文件  存放参数名称key和映射的类地址

student=com.self.project.Student
teacher=com.self.project.Teacher

创建PropertiesReader工具,拿到properties文件内键值对,存入hashmap中

package com.self.project;

import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * 工具类 读取Properties文件内容 将键值放入Map中
 * 
 * @author BreakingBad_
 *
 */
public class PropertiesReader {

	// 储存properties文件中的key value的map
	Map<String, String> personMap = new HashMap<String, String>();

	/**
	 * 读取properties文件 存入personMap中
	 * 
	 * @return
	 */
	public Map<String, String> getProperties() {
		Properties properties = new Properties();
		// 拿到输入流--->通过文件位置 web项目resource或src下就是classpath:***.properties
		InputStream input = getClass().getResourceAsStream("type.properties");
		try {// properties工具加载输入流
			properties.load(input);
			Enumeration<?> enumeration = properties.propertyNames();
			while (enumeration.hasMoreElements()) {
				// 读取properties文件
				String key = (String) enumeration.nextElement();
				String property = properties.getProperty(key);
				personMap.put(key, property);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return personMap;
	}
}

拿到键值对后,创建工厂,工厂内用反射拿到类类型(类的CLASS对象)通过newInstance创建实例,面向接口编程不用细说了

package com.self.project;

import java.util.Map;

/**
 * Person工厂
 * 
 * @author BreakingBad_
 *
 */
public class PersonFactory {

	/**
	 * 根据传进来的Key返回具体Object
	 * 
	 * @param key
	 * @return
	 */
	public static Person getInstance(String key) {
		// 读取文件读取类传来的map<key,反射的类地址>
		Map<String, String> personMap = new PropertiesReader().getProperties();
		try {// 通过Class.forName.newInstance方法拿到类对象
			Person person = (Person) Class.forName(personMap.get(key)).newInstance();
			return person;
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return null;
	}
}

测试:

package com.self.project;

/**
 * 游戏开始
 * 
 * @author BreakingBad_
 *
 */
public class GamePlay {
	public static void main(String[] args) {
		Person teacher = PersonFactory.getInstance("teacher");//参数在properties文件中一定存在键值
		teacher.say();
		Person student = PersonFactory.getInstance("student");
		student.say();
	}
}

控制台输出:

java enum 工厂类_properties文件