实践中的重构18_不对称的美

一般而言,自然界是以对称为美的。但是,在编程的世界里面,不对称的情况比比皆是,一样的美。
常见的api中有如下例子:
    	// String的方法。
	public String substring(int beginIndex, int endIndex)
 	// List的方法。 
	List<E> subList(int fromIndex, int toIndex) 

这里一直遵循着不对称的左闭右开原则。
这种原则有2个显著的优点。
1 计算该范围所包含的数量时,直接endIndex-beginIndex就好了。如果是左闭右闭区间的话,则需要形如endIndex-beginIndex+1的方式来计算。
2 左闭右开区间有良好的叠加性。举个例子,一个[0,100)的范围,自然等于[ 0,10), [10,20),…,[90,100)的叠加。
了解了这种不对称的优点,那么我们设计接口的时候,应该尽量遵循左闭右开原则。
	/**
	 * 查找在一定时间范围内加入系统的用户。包含start时间点,不包含end时间点。
	 * */
	public List<User> findUser(Date start, Date end)

再看一个例子:
	public static final String FILE_SEPARATOR = File.separator;

	private String baseDir;

	public String getFileDir(String userId, String date) {
		String relativePath = getDateDir(date) + getUserDir(userId);
		return getBaseDir() + FILE_SEPARATOR + relativePath;
	}

	private String getUserDir(String userId) {
		return FILE_SEPARATOR + userId + FILE_SEPARATOR;
	}

	private String getDateDir(String date) {
		return date + FILE_SEPARATOR + date;
	}

	private String getBaseDir() {
		return baseDir;
	}

这段代码的功能是构建一个用户在特定日期的文件路径目录。该文件路径目录由三部分组成,baseDir是配置的根目录,日期目录是根据日期所得到的目录,用户目录是根据用户id得到的目录。
在写这段代码的过程中,很明显没有考虑separator和目录的关系,导致各个子目录风格不统一,每次使用类的方法时都要仔细的检查该目录是不是以separator结尾,以防出错。
很明显,使用不对称的原则可以很好的解决该问题,可以规定所有子目录都以separator开头,但是不以separator结尾。
重构后代码如下:
	public static final String FILE_SEPARATOR = File.separator;

	private String baseDir;

	public String getFileDir(String userId, String date) {
		return getBaseDir() + getDateDir(date) + getUserDir(userId);
	}

	private String getUserDir(String userId) {
		return FILE_SEPARATOR + userId;
	}

	private String getDateDir(String date) {
		return FILE_SEPARATOR + date + FILE_SEPARATOR + date;
	}

	private String getBaseDir() {
		return baseDir;
	}

当然,这里getFileDir没有了separator结尾,需要修改使用到该方法的地方。
做了该重构以后,所有子目录的格式变为统一的,方便记忆和使用,并且极大的简化了目录拼接问题,由于separator不对称的使用,现在目录的拼接只需要简单的使用子目录拼接即可,不用关心separator的问题了。

你可能感兴趣的:(编程)