《您的设计模式》(CBF4LIFE)之“工厂方法模式”【整理】

来源:互联网 发布:英语口语交流软件app 编辑:程序博客网 时间:2024/06/06 21:44

故事背景:女娲造人,女娲架起八卦炉(技术术语:建立工厂开始创建人,具体过程是这样的:先是捏泥巴,然后放八卦炉里烤,再扔到地上成长,但是意外总是会产生的:

第一次烤泥人一个白人诞生了;第二次烤泥人,一个黑人第三次烤泥人,种人。


首先定义一个人类总称

package com.teng.pattern.impl;/** * 人类接口 * <br>创建日期:2016年6月22日 * <br><b>Copyright 2016 tengxiang All Rights Reserved</b> * @author tengxiang * @since 1.0 * @version 1.0 */public interface Human {/** * 哭 * @since 1.0 * <br><b>作者: @author tengxiang</b> * <br>创建时间:2016年6月22日 下午10:29:39 */public void cry();/** * 笑 * @since 1.0 * <br><b>作者: @author tengxiang</b> * <br>创建时间:2016年6月22日 下午10:29:54 */public void laugh();/** * 说 * @since 1.0 * <br><b>作者: @author tengxiang</b> * <br>创建时间:2016年6月22日 下午10:30:09 */public void talk();}

然后定义具体人种:

package com.teng.pattern.impl;/** * 白种人 * <br>创建日期:2016年6月22日 * <br><b>Copyright 2016 tengxiang All Rights Reserved</b> * @author tengxiang * @since 1.0 * @version 1.0 */public class WhiteHuman implements Human {@Overridepublic void cry() {System.out.println("白种人哭。。。");}@Overridepublic void laugh() {System.out.println("白种人笑。。。");}@Overridepublic void talk() {System.out.println("白种人说。。。");}}package com.teng.pattern.impl;/** * 黄种人 * <br>创建日期:2016年6月22日 * <br><b>Copyright 2016 tengxiang All Rights Reserved</b> * @author tengxiang * @since 1.0 * @version 1.0 */public class YellowHuman implements Human {@Overridepublic void cry() {System.out.println("黄种人哭。。。");}@Overridepublic void laugh() {System.out.println("黄种人笑。。。");}@Overridepublic void talk() {System.out.println("黄种人说。。。");}}package com.teng.pattern.impl;/** * 黑种人 * <br>创建日期:2016年6月22日 * <br><b>Copyright 2016 tengxiang All Rights Reserved</b> * @author tengxiang * @since 1.0 * @version 1.0 */public class BlackHuman implements Human {@Overridepublic void cry() {System.out.println("黑种人哭。。。");}@Overridepublic void laugh() {System.out.println("黑种人笑。。。");}@Overridepublic void talk() {System.out.println("黑种人说。。。");}}

定义八卦炉(工厂

package com.teng.pattern.impl;import java.util.HashMap;import java.util.List;import java.util.Random;import com.teng.pattern.utils.ClassUtils;/** * 工厂类 * <br>创建日期:2016年6月22日 * <br><b>Copyright 2016 tengxiang All Rights Reserved</b> * @author tengxiang * @since 1.0 * @version 1.0 */public class HumanFactory {//定义一个Map 初始化过的Human对象都放在这里//在类初始化很消耗资源的情况下,很实用private static HashMap<String,Human> map = new HashMap<String,Human>();/** * 工厂方法——指定人种 * @since 1.0 * @param c c * @return * <br><b>作者: @author tengxiang</b> * <br>创建时间:2016年6月22日 下午10:47:04 */public static Human createHuman(Class c){Human human = null;try {//如果map中有,则直接取出,不用初始化了。类似于memcached?if(map.containsKey(c.getSimpleName())){human = map.get(c.getSimpleName());}else{human = (Human)Class.forName(c.getName()).newInstance();//放到Map中map.put(c.getSimpleName(), human);}} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();}return human;}/** * 工厂方法——随机产生人种 * @since 1.0 * @return * <br><b>作者: @author tengxiang</b> * <br>创建时间:2016年6月26日 上午10:17:12 */public static Human createHuman(){Human human = null;//首先获得有多少个实现类,多少个人种List<Class> humanClassList = ClassUtils.getAllClassByInterface(Human.class);//八卦炉自己开始想烧出什么人就烧出什么人Random random = new Random();int rand = random.nextInt(humanClassList.size());human = createHuman(humanClassList.get(rand));return human;}}

相关的工具类:

package com.teng.pattern.utils;import java.io.File;import java.io.IOException;import java.net.URL;import java.util.ArrayList;import java.util.Enumeration;import java.util.List;/** * 由一个接口,查找到所有的实现类 * <br>创建日期:2016年6月26日 * <br><b>Copyright 2016 tengxiang All Rights Reserved</b> * @author tengxiang * @since 1.0 * @version 1.0 */public class ClassUtils {/** * 给一个接口,返回这个接口的所有实现类 * @since 1.0 * @param c c * @return * <br><b>作者: @author tengxiang</b> * <br>创建时间:2016年6月26日 上午10:37:29 */public static List<Class> getAllClassByInterface(Class c){List<Class> returnClassList = new ArrayList<Class>();//如果不是接口,则不做处理if(c.isInterface()){String packageName = c.getPackage().getName();try{//获取当前包下,以及子包下的所有类List<Class> allClass = getClasses(packageName);//判断是否是同一个接口for(int i = 0; i < allClass.size() ;i++){//判断是是不是一个接口if(c.isAssignableFrom(allClass.get(i))){if(!(allClass.get(i)).equals(c)){//本身不加进去returnClassList.add(allClass.get(i));}}}}catch(Exception e){e.printStackTrace();}}return returnClassList;}//从一个包中查出所有的类,在jar包中不能查找private static List<Class> getClasses(String packageName) throws IOException, ClassNotFoundException{ClassLoader classLoader = Thread.currentThread().getContextClassLoader();String path = packageName.replace(".", "/");//由路径,获取该路径下的所有文件的URLEnumeration<URL> resources = classLoader.getResources(path);//获取该路径下的所有文件List<File> dirs = new ArrayList<File>();while(resources.hasMoreElements()){URL resource = resources.nextElement();dirs.add(new File(resource.getFile()));}ArrayList<Class> classes = new ArrayList<Class>();for(File directory : dirs){classes.addAll(findClasses(directory,packageName));}return classes;}private static List<Class> findClasses(File directory,String packageName) throws ClassNotFoundException{List<Class> classes = new ArrayList<Class>();//如果路径不存在,则返回if(!directory.exists()){return classes;}File[] files = directory.listFiles();for(File file : files){if(file.isDirectory()){//如果文件为文件夹,则递归调用assert !file.getName().contains(".");classes.addAll(findClasses(file,packageName+"."+file.getName()));}else if(file.getName().endsWith(".class")){classes.add(Class.forName(packageName + '.'+file.getName().substring(0, file.getName().length()-6)));}}return classes;}}

女娲开始造人:

package com.teng.pattern;import com.teng.pattern.impl.BlackHuman;import com.teng.pattern.impl.Human;import com.teng.pattern.impl.HumanFactory;import com.teng.pattern.impl.YellowHuman;/** * 造物主 * <br>创建日期:2016年6月22日 * <br><b>Copyright 2016 tengxiang All Rights Reserved</b> * @author tengxiang * @since 1.0 * @version 1.0 */public class God {/** * 主方法 * @since 1.0 * @param args * <br><b>作者: @author tengxiang</b> * <br>创建时间:2016年6月22日 下午10:55:37 */public static void main(String[] args){Human yellowHuman = HumanFactory.createHuman(YellowHuman.class); yellowHuman.cry();yellowHuman.laugh();yellowHuman.talk();Human blackHuman = HumanFactory.createHuman(BlackHuman.class);blackHuman.cry();blackHuman.laugh();blackHuman.talk();//...//随机产生人种for(int i = 0; i <10000 ;i++){Human human = HumanFactory.createHuman();System.out.println("随机产生人种。。。。。。");human.cry();human.laugh();human.talk();}}}

工厂方法模式还有一个非常重要的应用,就是延迟初始化什么是延迟初始化呢?一个对象初始化完毕后就不释放,等到再次用到就不用再次初始化了,直接从内存中拿到就可以了。






0 0
原创粉丝点击