当前课程知识点:软件工程 > 第2章 编写高质量代码 > 2.1 编程过程与规范 > 讲课视频
软件工程师对软件开发的成败
起着至关重要的作用
因此 提升自己的编程能力
是每一个软件工程师
应该修炼的基本功
编写优雅的程序
漂亮完美地解决问题
实现用户需求
也是每一个工程师
永远的追求
编程是一门艺术
它能够展示结构之美
构造之美 表达之美
优美的代码会给人们带来
喜悦 舒畅 优雅的享受
编程人员应该以业界良心的
高标准要求自己
在编程实践的过程中
逐步成长和成熟
成为一名优秀的软件工程师
高质量的代码
不能只是运行正确的
还要求做到可读性强
易于维护和简洁高效
因此 编程的工作
除了编写代码之外
还要包括代码审查
单元测试 代码优化
系统构建 集成调试等
一系列的工作
由于软件开发具有迭代的特性
所以编程一般来说
也不是能够一次性完成的
一个简单过程
而是一个复杂的迭代的过程
软件开发
是由多人协作完成的
程序员编写的代码
除了让计算机理解
并运行正确之外
还要让其他程序员
能够理解和维护
因此代码作为程序员的作品
也代表着他的脸面
荣誉和信用
皮尔卡丹曾经说过
如果你能真正地钉好一枚钮扣
这比你缝出一件
粗制滥造的衣服更有价值
为了提高代码的可读性
我们应该养成良好的编程习惯
认真对待每一个细节
掌握和执行编程规范
保证代码的清楚 整洁
为整个系统的结构之美
打下良好的基础
软件编程规范
是和特定语言相关的
描写如何编写代码的规则集合
说白了就是一组写代码的规矩
就如同交通规则
如果人人遵守
我们的城市交通
就能井然有序
减少交通事故
同样的道理
遵照一定的编程规范
可以让我们写出来的代码
井然有序
进而减少编程事故
或者说Bug的发生
避免不必要的错误
同时还能增加代码的可读性
可重用性和可移植性
这样的软件维护变的容易
而现实中
软件生命周期的70%成本
是维护
实际上
软件编程规范
并不存在一个业界的统一标准
许多公司都会制定自己的规范
在这里我们推荐大家阅读
学习并遵守Google公司
制定的编程规范
这一套规范相对来说
接受的范围更广泛一些
写的也比较具体
不仅告诉了我们该怎么做
还尽量解释了原因
Google的编程规范
涵盖了多种编程语言
下面将结合软件工程课程中
用到的Python语言
概要地介绍一下
Python编程有哪些值得
注意的地方
这里我们给出了一个
Python的直接运行程序模板
当然你也可以依照规范
编写自己的程序模板
先看第一行
它说明了Python程序的
运行解释器
对于可以直接执行的文件
建议增加这个说明
但是如果是被导入的模块文件
可以忽略
文件的基本头部
一般都是必须要写的
主要包括版权说明
许可声明和模块描述等信息
带有中文的文件
要写清楚它的编码形式
例如这里是utf-8格式
导入的外部模块
应当位于文件顶部
在模块注释和文档字符串之后
在全局变量和常量之前
这样可以方便地检查
模块导入是不是正确
有没有导入重复的模块
如果是直接执行的程序
建议创建一个main函数
来运行主功能
对于函数和类的定义
需要使用相应的注释
来说明其功能
这里是用以检查文件
是不是直接执行的
这一点是很重要的
因为有一些地方
比如pydoc和单元测试
都要求每一个文件
是必须可导入的
而且考虑到代码的最大
可重用性
即使我们打算某些文件
是被直接执行的
也不应该抹杀
未来它被其他模块导入的
可能性
加上这个对name的判断之后
主程序只有在被直接执行时
才会被执行
被作为模块导入时
不会执行
一般来说
人们都会使用注释
来增加对程序的理解
Python的注释是有两种形式
第一种形式是以#号打头的
这种真正的注释
一般是用来说明
一些实现的原理和难点
这里给的这个例子
是定义了一个
取黄金分割点的函数
它的注释说明了
黄金分割点的比例
并且说明函数
通过直接取0.618这样的方式
得出黄金分割点
这样做
可以避免使用公式计算
从而实现加速
第二种形式
就是像示例程序中
给出的这样
用前后各三个引号包起来的
一个文档字符串
它可以作为包 模块 类
函数之类的文档说明
在里面
也可以写上使用的示例
和单元测试
我们给的这个例子
用这种方式注释了
黄金分割点这个函数
说明了它的基本功能
输入参数还有返回值
程序注释可以帮助我们
更好地理解代码的语义
但是什么是好的注释
这是一位同学写的一个程序
我们看到这位同学很用心
他总是担心自己的代码
不容易被他人理解
所以
几乎对每一个语句
都加了注释
那么大家觉得
这个程序注释写得怎么样
我们仔细看一下这些注释
你就会发现
所有的注释
只是重复解释了一下
各行语句执行的功能
实际上
语句本身也是有含义的
比如说前面的这个
with open语句
没有它的注释
我们也清楚
它的意思就是
打开一个二进制的只读文件
显然呢这样的注释
只是重复了语句的语法含义
没有任何的价值
读完之后感觉什么都没说
另外 我们再来看这一段
for循环的代码注释
读了这个注释
你明白这段代码是干什么吗
看完了以后还是不明白
所以说这个同学
虽然在程序中
几乎是一行一行地解释代码
但是 这些注释
对于我们理解代码
没有任何帮助
反而影响了我们对程序
主要部分的理解
还不如没有注释看起来清楚
编写程序注释
并不是越多越好
而是要讲究实际的价值
不论我们使用什么样的语言
来编程
我们都应该学会
只编写够用的注释
重视质量而不是数量
好的注释应该解释为什么
而不是怎么样
所以 不要在注释里面
重复地描述代码
如果你发现在编写密密麻麻
过多的注释的时候
就有必要停下来看一看
是不是存在很大的问题
注释 其实要写好并不容易
应该要好好斟酌
注释里面写什么
写完之后再上下文回顾一下
检查它们是否包含了
正确的信息
另外
我们在维护代码的同时
也要做好注释的维护
根据上面讲的这些注释原则
我们把前面示例程序的注释
进行了重新改写
从现在的这个注释来看
我们可以很清楚地知道
这个程序
首先是读入一个文件
在检查输入的合法性之后
把所读入的RGB格式的图像
转化为YUV色彩空间的
Y通道灰度值
最后 再将结果写入
另一个文件
现在的这个代码
是不是看起来清楚多了
如果我们以后再来阅读
和维护这段代码
是可以很容易地理解
遵守良好的注释规范
还有一个好处
就是可以用规范的注释
自动地生成文档
比如说Python自带了一个
pydoc模块
它可以用简单的命令行
自动分析脚本文件
根据注释
生成可以方便查阅的
API文档
这里 显示的就是一个示例
如果你想生成更好看的文档
可以用其它的工具
总之许多文档自动化工具
都是基于代码的规范注释
所以在编写程序的时候
一定要注意写好注释
程序的代码离不开各种命名
我们要给模块命名
给类命名 给函数命名
给变量命名
一致的命名
可以减少开发人员很多麻烦
恰如其分的命名
也可以大幅度地提高
代码的可读性
降低维护成本
由于历史的原因
Python库的命名约定有一点混乱
不过现在已经有公认的
命名规范了
对于项目中已有的代码
因为历史遗留原因
可能不符合本规范
这时候应当看作是一个
可容忍的特例
允许它的存在
但是在新的代码中
不应该延续旧的风格
对于第三方模块
也可能不符合这个规范
这时也可以看作是
可容忍的一个特例
允许其存在
但是在新的代码中
也不要再使用
第三方模块的风格
在组装家具的时候
通常需要附带一个组装说明
为了更好地理解代码
我们也需要对代码
加上必要的注释
或者附带额外的文档
由于代码在软件的生命周期里
会不断地被修改 扩展和维护
相关的文档也就要随着代码的
更改而不断地更新
但是现实中
经常发生只改代码
不改文档的情况
这显然会对以后的维护
产生误导
甚至出现危险的错误
所以说最好的方法
是不要编写需要外部文档
来说明的代码
这样的代码是脆弱的
要确保你的代码本身
读起来就很清晰
换句话说
就是要编写自文档化的程序
让代码本身易于理解
而做到这一点的关键
在于清晰的代码结构
和规范的命名
现在来看一个程序
在没有注释的情况下
大家是不是可以很快地明白
这段程序是干什么的
也许有的同学会说
这段代码看起来太费解了
像i n1 n2这样的一些
变量的命名
根本就没有什么
任何实际的含义
看了半天
也弄不明白它们是什么意思
如果我们把这段代码重构一下
像右边这样的样子
是不是就可以一目了然了
首先 从函数的命名可以知道
它的功能是计算斐波那契数列
根据函数内变量的命名
和清晰的代码结构
我们可以了解
计算的过程和方法
从这个例子可以看出
通过有意义的命名
我们可以不需要任何注释
就能很容易地理解代码
而且这样做更便于后续的维护
Python的语句编写
也有相应的规范
我们在这里就不再一一地介绍
只是简单地说明部分语句的
书写规范
首先Python的语句
是不需要在行尾加分号的
再一个缩进是Python区分
代码块的关键
注意不要用制表符来缩进
也千万不要混用制表符和空格
应该用4个空格来进行缩进
类的命名应该是驼峰风格
而且首字母应该大写
变量的命名
应该是下划线风格
使用文件的话
应该要显示地调用close
否则很容易造成长时间
占用文件的问题
或者也可以通过with语句
来更优雅地解决这个问题
最后
每一行应该只写一条语句
该换行就换行
一定不要吝啬换行
import的语句
在Python程序里
很关键
通过它才能做到Python的
代码重用
前面我们说过
import的语句要全部放在
文件头部
这里再强调一下它的顺序
应该先是import Python的
内置模块
然后是第三方模块
最后是自己的模块
有条件的话
还应该让它们在各自的部分
按字母表顺序排列
一般来说
一条import的语句
只import的一个模块
一行写好多模块的话
不仅难看
还容易出错
如果我们从某个模块
import多个对象
可能会导致那一行太长
一般建议一行不超过80个字符
这种情况下
可以借助括号来进行换行
另外最好也不要用import*
这种方式来导入某个模块的
所有内容
因为这样很容易出现
命名空间的冲突
关于语句Python还有很多
灵活的用法
但是用的时候
应该注意删繁就简
比如Python就有很好用的
列表推导
不过使用的时候不要滥用
太复杂的话就很难理解
条件表达式也是很漂亮的
一个简短的语法
但是应该注意到
要在简单的情况下使用
另外 Python还有很多
很酷的特性
不过 这种酷酷的代码
写着试一试 玩一玩就行了
千万不要写到真实的项目里
因为它们会大大地增加
开发 调试和维护的难度
关于完整的Python编程规范
大家可以参考Google的
官方文档
另外
还有一个比较有趣的东西
是Python之禅道
通过import this就可以看到
里面列举了十多条
Python程序应该遵循的
一些原则
不过非常有意思的是
你可以在Python的库目录
找到this模块
打开看一看它的源代码
就会发现这些代码完全违背了
Python之禅道
总之一个优秀的程序员
首先要认真踏实地写好代码
要养成良好的编程习惯
在这门课中
我们希望大家自觉实践
编写结构优美
表达简洁清晰的代码
-1.1 软件无处不在
--讲课视频
-1.2 软件的本质特性
--讲授视频
-1.3 软件工程的产生与发展
--讲授视频
-1.4 软件工程的基本概念
--讲授视频
-1.5 软件质量实现
--讲授视频
-1.6 业界人士谈软件工程
-测验题--作业
-讨论题
--讨论题
-作业题
--第一张 作业题
-2.1 编程过程与规范
--讲课视频
-2.2 良好的编程实践
--讲课视频
-2.3 Python集成开发环境
--讲课视频
-2.4 代码静态检查
--讲课视频
-2.5 代码性能分析
--讲课视频
-2.6 结对编程实践
--讲课视频
-2.7 刘贺谈软件工程
--讲课视频
--讨论
-测验题--作业
-作业题
--第二章 作业题
-3.1 单元测试概述
--讲课视频
-3.2 黑盒测试方法
--黑盒测试方法
-3.3 白盒测试方法
--基本概念
--代码覆盖标准
--基本路径测试
-3.4 单元测试工具
--单元测试工具
--html
-测验题--作业
-作业题
--第三章 作业题
--作业题附件
-4.1 软件过程
--讲课视频
-4.2 软件过程模型
--讲课视频
-4.3 敏捷开发过程
--讲课视频
-4.4 微软公司开发过程
--邹欣经理自我介绍
--微软开发过程之一
--微软开发过程之二
-测验题--作业
-5.1 团队组织与管理
--讲课视频
-5.2 项目沟通管理
--讲课视频
-5.3 软件项目计划
--讲课视频
-5.4 软件项目估算
--讲课视频
-测验题--作业
-讨论题
--讨论
-6.1 敏捷开发之Scrum
-- 敏捷开发之Scrum
--html
-6.2 用户故事与估算
--讲课视频
-6.3 团队协作工具Tower
-6.4 配置管理
--讲课视频
-6.5 配置管理工具Git
--讲课视频
-测验题--作业
-作业题--作业
-7.1 需求工程师
--讲课视频
-7.2 需求定义
--讲课视频
-7.3 需求的类型
--讲课视频
--讲课视频(2)
-7.4 需求工程过程
--讲课视频
-7.5 需求的主要来源
--讲课视频
-7.6 需求获取技术
--讲课视频
--讲课视频二
--讲课视频三
-7.7 撰写需求文档
--讲课视频
-测验题--作业
-讨论题
--讨论
-8.1 用例建模概念
--讲课视频
-8.2 用例建模过程
--讲课视频
-8.3 用例建模精讲
--讲课视频
-8.4 建模工具介绍
--讲课视频
-8.5 微信抢票应用案例
--讲课视频
-测验题--作业
-讨论题
--讨论
-9.1 面向对象分析
--讲课视频
-9.2 CRC卡片分拣法
--讲课视频-1
--讲课视频-2
-9.3 面向对象设计
--讲课视频-1
--讲课视频-2
-9.4 类图建模
--讲课视频-1
--讲课视频-2
-第9章 面向对象分析与设计--测验题
-讨论题
--讨论
-10.1 顺序图概念
--讲课视频
-10.2 顺序图建模
--讲课视频
-10.3 顺序图风格
--讲义视频
-10.4 状态建模
--讲课视频
-10.5 状态图
--讲课视频
-10.6 状态图精讲
--讲义视频
-测验题--作业
-讨论题
--讨论
-11.1 软件体系结构概念
--讲授视频
-11.2 软件设计原则
--讲授视频
-11.3 软件体系结构风格(一)
--讲授视频
-11.4 软件体系结构风格(二)
--讲授视频
-11.5 软件体系结构风格(三)
--讲授视频
-11.6 软件设计过程
--讲授视频
-11.7 Web系统架构设计
--讲授视频
-11.8 数据库选择策略
--讲授视频
-测验题--作业
-作业题
--html
--html
--html
-作业题--作业
-12.1 交互设计概述
--讲授视频
-12.2 交互设计目标
--讲授视频
-12.3 GUI设计原则
--讲课视频
-12.4 KLM效率模型
--Video
-12.5 Fitts定律
--讲授视频
-12.6 交互设计过程
--讲授视频
-测验题--作业
-13.1 软件测试概念
--讲课视频
-13.2 软件测试类型
--讲课视频
-13.3 软件功能测试
--讲课视频
-13.4 软件性能测试
--讲课视频
-测验题--作业
-14.1 软件部署与交付
--讲课视频
-14.2 软件演化与维护
--讲课视频
-测验题--作业
-第一部分:基础知识
-第二部分:编程与测试(选做)