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

这里写图片描述
(图侵删 玩笑脸)

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

创建子程序的正当理由

  • 降低复杂度
  • 引入中间、易懂的抽象
  • 隐藏内部的实现细节
  • 缩小代码规模
  • 改善可维护性
  • 提高正确性
  • 改善性能

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


低质量的子程序

差劲的子程序名字
没有文档
代码布局不好
子程序没有一个单一的目的
没有错误处理
使用神秘数据(没有意义的单纯数字)
参数过多
参数顺序混乱且未经注释

如何优化子程序

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

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个参数以上,考虑创建一个类来包裹参数

  • 考虑对参数采用某种表示输入、修改、输出的命名规则
    认为区分输入、修改、输出参数很重要的话,就建立一种命名规则来进行区分。
  • 使用具名参数

  • 确保实际参数和形式参数相匹配


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值