`
bmqnc
  • 浏览: 126039 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

CheckboxTreeViewer中判断节点的相同性的原理浅析

    博客分类:
  • java
阅读更多
首先说这个项目的结构比较混乱,软件架构我还看得不是很清楚,但代码结构实在很混乱,程序员的水平实在不敢恭维,代码中竟然能出现“index_1”一直到index好几十的那种命名方式,faint!后来还要一直遵守这种命名方式,实在很无聊。。。

好了,我就说说我今天的收获。

首先是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表,但是很遗憾,也没有。。。。。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics