网站LOGO
博客 | 棋の小站
页面加载中
12月6日
达尔达尼亚瀑布,博洛尼亚,意大利 ...
网站LOGO 博客 | 棋の小站
记录学习,心得,状态,生活。
菜单
  • 热评
    用户的头像
    首次访问
    上次留言
    累计留言
    我的等级
    我的角色
    打赏二维码
    打赏博主
    程序员如何编写高质量代码呢
    点击复制本页地址
    微信扫一扫
    文章二维码
    文章图片 文章标题
    创建时间
  • 一 言
    确认删除此评论么? 确认
  • 本弹窗介绍内容来自,本网站不对其中内容负责。
    按住ctrl可打开默认菜单

    程序员如何编写高质量代码呢

    · 原创 ·
    技术分享 · 实用教程
    共 10476 字 · 约 14 分钟 · 477

    前言

    不想看前言直接翻过这里看第二个二级标题。

    在正式向大家分享我个人的代码编写风格时,我还是一如既往地想聊聊我为什么想写这篇文章,因为我都是想写什么就写什么。这篇文章的想法缘起于一篇微信公众号的文章:《你见过哪些奇趣的代码注释》,其中的回答三,让我感觉很搞笑。

    微信公众号文章中的回答三微信公众号文章中的回答三

    这个图片中的文字让我联想到了变量名命名,我想起来了我们同班的同学在写项目时那些奇奇怪怪的命名。然后我在浏览哔哩哔哩时又看到了下面一个视频:

    这个视频的后半段就是描述实际开发时有些人会花大量时间查阅程序运行时的错误。实际上除了这个,还有些人在配置环境上查阅大量资料,花费大量时间。

    然后我就随便点了个相关视频看看,是关于“新手程序员是怎样写代码的”,里面都是用调侃的语气形容烂代码都是什么样的。最让我感觉很气的就是成堆嵌套的if,就类似于下面的代码:

    python 代码:
    ...
    
    if xx == 'a':
        if xx == 'b':
        ...  # 省略十几个按此方式嵌套的if
    
    ...

    接着就是再看微信公众号,有一个教你如何写烂代码的,说的都是反话,具体可以点我

    之前我也出了个文章,是关于PEP8代码规范的,我也一直遵守这个规范,写出的代码简洁明了可读性非常高,和Python没有多余符号的特性很配合。这也是我如此喜欢Python语言的原因。

    正文

    接下来我就分享一些我个人的代码风格,这是我长期编写程序以来形成的编程习惯,适用于面向对象编程的语言。其实这个话题是有一个专门的概念的,叫设计模式。我没有专门学习设计模式,但是我从阅读大量代码,以及自己编写了大量项目后,已经形成了自己编写代码的一套习惯。下面的设计模式都是最适合我自己的,各位也可以专门学习设计模式,肯定比我讲的要好。

    项目开发流程

    首先先谈一谈项目开发流程。我用Java语言写过很多项目,就是在博客建立之前,程序源码也删了,但是那种思想一直刻在我的脑海里。拿我以前做过的一个面向教师、校长和同学的三方通知系统,当时只有我一个人开发这个项目,使用的是Java的Swing。我的开发流程是这样的,也是我一直以来自认为最正确的编写大型项目的开发顺序。

    首先就是确定数据库结构。就用前面开发的三方通知系统来说,程序中很多功能都与数据库互动有关。一旦数据库的结构有变,比如字段改变名字了,程序中所有涉及到字段名称的部分都要改变,项目越大越难以改变。而且数据库结构的设计也很重要,你要有良好的数据库知识,要:a.熟悉数据库如何建立能够节省内存空间、b.如何最大化平衡改变表数据和查询表数据之间的关系、c.如何确保数据是合法和安全的,d.以及如何简化查询语句。a和b对于项目是次要的,若项目的数据量不大,这点优化不会对整体存储空间和查询速度影响太多。对于a,具体体现在数据类型、数据长度、数据约束上。如人类的年龄,可以用tinyint类型而不是用int类型;如具体住址,用varchar(50)而不是varchar(1024)。b指查询表和修改表数据的速度,二者不可兼得。拿MySQL的索引来说,MySQL的索引可以优化表查询速度,而插入、更改和删除的速度会被索引拖慢。对于频繁更新表结构的情况,索引就要优先考虑加在查询频率最高的字段上,那这又要思考哪些字段会被频繁查询。对于经常查询表的情况,则要考虑如何为表的哪些字段添加索引,是添加单列索引还是组合索引。c则可以通过数据完整性约束和程序检查功能确保;d则可以通过使用存储过程和存储函数简化。设计完数据库后就是编写DAO,即数据库帮手类,一般封装常用的数据库操作方法,可以针对项目需求合理定制。

    对于功能的实现,则有两种方式:a.边设计界面边实现功能,b.先设计页面再设计功能。我个人喜欢a。我是一个个人开发者,对于我来说,我做项目时并没有事先计划功能有哪些,都是想到什么做什么,我在生活中做事也不事先计划,都是想到什么做什么。还是引用前面通知系统的例子,比如我要为教师用户开发功能,我会先设计大体的界面,排放按钮、面板、标签等内容的位置,调整到大小合适、位置合适后就开始开发功能。在我开发这个项目的教师功能时,学生用户和校长用户已经完成了,我设计教师用户的功能和其他用户一致,都是先设计界面。在这个项目中就是先放置菜单栏、通知面板,以及管理学生的按钮、管理自己用户的按钮和管理通知的按钮。在设计完页面后就是设计功能。我会从简入繁设计,先设计最简单的功能,即发送通知的功能,然后再设计管理通知、管理学生等功能,其中学生信息都是用表格处理的,这部分最难。

    最后就是完善功能并进行完整测试,包括各种极端情况的测试,以确保我编写的系统没有任何漏洞。

    程序设计规范——Java

    我自己在长期编写项目的经历中,逐渐形成了一套最适合自己的程序编写规范,今天将它分享给大家。有些规范是业界标准,有些则是我的个人习惯。我的Java标准和Python标准不一致,因此分成两部分编写。

    1. 项目结构

    项目结构指各个文件、文件夹从项目的跟文件夹中如何排列或包含。项目结构要符合以下要求:

    • 相同用途的文件或文件夹放在一个文件夹中,用途不同但并列的放在同一父文件夹中,否则放在不同文件夹中;
    • 各个文件的用途要明确,要独立,要方便外部使用或调用。

    良好的项目结构会让文件的寻找更简易,在代码的导入语句中体现最明显。

    正确的项目结构示例正确的项目结构示例
    1. 标识符命名方式

    标识符命名使用“驼峰命名法”。大多数标识符中都不包含任何符号,且所有单词都用全拼。每个单词都要有自己的含义,且使用英文单词,而不是使用英文首字母、汉语拼音。

    • 变量和方法:所有单词都是小写,且从第二个单词开始,后面的所有单词首字母都大写。如personId(人员编号),teacherFirstName(老师的姓),updateTeacherNumber(int newTeacherNumber)(更新教师数目),updateTeacherInfo(int teacherId, Teacher teacher)(更新教师信息)。
    • 类名:所有单词都是小写,且所有单词的首字母都是大写。如StudentList(学生列表),CustomDatabaseHelper(自定义数据库帮手类。
    • 常量:所有单词都是大写,单词与单词之间用下画线隔开。如DB_PASSWORD(数据库密码)。
    1. 文件中的代码

    首先是代码块的顺序。代码块指具有相同功能的一系列代码集。Java中代码块的顺序从上到下排列如下:

    • 包名。
    • 导入语句。
    • 类声明。

      • 常量。
      • 成员变量。
      • 静态方法。
      • 成员方法。
      • 主方法。
      • 内部类。

    在同一个方法中,不同的代码块之间用一行空格隔开。其他代码块也是一行。例:

    java 代码:
    package users;
    
    import db.DbHandler;
    import frames.TeacherFrame;
    
    public class Teacher {
        private final TeacherFrame teacherFrame = new TeacherFrame(this);
        private int teacherId;
        // ...
        private Teacher(int id, String name, int age){
            this.teacherId = id;
            // ...
        }
        
        static class Notification{
            // ...
        }
    
        public static void main(String[] args) {
            Teacher teacher =  new Teacher(1, "小王", 18);
            System.out.println(teacher.print());
        }
    }

    其次是类、变量和方法的关键字修饰。final用于限定常量、修饰不可被重写的方法和修饰不可被继承的类;static用于修饰静态变量或静态方法等。还有private修饰成员变量并用setter方法设定,用getter方法获取。

    还需要注意的还有:尽量少用循环,减少循环和判断的嵌套,对于常用的、相同的代码块,封装成该类的静态方法,对于需要在不同类中多次使用的相同代码块,则封装在util中。

    1. 注释

    尽量多用行注释,少用块注释。对于方法的封装,注释存在的目的是要让调用者明白此方法是干嘛的,所以注释要写这个方法是干嘛的,接受什么参数,参数有什么意义,返回值是什么,有什么意义。对于复杂的算法,每一步注释要说明该行有什么作用,比如声明辅助数组,用于存储中间值,而不是简简单单写该代码做了什么,如int newNum = oldNum + addNum的注释不要写相加oldNum和addNum,而要写声明一个新数量,值为旧数量加上更新的数量,作为更新方法的返回值。

    感兴趣的可以看看JDK的源文件,这里给出一张截图。

    JDK8中Optional类的of方法描述JDK8中Optional类的of方法描述

    Python程序设计规范——Python

    Python规范中,项目结构、项目编写顺序,参照上部分。

    1. 标识符命名

    Python的标识符要尽量短小,对于长的单词,则在尽可能保证可读性的情况下使用缩写,如规则描述,可以写成“rule_desc”。Python的很多包导入就用了缩写,比如数据科学常用的Pandas和Numpy分别缩写为“pd”和“np”。

    Python的标识符采用下列规则:

    • 类名:每个单词的首字母大写,剩下全小写。
    • 方法名:单词之间无分隔,全小写,第二个单词开始可以首字母大写。
    • 变量名:全小写,不同单词之间使用下画线隔开。
    • 常量:全大写,不同单词之间使用下画线隔开。
    • 与关键字相冲突的标识符,可以在最后添加下画线。
    • 尽量不要与内置变量相冲突。
    1. 文件中的代码

    和Java类似,Python的文件中代码块从上而下顺序如下:

    • 导入语句。

      • import ...
      • from ... import ...
    • 全局变量声明和在类外执行的代码。
    • 类名声明。

      • 定义变量。
      • 定义方法,__init__方法位于第一个。
    • if __name__ == '__main__'部分。

    例:

    python 代码:
    from re import findall
    import re
    
    website = 'QI1.ZONE'
    strings = re.split(r'\.', website)
    print(f'前缀:{strings[0]}', f'后缀:{strings[1]}')
    matches = findall(r'[A-Za-z]*', website)
    print(fr'是纯字母的的字符串:{matches}')
    
    class MyClass(object):
        def __init__(self):
            ...
    
        def __repr__(self):
            return f"<'MyClass' object at {self.__hash__()} created by qi1>"
    
    if __name__ == '__main__':
        print(MyClass())

    其他关于Python代码规范的我单独出了一篇文章,更多请参考此文章。

    PEP8,Python开发的美工指导员
    学学编程 401 头像

    其他资料中的代码编写指南

    我在网上找了一些说的很有道理,我高度认可的高质量代码指南,来补充我遗漏的地方。

    第一个

    原文:【如何写出高质量的代码? - CSDN App】http://t.csdnimg.cn/uH8yf

    在软件开发行业,代码是业务逻辑的核心表达形式。因此,编写高质量代码是每个开发人员的责任。然而,即使是经验丰富的程序员,也会犯一些常见的错误,这会导致难以维护、难以修改和未实现预期功能等问题。幸运的是,有一些简单的实践和原则,可以帮助开发人员编写高质量的代码。以下是一些写高质量代码的技巧:

    1. 代码应当清晰易懂

    好的代码应该是简洁明了的,不漏代码说明,在不受影响的情况下能够去掉多余的代码行。变量命名清晰明了,不能过短也不能过长,应该具有可读性。注释应该清晰明了,仅当必要时添加。代码的结构应该易于理解,应该按照时间顺序编写。

    1. 代码应该可读性强

    代码的阅读应该是易于理解的。变量名应该具有自我描述性,并且应使用自然语言编写。在编写方法和函数时,应该仔细考虑参数和返回值的类型,并为它们编写自描述性的名称。

    1. 代码应该是可维护的

    好的代码应该是可维护的代码。这意味着代码应该是可修改的,易于定位和解决来自任何类别的问题。为了实现这个目标,应该按照良好文件夹和项目结构严格组织代码。使用版本控制等工具使代码管理易于扩展。

    1. 添加适当的注释

    在编写代码时,注释是一个非常重要的组成部分。它们可以为代码的实现提供支持,解释代码的意图和要求。因此,努力为代码添加适当的注释,应该是一个开发人员的程序编写策略。

    1. 切勿忘记单元测试

    单元测试是帮助开发人员编写高质量代码的非常重要的工具。单元测试可确保代码的正确性,并确保多个代码模块之间的协作达到预期结果。因此,在编写代码之前,应始终编写完善的单元测试,并在代码更改后运行该测试来确保代码仍符合预期结果。

    1. 避免重复代码

    代码复制和粘贴可以造成非常严重的问题。重复代码容易导致代码的不一致性和错误。为了避免这种问题,应在整个项目范围内共享代码,并将代码封装在可重用的函数和类中。

    1. 参考和遵循编码指南

    在开发过程中,参考编码指南非常重要。这种指南包含了正确的代码实践,帮助开发人员尽可能地使用最佳的编码实践,避免犯常见错误。使用好的编码指南可以提高代码的质量,帮助开发人员遵循相关规范。

    总而言之,编写高质量代码是软件开发的关键。遵循上述方法并努力实践它们,开发人员将编写出清晰、可读、具有可维护性和未来可扩展性的代码。

    第二个

    原文:【常见优秀代码汇总 - CSDN App】http://t.csdnimg.cn/Vmvzh

    1. 语义简单明确

    写代码时考虑读者,优先采取易于读者理解的写法。

    1. 简洁≠代码短,复杂的问号表达式反而不如 if..else 方便理解。
    2. 提前返回错误

    提前返错能减少主体逻辑的缩进数量,让主体代码逻辑显得更醒目。

    1. 利用析构函数做清理工作(针对C++)

    利用 C++ 析构函数做清理工作,在复杂冗长代码中不会漏掉。典型的清理工作有执行回调、关闭文件、释放内存等。

    1. 用朴素直观的算法

    在非关键路径上,优先使用朴素直观的算法,此时代码可维护性更重要。

    6.用轮循代替条件变量

    在非关键路径上使用简单的轮循代替精巧的条件变量同步,代码简洁且不容易出 bug。

    1. 避免有歧义的函数名和参数表

    函数名和参数表要符合直觉,大多数使用者没空读你的注释,小部分使用者读了你的注释也看不明白。

    第三个

    原文:【如何编写出优秀的代码 - CSDN App】http://t.csdnimg.cn/Q0LZa

    【规则 1】用 #include <filename.h> 格式来引用标准库的头文件(编译器将从标准库目录开始搜索)。

    【规则 2】用 #include “filename.h” 格式来引用非标准库的头文件(编译器将从用户的工作目录开始搜索)

    【规则 3】在每个类声明之后、每个函数定义结束之后都要加空行。

    c 代码:
    // 空行 
    void Function1(…) 
    { 
     … 
    } 
    // 空行 
    void Function2(…) 
    { 
     … 
    } 
    // 空行 
    void Function3(…) 
    { 
     … 
    }

    【规则 4】在一个函数体内,逻揖上密切相关的语句之间不加空行,其它地方应加空行分隔。

    c 代码:
    // 空行
    while (condition) 
    { 
      statement1; 
    // 空行
    if (condition) 
    { 
     statement2; 
    } 
    else 
    { 
     statement3; 
    } 
    // 空行
     statement4; 
    }

    【规则 5】一行代码只做一件事情,如只定义一个变量,或只写一条语句。这样的代码容易阅读,并且方便于写注释。

    【规则 6】if、for、while、do 等语句自占一行,执行语句不得紧跟其后。不论执行语句有多少都要加{}。这样可以防止书写失误。

    【规则 7】关键字之后至少要留一个空格,否则无法辨析关键字。像 if、for、while 等关键字之后应留一个空格再跟左括号‘( ’ ,以突出关键字。

    【规则 8】函数名之后不要留空格,紧跟左括号‘( ’ ,以与关键字区别。

    【规则 9】‘,’之后要留空格,如 Function(x, y, z)。如果‘;’不是一行的结束符号,其后要留空格。

    【规则 10】赋值操作符、比较操作符、算术操作符、逻辑操作符、位域操作符,等二元操作符的前后应当加空格。

    【规则 11】一元操作符前后不加空格。

    【规则 12】象"[]"、 “.” 、“->”这类操作符前后不加空格。

    【规则 13】程序的分界符‘{’和‘}’应独占一行并且位于同一列,同时与引用它们的语句左对齐。

    【规则 14】之内的代码块在‘ { ’右边数格处左对齐。

    【规则 15】代码行最大长度宜控制在 70 至 80 个字符以内。代码行不要过长,否则眼睛看不过来,也不便于打印。

    【规则 16】长表达式要在低优先级操作符处拆分成新行,操作符放在新行之首(以便突出操作符)。拆分出的新行要进行适当的缩进,使排版整齐,语句可读。

    【规则 17】应当将修饰符 * 和 & 紧靠变量名。

    【规则 18】注释是对代码的“提示”,而不是文档。程序中的注释不可喧宾夺主,注释太多了会让人眼花缭乱。注释的花样要少。

    【规则 19】如果代码本来就是清楚的,则不必加注释。否则多此一举,令人厌烦。

    【规则 20】边写代码边注释,修改代码同时修改相应的注释,以保证注释与代码的一致性。不再有用的注释要删除。

    【规则 21】注释应当准确、易懂,防止注释有二义性。错误的注释不但无益反而有害。

    【规则 22】尽量避免在注释中使用缩写,特别是不常用缩写。

    【规则 23】注释的位置应与被描述的代码相邻,可以放在代码的上方或右方,不可放在下方。

    【规则 24】当代码比较长,特别是有多重嵌套时,应当在一些段落的结束处加注释,便于阅读。

    【规则 25】标识符最好采用英文单词或其组合,便于记忆和阅读。

    【规则 26】标识符的长度应当符合“min-length && max-info rmation”原则。

    一般来说,长名字能更好地表达含义,所以函数名、变量名、类名长达十几个字符不足为怪。那么名字是否越长约好?不见得! 例如变量名 maxval 就比 maxValueUntilOverflow好用。单字符的名字也是有用的,常见的如 i,j,k,m,n,x,y,z 等,它们通常可用作函数内的局部变量。

    【规则 27】命名规则尽量与所采用的操作系统或开发工具的风格保持一致。

    例如 Windows 应用程序的标识符通常采用“大小写”混排的方式,如 AddChild。而 Unix 应用程序的标识符通常采用“小写加下划线”的方式,如 add_child。别把这两高质量 C++/C 编程指南,v 1.0 2001 Page 23 of 101类风格混在一起用。

    【规则 28】程序中不要出现仅靠大小写区分的相似的标识符。

    【规则 29】程序中不要出现标识符完全相同的局部变量和全局变量,尽管两者的作用域不同而不会发生语法错误,但会使人误解。

    【规则 30】变量的名字应当使用“名词”或者“形容词+名词”

    【规则 31】全局函数的名字应当使用“动词”或者“动词+名词”(动宾词组)。类的成员函数应当只使用“动词”,被省略掉的名词就是对象本身。

    【规则 32】用正确的反义词组命名具有互斥意义的变量或相反动作的函数。

    int minValue; 
    int maxValue; 
    int SetValue(…); 
    int GetValue(…);

    优秀的代码格式

    我找了一些源码,筛选出一些我满意的代码格式,和不满意的代码格式,大家可以参考一下。

    规整导入顺序规整导入顺序对于重复的代码,单独封装成方法或装饰器,以及多使用行注释对于重复的代码,单独封装成方法或装饰器,以及多使用行注释常量使用全大写字母加下画线隔开常量使用全大写字母加下画线隔开类中各标识符的声明顺序类中各标识符的声明顺序少用嵌套控制和判断少用嵌套控制和判断

    不好的代码格式

    嵌套太深,缩进太多嵌套太深,缩进太多嵌套太深,缩进太多嵌套太深,缩进太多使用中文命名使用中文命名将很长的代码写在一行将很长的代码写在一行缩进非常混乱缩进非常混乱
    声明:本文由 (博主)原创,依据 CC-BY-NC-SA 4.0 许可协议 授权,转载请注明出处。

    还没有人喜爱这篇文章呢

    现在已有

    4

    条评论
    发一条!
    1. 头像
      云晓晨
      • 等级:Lv.5
      • 角色:首页 · 好友
      • 在线:本周

      还是喜欢规范代码滴,至少我自己看的时候,能快速看懂

      · · · 山东-济南
      1. 头像
        云晓晨

        嗯呢,规范的代码看起来很舒服

        · · · 河北-秦皇岛
    2. 头像
      TeacherDu
      • 等级:Lv.5
      • 角色:首页 · 好友
      • 在线:本周

      有那种代码格式化工具!

      · · · 海外
      1. 头像
        TeacherDu

        常见的IDE都有格式化功能

        · · · 海外
    博客logo 博客 | 棋の小站 记录学习,心得,状态,生活。
    ICP 冀ICP备2023007665号 ICP 冀公网安备 13030202003453号

    🕛

    本站已运行 221 天 14 小时 17 分

    👁️

    今日访问量:219 昨日访问量:2564

    🌳

    建站:Typecho 主题:MyLife
    博客 | 棋の小站. © 2023 ~ 2023.
    网站logo

    博客 | 棋の小站 记录学习,心得,状态,生活。
     
     
     
     
    壁纸