【优雅编程之道】之方法的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个建议》

其他

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

时间: 2024-11-05 14:48:07

【优雅编程之道】之方法的9点建议的相关文章

VC++编程之道读书笔记(2)

第三篇 技术细节 第七章:细说开发人员必知必会的39个开发细节 细节36:单例模式的应用 在开发程序时,往往需要在整个工程中只需要一个类的实例.而这个实例一旦被创建就不能被其他的实例再创建了,通常我们称这个实现过程为单例模式. 既然要保证类只有一个实例,那么就需要其他的类不能使用实例化该类.因此,需要将其构造方法设为私有的,即使用private关键字修饰.同时,类中提供一个静态方法,该方法的返回值是该类的一个实例.这样就只能使用该静态方法来获取类的实例了,从而保证了唯一性. 下面通过具体代码来实

Javascript异步编程的4种方法

转自 阮一峰 http://www.ruanyifeng.com/blog/2012/12/asynchronous%EF%BC%BFjavascript.html 作者: 阮一峰 日期: 2012年12月21日 你可能知道,Javascript语言的执行环境是"单线程"(single thread). 所谓"单线程",就是指一次只能完成一件任务.如果有多个任务,就必须排队,前面一个任务完成,再执行后面一个任务,以此类推. 这种模式的好处是实现起来比较简单,执行环境

Javascript教程:js异步编程的4种方法详述(转载)

文章收集转载于(阮一峰的网络日志) 你可能知道,Javascript语言的执行环境是“单线程”(single thread). 所谓“单线程”,就是指一次只能完成一件任务.如果有多个任务,就必须排队,前面一个任务完成,再执行后面一个任务,以此类推. 这种模式的好处是实现起来比较简单,执行环境相对单纯:坏处是只要有一个任务耗时很长,后面的任务都必须排队等着,会拖延整个程序的执行.常见的浏览器无响应(假死),往往就是因为某一段Javascript代码长时间运行(比如死循环),导致整个页面卡在这个地方

VC++编程之道读书笔记

第二篇 缪误21:位图数据是按照红绿蓝顺序存储的 大家都知道位图的颜色是由红.绿.蓝三个分量构成的,但是位图颜色数据存储的方式则不是按照这个顺序存储的,而是按照蓝.绿.红的顺序存储的.并且对于真彩色位图来说,位图的颜色数据是倒序存储的,即位图的第一行数据位于位图数据的最底部. 第三篇 细节12 :内存中的数组 在C++中通过数组可以操作内存,创建数组时需要为数组分配内存空间,操作数组时就是对内存空间中的数组元素进行操作.数组创建后,数组引用和数组元素分别存储在栈内存和堆内存中,并通过数组引用与数

C#脱离Halcon编程开发环境使用方法

在没有安装Halcon开发程序(HDevelop (SSE2))的电脑上面编程,使C#脱离Halcon编程开发环境使用方法,除了按照Halcon与编程环境必须要做的设置步骤外,还需要做如下两个工作: 1. 必须将halcon.dll  halcondotnet.dll   license 三个文件库复制到工程文件运行目录下,即(\bin\Debug目录下):(注:另外halcon.dll库文件也可以复制到C:\WINDOWS目录下) 2. 然后创建C:\Program Files\MVTec\h

C指针编程之道 ---第一次笔记

//==================C指针编程之道===========================// /////////////第一次笔记//////////////// * 表示该变量为指针变量,这也是指针变量的特性. int *pStu; //定义指针变量pStu, 并且pStu指向int类型变量 static int *pStu; //定义指针变量pStu, 并且pStu指向静态整形变量 char *pStu;   //pStu是一个指针变量 取地址符& 和 取值运算符 * 通

js面向对象编程:如何实现方法重载

js中如何实现方法重载?这涉及到三个问题 1同名函数的调用问题 2函数中特殊的参数arguments 3如何利用arguments实现方法重载 1同名函数的调用问题 都知道在js中如果存在多个名称相同的函数,则调用实际每次都只使用最后一个,js其实是没有重载的,也就是说,如果定义了多个同名的函数,单参数不一样,在调用时,js不管参数个数,只管前后顺序 例如: function test1(arg1) { alert("参数1:"+arg1); } function test1(arg1

iOS端JSON转Model链式编程框架SuperKVC使用方法与原理

背景 在client编程中.字典转模型是一个极为常见的问题,苹果提供了KVC来实现NSDictionary到Model的注入,可是KVC仅仅能进行单层浅注入.且无法处理类型转换.key与属性名不正确应.深度注入等问题,笔者从Masonry得到启示,开发了一个通过链式配置注入器实现深度注入.类型转换.key-属性名映射等功能的轻量级注入框架SuperKVC.眼下已经开源到GitHub,点击这里前往.欢迎Star和Fork.欢迎和我一起完好这个框架! 本文将从应用和原理两个角度介绍SuperKVC

好书推荐: 《Python 黑帽子:黑客与渗透测试编程之道 》

安全畅销书<Python灰帽子>同作者姊妹篇 知道创宇余弦.腾讯胡珀及Keen.蓝莲花等知名黑客战队联合作序盛赞 内容摘要: <Python 黑帽子:黑客与渗透测试编程之道>是畅销书<Python 灰帽子—黑客与逆向工程师的Python 编程之道>的姊妹篇,那本书一面市便占据计算机安全类书籍的头把交椅.<Python 黑帽子:黑客与渗透测试编程之道>由Immunity 公司的高级安全研究员Justin Seitz 精心撰写.作者根据自己在安全界,特别是渗透测