`
gege_s
  • 浏览: 18101 次
  • 性别: Icon_minigender_1
  • 来自: 郑州
社区版块
存档分类
最新评论

树形结构之一 建立业务无关的结点类型

阅读更多

 

程序开发中经常会用到树型结构,如组织机构·菜单·角色(支持继承的角色)·分目录的参数管理。

 

下面是我的一段经历,来单位不久我被分配到一个客服平台开发的项目中,由一位‘资深’项目经理带着做,他已经有五到六年的工作经验

 

了,不过在后来的工作中发现,他这六年是ctrl+c,ctrl+v过来的。

 

切入正题,我负责的模块中有一个是知识库的建立与应用,它的需求是这样的,要有一个目录,目录里有子目录,共要求三级目录,目录下

 

面对应着的是一些业务知识点供客服人员查看。

 

之前我没有用过树型结构,在这个程序里他们有写好的树型结构的读取工具,我看了看,大致如下做法是在后台组织一个html,然后发送到

 

前台再用js工具进行格式化成树的模样,具体操作是读很多次数据库数据,如果有三级就先读取一级结点,然后读取二级结点,再读取三级

 

结点。采用的是深度优先的做法把数据读取出来,在读取的时候组装html。

 

我看了以后头很大,因为我想用他们现有的模式去做,心里会很不舒服:

他们的做法有很多不足

1.在组装树型结构的时候会查询多次数据库,而且随着结点数目的增长,查询次数也随之增长很多。

  2.不便于调试,有了问题很难发现。

3.不便于数据缓存。

4.增加网络流量。

5.针对一个js树型工具组装的html,如果换成其他的js工具几乎是不可能的。

6.代码没有可重用性,它把业务数据库与组装html混合在一起。

7.如果数据库数据出现循环引用,会在死循环里出不来,还有可能导致系统崩溃。

....

 

为了解决上述问题,我自己写了一个简单的树型结构加载工具,经历过数次的重构,在三个项目中使用。

 

 

定义一个结点类型:Node<T> 代码如下:

 

package com.**.power.tool.tree.node;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

public class Node<T> implements Serializable ,Comparable{
	private static final long serialVersionUID = -8658937456797684778L;
	private Node<T> parent;			//父结点
	private List<Node<T>> children;	//子结点
	private String id;				//结点编号
	private String text;			//结点标签
	private String parentId;		//父结点编号
	private int grade;				//结点级别 根结点为0
	private int subLevels;			//结点下面最深有多少层
	private boolean isexpand=false;	//结点展开状态
	
	public Node(){}
	public Node(T t) {
		this.extend=t;
	}
	//
	private T extend;	//扩展属性 用于扩展业务属性与指定的业务实体进行扩展
	//....这里省去get set方法
	@SuppressWarnings("unchecked")
	
	public boolean equals(Object obj) {
		if (obj == null) {
			return false;
		}
		if (super.equals(obj)) {
			return true;
		}
		if (!(obj instanceof Node)) {
			return false;
		}
		Node<T> target = (Node<T>) obj;
		if (target.getId() == null) {
			return false;
		}
		if (target.hashCode()==hashCode()) {
			return true;
		}
		return false;
	}

	@Override
	public int compareTo(Object o) {
		if (o instanceof Node ) {
			Node tmp=(Node) o;
			Object ext=tmp.getExtend();
			if (ext!=null&&this.getExtend()!=null) {
				if (ext instanceof Comparable&&this.getExtend() instanceof Comparable) {
					Comparable extcomp=(Comparable)this.extend;
					Comparable tmpcomp=(Comparable)tmp.getExtend();
					int i= tmpcomp.compareTo(extcomp);
					System.out.println(i);
					return i;
				}
			}
			
		}
		return 0;
	}
}

 

 

从注释上可以看出以下几点:

1.它是一个泛型类型

2.业务无关

3.有可扩展属性

4.实现了Comparable接口,从而实现对结点进行排序

这个从接口实现上可以看出,先去查看它的扩展属性是不是实现了Comparable,如果实现了就用扩展属性进行比较,如果没有实现,就不进行比较返回0,表示相等以免对结点不必要的移动。

5.它有grade级别和subLevels下面最多有多少层,以便判断是不是对该结点进行相关操作。

 

这篇博客到此吧,下次再说如果组装树型结构。

谢谢大家来捧场!!

欢迎留言讨论!

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics