论坛首页 Java企业应用论坛

实践中的重构01_一段代码的细调

浏览 5736 次
精华帖 (0) :: 良好帖 (3) :: 新手帖 (1) :: 隐藏帖 (0)
作者 正文
   发表时间:2010-08-02   最后修改:2010-12-04
重构的概念已经为广大的程序员所熟悉。但是还是有很多细节可以注意。
    public static String getHiddenEmail(String email, int prefix, int suffix) {
        // 仅对包含@的email账户进行处理
        if (StringUtil.isBlank(email) || !StringUtil.contains(email, "@")) {
            return email;
        }

        int length = email.length();

        if (length < DEFAULT_TOTAL) {
            return email;
        }
        // @所在位置
        int splitPos = StringUtil.lastIndexOf(email, '@');
        // @前的字符段
        String preEmail = StringUtil.substring(email, 0, splitPos);
        if (StringUtil.isBlank(preEmail)) {
            return email;
        }
        // @后的字符段,包含@
        String latEmail = StringUtil.substring(email, splitPos, length);
        if (StringUtil.isBlank(latEmail)) {
            return email;
        }
        if (preEmail.length() > 17)
            preEmail = StringUtil.abbreviate(preEmail, prefix);

        if (latEmail.length() > 13)
            latEmail = StringUtil.abbreviate(latEmail, suffix);

        return preEmail.concat(latEmail);
    }

以上的code在我看来,有以下几个缺点。
1 方法名和实际的方法体不匹配。
2 魔数
3 if (StringUtil.isBlank(latEmail)) 永远返回false,因为当程序执行到这里,latEmail至少包括一个字符@。
4 方法中的代码的内聚性不够。主要是对preEmail和latEmail的处理分开了。
5 拼写错误,应该为lastEmail而误拼为latEmail

清洗代码后如下
private static String getAbbreviatedEmail(String email, int prefix, int suffix) {

        if (StringUtil.isBlank(email)) {
            return email;
        }

        if (email.length() <= DEFAULT_TOTAL) {
            return email;
        }

        // @所在位置
        int splitPos = StringUtil.lastIndexOf(email, '@');
        if (splitPos == -1 || splitPos == 0|| splitPos == email.length() - 1) {
            return email;
        }

        // @前的字符段
        String preEmail = StringUtil.substring(email, 0, splitPos);
        if (preEmail.length() > DEFAULT_PREFIX_LENGTH) {
            preEmail = StringUtil.abbreviate(preEmail, prefix);
        }

        // @后的字符段,包含@
        String lastEmail = StringUtil.substring(email, splitPos, email.length());
        if (lastEmail.length() > DEFAULT_SUFFIX_LENGTH) {
            lastEmail = StringUtil.abbreviate(lastEmail , suffix);
        }

        return preEmail+lastEmail ;
    }


其实我个人最喜欢的风格是简单的方法的guard condition不用大括号{},这样代码变为

private static String getAbbreviatedEmail(String email, int prefix, int suffix) {

        if (StringUtil.isBlank(email)) 
            return email;

        if (email.length() <= DEFAULT_TOTAL) 
            return email;

        // @所在位置
        int splitPos = StringUtil.lastIndexOf(email, '@');
        if (splitPos == -1 || splitPos == 0|| splitPos == email.length() - 1) 
            return email;

        // @前的字符段
        String preEmail = StringUtil.substring(email, 0, splitPos);
        if (preEmail.length() > DEFAULT_PREFIX_LENGTH) {
            preEmail = StringUtil.abbreviate(preEmail, prefix);
        }

        // @后的字符段,包含@
        String lastEmail = StringUtil.substring(email, splitPos, email.length());
        if (lastEmail.length() > DEFAULT_SUFFIX_LENGTH) {
            lastEmail = StringUtil.abbreviate(lastEmail , suffix);
        }

        return preEmail+lastEmail ;
    }


谢谢论坛上朋友的讨论,preEmail+latEmail这个地方用+号比用concat方法好。
   发表时间:2010-08-02  
感谢lz,我最近也在重构那本书,感觉还是在日常生活中多积累比较好。
0 请登录后投票
   发表时间:2010-08-02  
恩 重构的书不错 不过更应该看重的是重构的精神 然后在以后的代码里面 一遍一遍的搞 直到自己可以满意
0 请登录后投票
   发表时间:2010-08-03  
可否举个更加复杂的重构例子
0 请登录后投票
   发表时间:2010-08-03  
snow8261 写道
可否举个更加复杂的重构例子

这个是个好想法 但是得慢慢来 复杂的你可以看我的blog的CodeLineCounter,那个是一步一步进化而来。
而且最近又在重构。
这个系列主要记录一些平时遇到的小问题的重构,一般是维护其他人的代码的时候的一些小例子。
0 请登录后投票
   发表时间:2010-08-03  
还可以再精简一下。
if (splitPos == -1 || splitPos == 0) {   

改为
if (splitPos < 1) {   
0 请登录后投票
   发表时间:2010-08-03  
liyun_1981 写道
还可以再精简一下。
if (splitPos == -1 || splitPos == 0) {   

改为
if (splitPos < 1) {   


这样代码行数是少了 但是代码的含义变得不是很清晰
0 请登录后投票
   发表时间:2010-08-03  
liyun_1981 写道
还可以再精简一下。
if (splitPos == -1 || splitPos == 0) {   

改为
if (splitPos < 1) {   


这样改将会出现问题。 splitPos == -1 || aplitPos == 0 不能用splitpos <1来表示。你改变它的作用范围。
0 请登录后投票
   发表时间:2010-08-03   最后修改:2010-08-03
zhang_xzhi_xjtu 写道


其实我个人最喜欢的风格是简单的方法的guard condition不用大括号{},这样代码变为

private static String getAbbreviatedEmail(String email, int prefix, int suffix) {

        if (StringUtil.isBlank(email)) //1
            return email;

        if (email.length() <= DEFAULT_TOTAL) //2
            return email;

        // @所在位置
        int splitPos = StringUtil.lastIndexOf(email, '@');
        if (splitPos == -1 || splitPos == 0) //3
            return email;

        // @前的字符段
        String preEmail = StringUtil.substring(email, 0, splitPos);
        if (preEmail.length() > DEFAULT_PREFIX_LENGTH) {//4
            preEmail = StringUtil.abbreviate(preEmail, prefix);
        }

        // @后的字符段,包含@
        String lastEmail = StringUtil.substring(email, splitPos, email.length());
        if (lastEmail.length() > DEFAULT_SUFFIX_LENGTH) {//5
            lastEmail = StringUtil.abbreviate(latEmail, suffix);
        }

        return preEmail.concat(latEmail);
    }


正则式可以干掉1 ,3 ,多个@ , @在开头 状况 
2 与 4,5 逻辑重叠
如果不是重构.
可以问一下美工到底是要什么效果
去掉其中的一些逻辑.

preEmail变换....与lastEmail变换最好不要把自己变更

还有就是返回值 return preEmail+latEmail;
就可以了看的明白更重要一些.

看一下能否用上.
StringBuilder buffer = StringBuilder();
String[] emailarry = StringUtil.split(email,"@");
int[] keys = {DEFAULT_PREFIX_LENGTH,DEFAULT_SUFFIX_LENGTH};
for(int i = 0 ; i < emailarry.length ; i++){
   ...............
}

0 请登录后投票
   发表时间:2010-08-03  
没感觉重构完之后有什么不同
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics