一、相关概念了解
首先知晓什么是工厂模式(概念)?
①实例化对象,用工厂方法代替new操作。②工厂模式包括工厂方法模式和抽象工厂模式。③抽象工厂模式是工厂方法模式的拓展。
其次明白工厂模式的意图
①定义一个借口来创建对象,但是让子类来决定哪些类需要被实例化。②工厂方法把实例化的工作推迟到子类中去实现。
最后了解什么情况下适合工厂模式?
①有一组类似的对象需要创建。②在编码时不能预见需要创建哪种类的实例。③系统需要考虑扩展性,不应依赖于产品类实例如何被创建、组合和表达的细节。
二、几种工厂模式的描述(打比方)
三、主要实现方式
以发型实现为例:
(一)常规方法
1.创建接口,定义实现发型的方法
package Factory.sunny.project; /*** 发型接口* * */ public interface HairInterface {//实现了发型public void draw(); //注意 : 接口中没有方法体 }
2.用相应的类来实现该接口,重写接口内的方法
左偏分发型——
package Factory.sunny.project;public class LeftHair implements HairInterface {@Overridepublic void draw() {// TODO Auto-generated method stubSystem.out.println("---------左偏分发型------------");} }
右偏分发型——
package Factory.sunny.project;public class RightHair implements HairInterface {@Overridepublic 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里的BeanFactorypublic 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();