一、相关概念了解
首先知晓什么是工厂模式(概念)?
①实例化对象,用工厂方法代替new操作。②工厂模式包括工厂方法模式和抽象工厂模式。③抽象工厂模式是工厂方法模式的拓展。
其次明白工厂模式的意图
①定义一个借口来创建对象,但是让子类来决定哪些类需要被实例化。②工厂方法把实例化的工作推迟到子类中去实现。
最后了解什么情况下适合工厂模式?
①有一组类似的对象需要创建。②在编码时不能预见需要创建哪种类的实例。③系统需要考虑扩展性,不应依赖于产品类实例如何被创建、组合和表达的细节。
二、几种工厂模式的描述(打比方)
三、主要实现方式
以发型实现为例:
(一)常规方法
1.创建接口,定义实现发型的方法
package Factory.sunny.project; /** * 发型接口 * * */ public interface HairInterface { //实现了发型 public void draw(); //注意 : 接口中没有方法体 }
2.用相应的类来实现该接口,重写接口内的方法
左偏分发型——
package Factory.sunny.project; public class LeftHair implements HairInterface { @Override public void draw() { // TODO Auto-generated method stub System.out.println("---------左偏分发型------------"); } }
右偏分发型——
package Factory.sunny.project; public class RightHair implements HairInterface { @Override public void draw() { // TODO Auto-generated method stub System.out.println("------------右偏分发型----------"); } }
3.测试代码(贴一小段主要的)
HairInterface left=new LeftHair(); left.draw();
缺点是每来一个发型都需要创建新的...Hair类实现,而且还要在客户端调用,不利于维护......
(二)采用发型工厂方法
1.创建发型工厂
package Factory.sunny.project; import java.util.Map; /** * 发型工厂 * */ public class HairFactory { /** * 根据类型创建对象 * */ public HairInterface getHair(String key){ if("left".equals(key)){//字符放在前面是预防key报空指针 return new LeftHair(); }else if("right".equals(key)){ return new RightHair(); } return null; } }
2.测试
HairFactory factory=new HairFactory(); HairInterface left=factory.getHair("left"); left.draw();
缺点:不智能,判断条件太冗杂,解决办法——>反射
(三)反射方法解决上述问题(一步到位,采取映射)
1.首先看未采取映射办法的代码
//生产发型的方法,为了优化上面代码对于大量发型的大量判断,使用反射原理,类似于spring里的BeanFactory public HairInterface getHairByClass(String className){ try { HairInterface hair=(HairInterface) Class.forName(className).newInstance(); return hair; } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; }
2.采取映射的代码(在此之前先要创建properties文件和properties文件读取类)
properties文件
properties文件读取类
package Factory.sunny.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文件的读取工具 * * */ public class ProrpertiesReader { public Map<String,String> getProperties(){ Properties props =new Properties(); Map<String,String> map=new HashMap<String,String>(); //将key和property读入到map中 try { InputStream in=getClass().getResourceAsStream("type.properties"); props.load(in); Enumeration en=props.propertyNames(); while(en.hasMoreElements()){ String key=(String) en.nextElement(); String property=props.getProperty(key); map.put(key, property); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return map; } }
反射&映射方法代码
public HairInterface getHairByClasskey(String key){ try { Map<String,String> map=new ProrpertiesReader().getProperties(); HairInterface hair=(HairInterface) Class.forName(map.get(key)).newInstance(); return hair; } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; }
3.测试
//反射方法
HairInterface right=factory.getHairByClass("Factory.sunny.project.RightHair");
right.draw(); // 反射&映射方法 HairInterface hair=factory.getHairByClasskey("right"); hair.draw(); HairInterface hair2=factory.getHairByClasskey("in"); hair2.draw();