您的位置:首页 > 编程语言

代码规范 : 高质量的子程序设计(函数)

2017-12-21 22:57 274 查看


(图侵删 玩笑脸)

子程序定义:为实现一个特定的目的而编写的一个可被调用的方法或过程。

创建子程序的正当理由

降低复杂度

引入中间、易懂的抽象

隐藏内部的实现细节

缩小代码规模

改善可维护性

提高正确性

改善性能

如果你的程序中有一个长长的函数,那么意味上面的你可能一条都不沾

低质量的子程序

差劲的子程序名字

没有文档

代码布局不好

子程序没有一个单一的目的

没有错误处理

使用神秘数据(没有意义的单纯数字)

参数过多

参数顺序混乱且未经注释

如何优化子程序

引入中间抽象: 子程序内部的逻辑抽象出来一个新的函数, 在原来的子程序中调用

public void doSometihing(){
// 将本来在函数内实现的逻辑抽象到别的函数中去
String name = getName();
...
}


支持子类化: 将原有的函数放到父类中, 使用继承就能使用父类中除私有外的函数,这样意外着子类中要构建的函数更少

// 在子类对象使用父类的方法, 这样你不用去构造一个一样的方法
public Class SonClass extends FatherClass{

}

public Class OrderClass{
public static final main(String [] arge){
SonClass son = new SonClass();
son.doSomething();
}
}


避免代码重复(这个不用说)

隐藏操作顺序: 将一个过程的操作顺序抽象出来,私有,只保留出入口, 让逻辑函数能将注意力放在目前要进行的业务处理上

// 原来的程序
public void doSometihing(){
...
InputStream inputStream=socket.getInputStream();
InputStreamReader inputStreamReader=new InputStreamReader(inputStream);
BufferedReader bufReader=new BufferedReader(inputStreamReader);
...

}

// 修改之后, 你完全在io 流程中 不用关心io流的写入, 专心做自己的逻辑控制
public void doSometihing(){
...
InputStream inputStream=socket.getInputStream();
BufferedReader bufReader = getBufferedReader (inputStream);
...

}

public BufferedReader  getBufferedReader (InputStream inputStream){
InputStreamReader inReader = new InputStreamReader(inputStream);
return new BufferedReader(inReader);
}


提高可移植性

可以使用子程序来隔离不可移植的部分。 让自己的代码适应在不同的环境(语言提供的非标准特型、对硬件和操作系统的依赖)下工作 。

简化控制流程判断

1 将判断抽象到别的函数中

2 使用一个具象的命名来表达

改善性能:

这样方便查出运行效率低下的代码,更容易给多个函数分别优化性能

隔离复杂度,限制变化带来的影响

隐藏全局数据

初始化返回值

在函数开头用一个默认值来初始化返回值,能够在未正确返回值时提供一张保护网

// 原来的代码
public void doSomeThing(){
String strCode = "";
strCode = getCode() == null ? strCode : getCode();
return strCode ;
}
// 修改初始值之后
public String getCode(){
String strCode = "FA0001";
strCode = getCode() == null ? strCode : getCode();
strCode = getCode
}


在子程序层上设计

目的

通过开头给出的子程序的定义,我们可以知道,子程序为了实现单一目的而生

内聚性:

指的是子程序中各个操作的紧密程度, 虽然在面向对象发展很多年的今天,更多人在编程时更讲究的是抽象和封装,但是内聚还是一直存在

功能内聚

最高级的内聚, 让子程序只执行一个操作

顺序上的内聚

比较次级的内聚, 需要按照特定的顺序进行操作,这些操作步骤需要共享数据,而且只有在全部执行完毕之后,才算完成一项完整的功能

通讯上的内聚

指的是子程序在不同的操作中使用了同种数据,但子程序之间没有联系

临时内聚

不同的功能需要同时执行才放到一起

过程上的内聚

指的是子程序中的操作是按特定的顺序执行

逻辑上的内聚

他们之间没有关联,只是在判断逻辑的时候放到一起

巧合内聚性

无内聚性,混乱内聚性

子程序的长度

60行之内 之前有做过说明,这里不做复述

如何使用子程序参数

按照输入-修改-输出的顺序排列参数

反例:随机、按字母顺序
正例:仅作为输入参数 à 既是输入又是输出的参数 à 仅作为输出的参数


考虑自己创建IN和OUT关键字

预处理定义IN和OUT(起说明性作用)

注释内描述

注意:

1、确保一致的使用该定义方法。

2、不要混淆IN和const的作用。

如果几个子程序都用了类似的一些参数,应该让这些参数的排列顺序保持一致

例:fprintf()/printf、fputs/puts、strncpy/memcpy。

使用所有的参数

往一个子程序中传递一个参数,就一定要使用这个参数。如果你不要它,请尽快把它从接口中删除。

把状态和出错变量放在参数表最后

它们只是附属于程序的主要功能,而且它们是仅用于输出的变量。

应该对哪些接口参数的假定说明(注释):

参数是仅用于输入的、要被修改的、还是仅用于输出的。

表示数量的参数的单位(英寸、英尺、米等)。

状态代码和错误值的含义。

接受的数值的范围。

不该出现的特定数值。

把子程序的参数个数限制在3个以内, 3个参数以上,考虑创建一个类来包裹参数

考虑对参数采用某种表示输入、修改、输出的命名规则

认为区分输入、修改、输出参数很重要的话,就建立一种命名规则来进行区分。

使用具名参数

确保实际参数和形式参数相匹配
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: