首页 > 代码库 > 【优雅编程之道】之方法的9点建议

【优雅编程之道】之方法的9点建议

开心一笑

【一个去看演出的朋友回来了。
我问他:“怎么样演出好看吗?”
朋友:“人太多了,我去晚了,在后面什么也看不见,只能跳起来看几眼,
后来跳累了就不看了,也没有什么好看的。”
这时我另外一个朋友也回来了。
我:“你也看戏去了?”
另外一个朋友:“恩!”
我:“好不好看?”
另外一个朋友:“好看个屁!戏没看多少,就看见前面一个SB在那里跳来跳去的!”】

提出问题

项目中如何优雅编写方法???

技术分享

解决问题

取个好的方法名称

函数的名称皆是函数的用途。一个好的函数名称可以体现一个程序员的水平和素养。使用描述性的名字,函数名字:动/名词形式。

方法单一职权原则

这是个老话题了。对于函数,只应该做一件事情,把一件事情做好,而且只由它来做这一件事情。

返回值为null的罪恶

开发人员在写方法的返回值的,经常会返回 null 值,这个是系统报 NullPointerException 的罪恶之源。调用者不对 null 返回值方法进行判空,就会出现异常。况且,判空处理又会多出很多代码。所有,除非业务需要,不要让方法返回 null 值,切记。

例如:

程序清单 2-1

public List<Object> test(int size){

    if(size == 0){
        /*
        这里返回null值,是错误的,因为调用者,还需要判断这个null对象
        容易造成空指针异常
        */
        return null;
    }
}

正确做法:

程序清单 2-1

/**
 * @Author 阿毅
 * Created by Ay on 2016/01/21.
 */
public class Ay{

    private final List<Object> objects = new ArrayList<>();
    //定义final型的空数组
    private static final Object[] EMPTY_CHEESE_ARRAY = new Object[0];

    public Object[] test(int size){
        //返回空数组而不是null
        return objects.toArray(EMPTY_CHEESE_ARRAY);
    }

}

对于集合来说,可以通过返回Collections.emptySet,Collections.emptyList,Collections.emptyMap等等)

例如:

程序清单 2-1

//同样的对于集合(Collections.emptySet,emptyList,emptyMap等等)
public List<Object> test(String str){
    if(str.isEmpty()){
        //返回不可变的空集合,对于map
        return Collections.emptyList();
    }else{
        return new ArrayList<Object>();
    }

}

可能有人会认为:null返回值比零长度数组更好,因为它避免了分配数组所需要的开销。事实上是不比担忧的。数组的这点开销是不会有多大的影响的。

避免代码层级太深

一段代码的层级太深,一方面招人厌恶,另一方面也体现开发人员经验欠缺。例如:

程序清单 2-1

@Test
public void test(List<Object> objectList){
    Boolean flag = true;
    //代码层级:第一层 (不错)
    if(flag){
        //代码层级:第二层 (还行)
        if(flag){
            //代码层级:第三层 (没法接受)
            for(int i=0,len = objectList.size();i< len;i++){
                //代码层级:第四层 (逆天啊)
                if(flag){
                }
            }
        }
    }

}

解决方法:

程序清单 2-1    

if(!false) return;
    for(int i=0,len = objectList.size();i< len;i++){

}

学会使用逆向思维的方法,换个角度思考问题

避免方法过长

什么样的方法叫做过长呢?如果一个方法的长度用自己的电脑,一屏显示不完,需要滚动才能看完,那么这个方法就是过长。这是一个简单的判断标准。《代码整洁之道》特别强调方法的单一职权原则。就是一个方法只做一件事,也只能做一件事。

例如:

程序清单 2-1

if(){
    ..业务代码1
}else{
    ..业务代码2
}

for(int i=0;i<100;i++){
    ..业务代码3
}

解决方法:对于if和for中的代码,如果是处理业务代码,一般可以单独抽出一个或者多个方法,改成:

程序清单 2-1

if(){
    method1();
}else{
    method2();
}

for(int i=0;i<100;i++){
    method3();
}   

method1(){
    //业务代码1
}

method2(){
    //业务代码2
}

method3(){
    //业务代码3
}

避免过多的函数参数

先考虑下面例子:

程序清单 2-1

/**
 * 只做一件事
 * @param arg1  参数1
 */
public void onlyDoOneThing(String arg1){
    System.out.println("一个参数,不错!!!");
}

/**
 * 只做一件事
 * @param arg1  参数1
 * @param arg2  参数2
 */
public void onlyDoOneThing(String arg1,String arg2){
    System.out.println("两个参数,能接受和理解!!!");
}

/**
 * 只做一件事
 * @param arg1  参数1
 * @param arg2  参数2
 * @param arg3  参数3
 * @param arg4  参数4
 */
public void onlyDoOneThing(String arg1,String arg2,String arg3,String arg4){
    System.out.println("3个或3个以上的参数,没法接受!!!");
}

解决方法:

class XXX{
        private String arg1;
        private String arg2;
        private String arg3;
        private String arg4;
        //省略set get方法
}

/**
 * 只做一件事
 * @param XXX  参数1
 */
public void onlyDoOneThing(XXX args){
    System.out.println("3个或3个以上的参数,没法接受!!!");
}

当方法参数过多的时候,我们可以考虑用类来封装这些参数。同时,我们也要注意一点的是:方法参数过多,是否是因为单个方法处理的业务太多,是否可以考虑拆成多个方法等。

不可省略的@Override注解

如果在抽象类中对方法签名进行修改,其实现类会马上编译报错。所有使用@Override注解来覆盖超类声明,编译器就会替我们防止大量的编译错误。何乐而不为。具体实例如下:

程序清单 2-1

//子类
public class AyTest extends AlTest{
    @Override    
    void test(){}
}
//父类
class AlTest{
    void test(){}
}

保存紧密相关的函数,变量在一起

项目中的方法经常会调用其它方法,按照自顶向下的原则,我们应该保持保存紧密相关的函数,变量在一起。方便其他开发人员阅读。具体实例如下:

程序清单 2-1

public class AyTest{
    //error
    //public static final String NAME = "Ay";

    void test(){
        method();
    }

    // 1.method 方法应该紧挨着 test 方法
    // 2.Name应该写在method方法的上面
    public static final String NAME = "Ay";
    void method(){
        System.out.println("姓名:" + NAME);
    }
}

去掉接口中的public修饰符

虽然说洁癖不是一个很好的习惯,但是对于想成为大神级别的开发人员来说,洁癖确是一个好的品质,需要时刻培养。比如下面代码:

public interface AyTest {

    //错误写法:接口的public修饰符号不需要写
    public void test();

    public void test2();

    //-----------------------------------
    //正确写法
    void test();

    void test2();

}

在接口中,每个方法默认都是public。所以不需要public修饰符修饰。虽然加上public程序也能跑,但是记住:我们是走大神级别路线的,我们更别人不一样,我们是很优秀的。

读书感悟

来自罗伯特·穆齐尔《没有个性的人》

  • 一种爱情,它与插在心中的匕首共存。
  • 本性决定行为,本性取决于行为。
  • 今天每个人所迫切需求的莫过于简单、朴实、健康,也需要一个孩子,因为一个孩子就是把一个人牢牢栓在地上的东西。

经典故事

【有一位精神病学家,执业多年,获得了很大的成功,在精神病学界享有很高的声誉。他数年前将要退休时,发现在帮助自己改变生活方面最有用的老师,是他所谓的“四个小字”.头两个字是“要是”.他说:“我有许多病人,把时间都花在缅怀既往上,后悔当初该做而没有做的事,‘要是我在那次面试前准备得好一点……’或者‘要是我当初进了会计班……’”
  在懊悔的海洋里打滚是严重的精神消耗。矫正的方法很简单:只要在你的词汇里抹掉“要是”二字,改用“下次”二字即可。应该向自己说:“下次如有机会我应该如何做……”
  大道理:最浪费时间的莫过于懊悔。千万不要老是惦念已往的过错,当你又在后悔既往时便对自己说:“下次我不会再做错。”】

大神文章

【1】《Agile Java》
【2】《Java程序性能优化 让你的Java程序更快、更稳定》
【3】《Thinking in Java (Java编程思想)》
【4】《编写高质量代码:改善Java程序的151个建议》

其他

如果有带给你一丝丝小快乐,就让快乐继续传递下去,欢迎点赞、顶、欢迎留下宝贵的意见、多谢支持!

<script type="text/javascript"> $(function () { $(‘pre.prettyprint code‘).each(function () { var lines = $(this).text().split(‘\n‘).length; var $numbering = $(‘
    ‘).addClass(‘pre-numbering‘).hide(); $(this).addClass(‘has-numbering‘).parent().append($numbering); for (i = 1; i <= lines; i++) { $numbering.append($(‘
  • ‘).text(i)); }; $numbering.fadeIn(1700); }); }); </script>

    【优雅编程之道】之方法的9点建议