首先说这个项目的结构比较混乱,软件架构我还看得不是很清楚,但代码结构实在很混乱,程序员的水平实在不敢恭维,代码中竟然能出现“index_1”一直到index好几十的那种命名方式,faint!后来还要一直遵守这种命名方式,实在很无聊。。。
好了,我就说说我今天的收获。
首先是CheckboxTreeViewer的setSubtreeChecked(Object element, boolean state)方法引起的。代码如下:
底下代码没多大意思,看第一行的internalExpand方法。internalExpand主要是调用了internalGetWidgetToSelect方法,internalGetWidgetToSelect中又调用findItem方法,findItem又调用了findItems方法,跟进的调用了doFindItem方法,这里比较有趣,doFindItem是AbstractTreeViewer里实现的方法,接下来调用了internalFindItem,来看看:
下面for循环里递归调用没啥意思,主要看上面的
每一个Item都有一个data与之关联,因此那里才会调用getData,关键是下面那个equals方法,它是StruturedViewer的方法来看看:
代码就是有定义比较器,则用比较器比较,否则就用对象本身的equals!当时在这里终于查出了虫子在哪里。原来的程序员写的代码很ugly(重写了equals,但没有覆盖hashCode,之前可能没什么问题,但很多类库的东西是与这两个配合使用的,见Effective Java)。
由于系统本身的代码结构混乱,为了最大限度的避免对原来系统造成损害,我只好自定义了比较器,而不去改对象的equals方法。
这个项目据说之前做了7,8年了,我现在刚接手,我感觉之前的程序员水平实在很劣质。其实写代码是一种艺术活,不知道为什么大家写代码时都不动动脑子,好像能做出功能就很牛b(软件工程不是算法比赛,不是gcj,不是acm icpc,不是topcoder,没必要写代码好像赶时间似的,更何况时间也没赶上,东西做得也不好)。就像绝影说的,代码写的不好,会被后来的程序员骂,我以后写代码可不想被后面的程序员骂。尤其是做工具库的。。
可能本身这项目都属于二次开发的二次开发。。。的吧,可应用软件也不能这么写。。。
代码出来结构乱点有两种原因可以理解:
1.为了效率的考量,如linux内核一些地方,黑客们写的代码也不是就是乱,但很多地方就是看不懂,如果换成另外一种方式来写,可能就更好理解了,但内核那种级别,效率是最重要的。再如boss zhang 说百度基础库里的B+树代码结构也很混乱,但是人家比较稳定,这么多年了没人去改它,并且都建议不改。
2.为了某些考量。对应到具体的一些系统,有些考量比较特别,但这种特别的地方最后用代码注释或者文档写出来。但现在的项目时代码结构乱,而且注释也没有,有的话也是那种废话注释,关键的地方从不写注释,真不知道怎么想的。。。。
再者,我发现测试也很重要,可我发现公司的tester根本不会做测试,基本的流程分支测试都不会做,都是开发人员报了一个错误,然后在Bugzilla里登记一下,faint!看来真应该叫她好好看看BOP那本关于二分搜索测试的内容,测试其实还是很难的一种技术。另外,我觉得测试之后应该有test case表,但是很遗憾,也没有。。。。。
好了,我就说说我今天的收获。
首先是CheckboxTreeViewer的setSubtreeChecked(Object element, boolean state)方法引起的。代码如下:
public boolean setSubtreeChecked(Object element, boolean state) {
Widget widget = internalExpand(element, false);
if (widget instanceof TreeItem) {
TreeItem item = (TreeItem) widget;
item.setChecked(state);
setCheckedChildren(item, state);
return true;
}
return false;
}
底下代码没多大意思,看第一行的internalExpand方法。internalExpand主要是调用了internalGetWidgetToSelect方法,internalGetWidgetToSelect中又调用findItem方法,findItem又调用了findItems方法,跟进的调用了doFindItem方法,这里比较有趣,doFindItem是AbstractTreeViewer里实现的方法,接下来调用了internalFindItem,来看看:
private Widget internalFindItem(Item parent, Object element) {
// compare with node
Object data = parent.getData();
if (data != null) {
if (equals(data, element)) {
return parent;
}
}
// recurse over children
Item[] items = getChildren(parent);
for (int i = 0; i < items.length; i++) {
Item item = items[i];
Widget o = internalFindItem(item, element);
if (o != null) {
return o;
}
}
return null;
}
下面for循环里递归调用没啥意思,主要看上面的
// compare with node
Object data = parent.getData();
if (data != null) {
if (equals(data, element)) {
return parent;
}
}
每一个Item都有一个data与之关联,因此那里才会调用getData,关键是下面那个equals方法,它是StruturedViewer的方法来看看:
protected boolean equals(Object elementA, Object elementB) {
if (comparer == null) {
return elementA == null ? elementB == null : elementA.equals(elementB);
} else {
return elementA == null ? elementB == null : comparer.equals(elementA, elementB);
}
}
代码就是有定义比较器,则用比较器比较,否则就用对象本身的equals!当时在这里终于查出了虫子在哪里。原来的程序员写的代码很ugly(重写了equals,但没有覆盖hashCode,之前可能没什么问题,但很多类库的东西是与这两个配合使用的,见Effective Java)。
由于系统本身的代码结构混乱,为了最大限度的避免对原来系统造成损害,我只好自定义了比较器,而不去改对象的equals方法。
这个项目据说之前做了7,8年了,我现在刚接手,我感觉之前的程序员水平实在很劣质。其实写代码是一种艺术活,不知道为什么大家写代码时都不动动脑子,好像能做出功能就很牛b(软件工程不是算法比赛,不是gcj,不是acm icpc,不是topcoder,没必要写代码好像赶时间似的,更何况时间也没赶上,东西做得也不好)。就像绝影说的,代码写的不好,会被后来的程序员骂,我以后写代码可不想被后面的程序员骂。尤其是做工具库的。。
可能本身这项目都属于二次开发的二次开发。。。的吧,可应用软件也不能这么写。。。
代码出来结构乱点有两种原因可以理解:
1.为了效率的考量,如linux内核一些地方,黑客们写的代码也不是就是乱,但很多地方就是看不懂,如果换成另外一种方式来写,可能就更好理解了,但内核那种级别,效率是最重要的。再如boss zhang 说百度基础库里的B+树代码结构也很混乱,但是人家比较稳定,这么多年了没人去改它,并且都建议不改。
2.为了某些考量。对应到具体的一些系统,有些考量比较特别,但这种特别的地方最后用代码注释或者文档写出来。但现在的项目时代码结构乱,而且注释也没有,有的话也是那种废话注释,关键的地方从不写注释,真不知道怎么想的。。。。
再者,我发现测试也很重要,可我发现公司的tester根本不会做测试,基本的流程分支测试都不会做,都是开发人员报了一个错误,然后在Bugzilla里登记一下,faint!看来真应该叫她好好看看BOP那本关于二分搜索测试的内容,测试其实还是很难的一种技术。另外,我觉得测试之后应该有test case表,但是很遗憾,也没有。。。。。