新年慢慢靠近,也许这一年的收获寥寥不值一提,但是相信自己,一切都会好起来。fighting,You must believe yourself.
Java Reflect model :
看看下面的实例,相信比较之下,会有很好的启发:
不使用反射来进行工厂模式:
创建父类
1:创建一个关于电脑工厂父类(BaseComputer):
2:该父类拥有所有基本的属性
3:创建相应的set、get方法
public class BaseComputer {
private int price;
private String CPUStyle;
private String goodsName;
private String CORE;
···//相应的get/set方法(略)
}
创建对应的子类(lenovo、mac、dell、hp)
注:一下数据属于随便乱写,不存在任何参考意义
//DellComputer
public class DellComputer extends BaseComputer {
public DellComputer() {
setPrice(5900);
setCORE("intel i7");
setCPUStyle("思科处理器");
setGoodsName("戴尔 DELL");
}
//对电脑的描述
public String Describle(){
return "Dell 国际品牌";
}
}
//HPComputer
public class HpComputer extends BaseComputer {
public HpComputer() {
setPrice(4900);
setCORE("intel i5");
setCPUStyle("思科处理器");
setGoodsName("惠普 HP");
}
//对电脑的描述
public String Describle(){
return "HP 国际品牌";
}
}
创建工厂类
public class ComputerFactory {
public static BaseComputer newInstance(String className) {
if("Dell".equals(className)){
return new DellComputer();
}else if("Hp".equals(className)){
return new HpComputer();
}
return null;
}
}
在java方法中进行测试
@Test
public void main(){
HpComputer hp = (HpComputer) ComputerFactory.newInstance("Hp");
System.out.println(hp.getCORE()+"\n"+
hp.getGoodsName()+"\n"+
hp.getCPUStyle()+"\n"+
hp.getPrice()+"\n");
System.out.println(hp.Describle());
}
结果显示:
此时:我们也可以拿到想要的数据,调用不同的关于Computer的时候,只需要传入相应的类的名称就好了。
注:在java中的向下转型和向上转型很敏感。所以在转型的过程中,需要注意,避免ANR异常。
问题:
1:如果我们的业务中需要加入 lenovo,mac或者其他品牌的电脑。
2:工厂中的项目增多,我们需要加入相应的类,还需要修改我们的工厂类。
3:我们在进行调用的时候还需要知道工程模式中判断的字段,很麻烦。
使用反射来处理工厂模式
整体来说,变化并不是很大,只是在我们的工厂类中进行修改
public class ComputerFactory {
public static BaseComputer newInstance(Class clz) {
BaseComputer baseComputer = null;
try {
//异常处理
baseComputer = (BaseComputer) clz.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return baseComputer;
}
}
现在开始进行调用
public void main(){
DellComputer dell = (DellComputer) ComputerFactory.newInstance(DellComputer.class);
System.out.println(dell.getCORE()+"\n"+
dell.getGoodsName()+"\n"+
dell.getCPUStyle()+"\n"+
dell.getPrice()+"\n");
System.out.println(dell.Describle());
}
处理结果如下:
同样我们可以获取内容。实现功能。
之前有说过反射,会消耗内存,所以在能不进行使用的尽量不要使用。但是在软件架构的基础上需要频繁的扩展,不断的修改的时候,使用反射会大大节省开发成本,而且易于接受。
Debug测试,进行更深的了解。解释为什么从父类BaseComputer 强转到子类中,不会出现异常。
子类继承父类,父类转到子类中理所当然,当然不会异常。(鄙人之前的理解)
但是事实上不是这样的。
先看看下面这部分代码:
看看编译通过,但是执行中
java.lang.ClassCastException: 类转化异常ltd.xiamenwelivetechnologyco.mediaapplication.laptop.DellComputer cannot be cast to ltd.xiamenwelivetechnologyco.mediaapplication.laptop.HpComputer
at ltd.xiamenwelivetechnologyco.mediaapplication.ExampleUnitTest.main(ExampleUnitTest.java:28)
这个便无法进行转化。原因:
Debug如下:我们在ComputerFactory类中打上断点
因为我们传入的Class 是 DellComputer
所以实例化的也是DellComputer,对应baseComputer中的对象就是DellComputer
那么将父类强转为DellComouter就会正常,但是,当你转化为其他的类自然就会异常。
所以合理的强转是正常的。这个是需要注意的。
OK,这一部分问题整理到这了。待续。。。