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

实践中的重构13_利用递归提高代码的可维护性

阅读更多
有这么一段代码,是用来解析国内的地址信息的。
AddressInfo对象唯一确定一个地址信息,该地址信息可以是省市区县任意一级的地址信息,省级地址为市级地址的父地址,市级地址是区县地址的父地址。AddressInfo对象里面存储了父地址的地址码,当地址码为null或者查找不到该地址码对应的地址时,认为该AddressInfo对象为省级地址。系统提供了查找一个地址码对应父地址的方法,。
	/**
	 * 获取省、市、区的数组
	 * 
	 * @param info
	 *            地址信息
	 * @return 3个元素的字符串数组 第一个表示省,第二个表示市,第三个表示区/县
	 */
	private String[] getAddressArrayByInfo(AddressInfo info) {

		int addessArrayLength = 3;
		int provincePosition = 0;
		int cityPosition = 1;
		int areaPosition = 2;

		String[] result = new String[addessArrayLength];
		if (info == null) {
			return result;
		}

		if (info.getParentAreaCode() == null) {
			result[provincePosition] = info.getName();
			return result;
		}

		AddressInfo parentInfo = findAddressByAreaCode(info.getParentAreaCode());
		if (parentInfo == null) {
			result[provincePosition] = info.getName();
			return result;
		}

		if (parentInfo.getParentAreaCode() == null) {
			result[provincePosition] = parentInfo.getName();
			result[cityPosition] = info.getName();
			return result;
		}

		AddressInfo provInfo = findAddressByAreaCode(parentInfo
				.getParentAreaCode());
		if (provInfo == null) {
			result[provincePosition] = parentInfo.getName();
			result[cityPosition] = info.getName();
			return result;
		}

		result[provincePosition] = provInfo.getName();
		result[cityPosition] = parentInfo.getName();
		result[areaPosition] = info.getName();
		return result;
	}

该段代码有以下问题可以改进。
1 代码命名不好。
2 结构有重复。
利用递归可以提高该段代码的可维护性。
	private static int AddressLength = 3;

	/**
	 * 获取省、市、区的数组
	 * 
	 * @param info
	 *            地址信息
	 * @return 3个元素的字符串数组 第一个表示省,第二个表示市,第三个表示区/县
	 */
	public String[] getAddressArrayByInfo2(AddressInfo info) {

		String[] addressArray = new String[AddressLength];

		addAddressToArray(addressArray, info);

		return addressArray;
	}

	/**
	 * 将指定地址放入addressArray中。 原有的addressArray的值依次后移1位,第一个空位由指定地址填充。
	 * 
	 * <pre>
	 * Note:由于中国的行政划分基本不会变,所以这里可以用常数。
	 * </pre>
	 * */
	private void addAddressToArray(String[] addressArray, AddressInfo info) {

		if (info == null)
			return;

		addressArray[2] = addressArray[1];
		addressArray[1] = addressArray[0];
		addressArray[0] = info.getName();

		String parentAreaCode = info.getParentAreaCode();
		if (parentAreaCode == null) {
			return;
		}

		addAddressToArray(addressArray, findAddressByAreaCode(parentAreaCode));
	}

因为这里的重复结构只有3层,递归的好处没有得到淋漓尽致的体现。尽管如此,这里采用递归以后减少了重复的代码,并且提高了代码的可维护性。
如果遇到同类问题,当层次较为多时,递归的优点就可以得到充分体现了。
但是值得注意的是,当使用递归时,固然可以提高程序的可读性,但是如果层次太多,有可能导致调用栈太深,从而消耗大量的内存空间,影响性能,甚至抛出栈空间不足异常,这种情况下可以考虑转换为迭代的形式或者尾递归的形式。
分享到:
评论
2 楼 william_ai 2011-01-06  
区域问题,可以用自定义编码的方式来做。
如省2位,市2位,区2位

设:
A1省01,B1市01,C1区01
A1省01,B2市02,C1区01
A1省01,B2市02,C2区02
A2省02,B1市01,C1区01

就可以得出以下编码
A1省        :010000
A1省B1市    :010100
A1省B1市C1区:010110
A1省B2市    :010200
A1省B2市C1区:010201
A1省B2市    :010200
A1省B2市C2区:010202
A2省        :020200
A2省B1市    :020201
A2省B1市C1区:020201

求A1省所有的所有市、区:找出编码大于010000小于等于019999的即可。


也可以用写sql来做。ORACLE的话可以直接写sql
select AREA_ID
  from AREA_TM
connect by prior AREA_ID = PARENT_AREA_ID
 start with AREA_ID = ?;
1 楼 抛出异常的爱 2011-01-06  
核心三件事:
		JXPathContext context = JXPathContext.newContext(info);
		String[] arry =  (String[]) IteratorUtils.toArray(it,String.class);
		String[] result = Arrays.copyOf(arry, 4);




测试代码:



import java.util.Iterator;

import org.apache.commons.collections.IteratorUtils;
import org.apache.commons.jxpath.JXPathContext;
import org.apache.commons.lang.ArrayUtils;

public class JxpathDemo {
	JxpathDemo father;
	String name;

	public JxpathDemo() {

	}
	public JxpathDemo(String name){
		this.name = name ;
	}
	public JxpathDemo getFather() {
		return father;
	}
	public void setFather(JxpathDemo father) {
		this.father = father;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		JxpathDemo son = new JxpathDemo("son diver the hose");
		JxpathDemo me = new JxpathDemo("i 'm a big man");
		JxpathDemo father = new JxpathDemo(" father in house");
		JxpathDemo grandFather = new JxpathDemo("grand fater sleepping");
		
		son.setFather(me);
//		me.setFather(father);
//		father.setFather(grandFather);
		JXPathContext context = JXPathContext.newContext(son);
		Iterator<String> it = context.iterate("//name");
		String[] arry =  (String[]) IteratorUtils.toArray(it,String.class);
		String[] result = Arrays.copyOf(arry, 4);
		
		for(String o:result)
		System.out.println(o)
	}


}


相关推荐

Global site tag (gtag.js) - Google Analytics