写一些体会,反射+泛型,减少耦合

javawsj 2016-12-21 02:15:59
博客不知道什么原因给封了,写在论坛里,各位大侠多多包涵,写一些总结
面向对象实现,假设有雇佣兵业务类Business,方法sharen(Gun g),武器类Gun,Gun中有方法sheji()。
本业务实现杀人动作,需要参数Gun一个
public class Business {
public void sharen(Gun g){
g.sheji();
System.out.println("一个人被干掉了");
}
}
武器类,这里不加属性了。
public class Gun {
public void sheji(){
System.out.println("M1911射击");
}
}

测试类
public class MyTest {
public static void main(String[] args) {
Business bs = new Business();
Gun g = new Gun();
bs.sharen(g);
}
}
OK,以上是一个标准的面向对象业务设计,可以完成业务,但只能固定运行,也就是说不能用其它武器射击了,那如果要能满足其它武器还能兼顾现在的武器,怎么办呢,这就要增加程序的可扩展性,面向接口编程(牛人说的),重新设计Gun成一个接口,如下
public interface Gun {
public abstract void sheji();
}

此时Business 的sharen方法,不变,测试中的Gun g = new Gun();,显然是不可能了,增加实现Gun的子类ShouQiang
public class ShouQiang implements Gun {
@Override
public void sheji() {
System.out.println("M1911射击");
}
}

测试类MyTest中,Gun g = new Gun();变成Gun g = new ShouQiang ();,运行效果与之前一样,此时,如果要换武器,那么业务类代码不变,重新编写一个BuQiang类,同样实现Gun接口
public class BuQiang implements Gun {
@Override
public void sheji() {
System.out.println("毛瑟98K开火");
}
}
业务类Business 不作任何变动
测试类MyTest中,Gun g = new ShouQiang ();,变成Gun g = new BuQiang ();,利用java多态,运行结果改变,部分实现了扩展性,此时,如果还需要其它武器,只要实现Gun接口,并在测试类中new 出新的实例,赋值给变量g就可以了


以上代码每变一次武器,main方法都要修改,修改就意味着重新编译,仅仅这样,怎么能满足呢,接下来让后来的类写在配置文件中,main方法读配置文件,配置文件写入要实现的类,在src目录增加myconfig.properties文件,文件内容:
wuqi=com.abc.BuQiang

测试类中,main方法增加如下代码:
Properties pro = new Properties();
pro.load(new FileInputStream("src/myconfig.properties"));
String s = pro.getProperty("wuqi");
g = (Gun)Class.forName(className).newInstance();
//仍然是传入参数,只不过对象来自反射,不再是new了
bs.sharen(g);

运行OK。
此时如果还有其它武器类,测试类中的代码就不用再修改了,比如:
public class JiGuanQiang implements Gun{
@Override
public void sheji() {
System.out.println("机关枪来了");
}
}
有了新的武器类,想要用新的武器对象传参,只需要修改myconfig.properties配置文件
wuqi=com.abc.JiGuanQiang
运行,OK,行为改变了,在此过程中,只增加了一个新的类,修改配置文件,其它类的代码不做任何修改,而文本文件的修改不用编译

尽管已经又抽象了一步,但,仍不能满足,想想,可不可以让这样的通用性,不仅仅满足Gun
MyTest作如下方法:
public static <T> T getNewObject(String key,Class<T> c) {
String className = pro.getProperty(key);
return (T)Class.forName(className).newInstance();
}
到这一步,如果能悟到,就真的涨姿势了














...全文
420 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
nikyotensai 2016-12-22
  • 打赏
  • 举报
回复
一会儿枪,一会人杀人,不被封才怪。换个比方呀!比如射箭,击中靶子
star19860411 2016-12-22
  • 打赏
  • 举报
回复
此楼接分,扛得住
爱睡觉的阿狸 2016-12-22
  • 打赏
  • 举报
回复
此楼4分即可
heiguiDeng 2016-12-22
  • 打赏
  • 举报
回复
最后一个没有提现这个反射+泛型的优势~~~~~ 我最近也在倒腾这个,我们公司我现在在看的一个泛型方法是这样的 对数据库执行SQL语句对象是一个List<Map>类型的集合。利用泛型加反射创造出一个公共方法在执行SQL语句后返回一个含有对象的list. 大概是这样 public <T> List<T> findList(Class<T> t ,sql){ } 这样写的话泛型的优势才出来 主要写在接口上执行各种通用方法
brooklyng60 2016-12-22
  • 打赏
  • 举报
回复
一直用的就是最后的方式进行研发。。。。。。。。。
ergg007 2016-12-21
  • 打赏
  • 举报
回复
话不多说,支持楼主,给分儿吧
qq_35100747 2016-12-21
  • 打赏
  • 举报
回复
楼主可以的 对新手很有帮助
qq_33792119 2016-12-21
  • 打赏
  • 举报
回复
感谢楼主的分享

81,090

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧