当前课程知识点:软件工程 >  第2章 编写高质量代码 >  2.2 良好的编程实践 >  讲课视频

返回《软件工程》慕课在线视频课程列表

讲课视频在线视频

下一节:讲课视频

返回《软件工程》慕课在线视频列表

讲课视频课程教案、知识点、字幕

编程实际就是一项实践活动

学习编程最好的方法

就是学中做和做中学

具体说来

可以用看 问 练这三个字

来概念学习编程的关键环节

第一是看

要经常地阅读优秀的代码

这是提高开发人员修行的

一种捷径

我们可以从这些代码中

吸取到那些牛人们的技术精髓

第二是 问

要善于发现问题

并以专业的方式提出问题

通过对问题求解的交流

来扩展自己的编程学习

初学编程的人

可能经常遇到如何正确提问

这样的困惑

这里我们给出一个参考的网页

它说的是如何向开源社区

提问题

以及如何用更专业的方式

更好地提出自己的问题

希望大家下去阅读

并努力学会提问

第三是 练

要亲自动手去编写代码

不动手编程的学习

是徒劳无用的

提升编程能力最有效的方法

就是实践 实践 再实践

工程活动都是有相通性的

我们先来看一下高楼大厦

是如何建成的

在建楼之前

我们首先认真地分析问题

要明确盖什么样的楼

以及在哪里盖等等

然后呢会做一个初步的

总体设计

还有可能建造一个实体的模型

进行评估和测试

在完成整个设计方案之后

我们先用钢筋搭建一个

整体框架

然后再一层一层

一块一块地去建造

最后 测试和验收

软件工程也是一项解决问题的

工程活动

我们首先要对问题有一个

分析的过程

由于很多问题非常复杂

就需要把这些复杂的问题

分解成更容易处理的

若干小问题

然后针对这些不同的问题

设计相应的解决方案

再把所设计的小的构件

组合形成一个完整的系统

这个过程也是很有挑战性的

需要应用抽象的方法

进行分解和合成

在程序设计的过程中

实现这种分解和合成

有一些通用的原则

应用这些原则可以增加代码的

可修改性和可测试性

便于程序的扩展和维护

我们在这一讲

将介绍模块化设计

面向抽象编程

以及错误和异常处理

这三种编程实践

并结合一个实例

说明如何更好地设计

Python程序

模块化的设计思想

在工程领域中应用非常广泛

它的目的

就是降低系统构造的复杂性

增加灵活性

我们都知道活字印刷术

它可以称得上是古代

产品领域的一种模块化设计

这里单个的汉字作为一个

文字的“模块”

它本身是有自己的特定含义

不同的汉字通过语法

这个“接口”进行连接

可以进一步构成

一个更复杂的文章“产品”

在现代建筑领域中

模块化设计也用于建造

各种住宅和办公建筑

这里显示的是迪拜集团

在伦敦西部建立的第一家

模块化酒店

它把建筑体分成若干个

空间模块

精装修甚至清洁

都是在工厂里完成

然后运到工地

像搭积木一样来搭建房屋

这样做的好处

在于建造的房屋更加高效灵活

维护的时候

可以单独地替换一个单元

而不会影响到其它单元的使用

同样的道理

程序的模块化设计

就是把一个很大的程序

按照功能分拆成一系列

小的模块

其中每一个模块

相对独立 功能单一

结构清晰 接口简单

各个模块之间通过接口

进行调用

这样做可以有效地降低

程序设计的复杂性

提高模块的可靠性和可复用性

有助于实现快速地开发

方便维护和功能扩展

模块化设计需要对程序

进行分解

针对不同的系统

可能有不同的分解策略

对于一个WEB应用系统来说

我们可以按照系统业务类型

进行水平划分

将其分成用户管理

权限管理以及其他不同的

业务功能模块

也可以按照系统的层次

进行垂直的划分

把它分成应用服务 业务逻辑

数据存储等典型的多层结构

我们还可以通过

区别容易改变

和不容易改变的部分

来划分模块

将稳定 不常变化的代码

抽象到一个模块里

比如系统中比较通用的

基础的功能

将经常变化的代码

放在另外的一个或多个模块里

比如业务的逻辑

因为易变的代码经常修改

会很不稳定

分开之后

这些代码在修改的时候

就不会影响到那些不变的代码

模块化设计也可以基于

单一职责进行划分

就是把代码按照职责抽象出来

形成不同的模块

再把同一职责的代码

放在一个模块里

这是一个瑞士军刀

它大概有十几种刀

还有mp3的功能

显然 它不是基于单一职责的

虽然在野外瑞士军刀方便携带

但并不代表它很好用

类和函数是程序的基本构件

通过把一个大的程序

分解成若干相对独立的

类或函数

可以使程序的结构清晰

容易理解

对于类或者函数的设计

可以基于单一职责进行分解

就是应该只做一件事

并且做好这件事

但是在这里

单一职责并不等同于单一功能

而是指引起变化的原因

也就是说

从变化的角度去考虑

一个类或者函数应该有且只有

一个引起它变化的原因

按照这个原则

应该避免编写万能的类

和庞大的函数

Python程序的模块元素

主要包括函数 类 模块 包

这四种类型

每个Py文件就是一个模块

其中还可以导入其它的模块

一些模块还可以作为启动程序

独立运行

下面我们将结合一个

生命游戏的例子

来讲解一下如何对其

进行模块化设计

生命游戏是英国数学家康威

在1970年发明的细胞自动机

它是假设

有这么一个二维矩形的世界

这个世界里面每一个方格

都居住着一个细胞

细胞本身是有生和死两种状态

随着时间的变化

每个方格里面的细胞

它的生死也会发生变化

那么一个细胞

在下一个时刻的生死

是由它周围8个方格里面的

细胞状态来决定的

如果一个细胞的周围

至少有四个活的细胞

那么下一个时刻

它就会因为拥挤而死亡

如果这个细胞的周围

正好有三个活的细胞

那么下一个时刻

它也会成为一个活的细胞

如果正好

是有两个活的细胞

那么它的状态

是不会发生变化的

如果只有一个活的

或者甚至没有活的细胞

那么它就会因为孤独而死亡

这个游戏是在一个类似于

围棋棋盘一样的

可以无限延伸的

二维方格网中进行

在游戏的开始

每个细胞都可以随机地

或者被规定的设为一个

生或者死的状态

之后

细胞就按照前面给出的规则

进行生息衍繁

这里显示的

是维基百科上面的两个动态图

现在我们来分析一下生命游戏

这个例子

首先细胞是在一个

二维方格网中生长变化

所以像地图这样一些数据

是一个要素

其次细胞的变化

是有一定规则的

按照这样的规则

来控制细胞的变化

也就是游戏的规则

因此游戏需要有一个控制逻辑

最后整个细胞的变化

是和时间有关系的

那么就需要一个计时器

根据前面的分析

我们可以把生命游戏的

三个要素设计成

三个不同的模块

每个模块都有各自单一的职责

再通过一定的方式

相互地连接和调用

这样一来

生命游戏就被划分成

地图模块

逻辑模块和计时模块三个部分

其中地图模块它是管理

和地图相关的一切数据的

初始化 获取和更新

逻辑模块

是控制完整的游戏逻辑

按照游戏的规则

对地图数据进行改变

计时模块负责和时间

相关的功能

在适当的时机触发

逻辑模块的更新

这种划分是把生命游戏

这样一个大问题

分解成一些更容易处理的

小问题

显然每个模块实现起来

更加的简单 清楚

而且易于测试和扩展

比如说

可以修改游戏规则

改变更新频率

设置不同的地图数据等

上面给出的只是一种方案

实际上你还可以设计

其他不同的方案

只要符合设计质量原则就可以

例如你可以增加一个UI模块

专门负责游戏的图形化显示

完成模块的设计之后

我们就要设计这些模块之间的

连接部分

当然连接的设计

要抽象的合适

以便降低在未来开发中

发生变化的可能

面向抽象编程

就是把模块的行为抽象出来

形成相对固定的接口

这样不论对接口的实现

是如何变化

只要接口不变

就不会影响使用接口的模块

这就好像木工里边的榫

它并不关心不同部件的

实现方式

而是通过连接部分

把不同的部件严密地结合

在一起

形成一个完整的产品

首先我们来看地图模块

游戏逻辑对地图的操作

包括初始化

重置地图再随机设定活细胞

获取某一个方格周围的

活细胞数量

更新或者读取方格的

细胞状态等

因此需要在地图模块

定义这些关键的方法

对于逻辑模块

首先是要在主程序中

进行实例化

在计时器触发的时候

进行游戏的循环

也就是说

根据当前状态

更新地图的下一时刻的状态

还要输出当前的地图

所以 我们在这里

定义了逻辑模块的相应方法

最后是计时模块

它也要在主程序中

进行实例化

关键是设定触发的间隔秒数

另外还有一个触发函数

最后还需要启动计时器

计时器在启动之后

就会按照设定的间隔时间

持续地触发

这里我们给出了

相关方法的定义

完成模块化设计

以及关键方法的定义之后

开发人员就可以分别实现

各个模块

同时模块测试的设计工作

也可以开始进行

需要强调的是

各个模块对外提供的服务

也就是那些关键方法

不应该发生变化

否则会连带产生

其它调用模块的修改

给整个程序的构造

带来不稳定

程序可能会出现错误

例如Python的解析错误

或者未捕获的异常

这种运行时的错误等

如果程序能够对运行时

出现的可预见的错误进行处理

就会避免让用户

感到困惑的问题

常见的异常有很多

比如被零除

断言错误 操作系统错误

输入输出错误等

程序的异常处理

是用于管理程序运行期间

错误的一种常用方法

其实

我们已经见过很多产品的

报错处理

对错误和异常处理

应该不陌生

Python的异常

是用try except来捕获并处理的

编写代码的时候

我们要注意细化具体的

异常类型

有针对性地进行处理

同时还应该控制try和except的

代码块的大小

代码块越大就容易出现

预期之外的异常

除此之外

在代码实现的关键部分

还要养成检查

变量合法性的习惯

避免错误的数据

在未来积累成了更大的错误

那样可能会大大增加

错误定位的难度

很难进行调试

生命游戏这个程序

一旦开始运行

就会无休止地运行下去

我们需要有一种方式

让它安全地停止

目前我们是用命令行的方式

来运行

用控制台来打印输出

所以可以通过常见的Ctrl+C的

方式来终止程序

但是这样会在Python里边

引发异常

这是一种可预见的异常

我们需要捕获和处理它

要避免Ctrl+C报错

我们可以在启动部分

编写异常处理代码

另外

也应该在关键的部分

进行变量合法性检查

比如地图的初始化

就应该检查输入参数

是不是合法

这样可以避免程序

在某个奇怪的地方出错

到这里我们已经完成了

生命游戏的问题分析

模块和抽象设计

以及异常处理的部分实现

剩下的部分

就由同学们按照我们给出的

编程规范

高质量地完成这个游戏的

编程实现

最后再进行有效的测试

软件工程课程列表:

第1章 初识软件工程

-1.1 软件无处不在

--讲课视频

-1.2 软件的本质特性

--讲授视频

-1.3 软件工程的产生与发展

--讲授视频

-1.4 软件工程的基本概念

--讲授视频

-1.5 软件质量实现

--讲授视频

-1.6 业界人士谈软件工程

--海芯科技创始人施侃乐访谈

-测验题--作业

-讨论题

--讨论题

-作业题

--第一张 作业题

第2章 编写高质量代码

-2.1 编程过程与规范

--讲课视频

-2.2 良好的编程实践

--讲课视频

-2.3 Python集成开发环境

--讲课视频

-2.4 代码静态检查

--讲课视频

-2.5 代码性能分析

--讲课视频

-2.6 结对编程实践

--讲课视频

-2.7 刘贺谈软件工程

--讲课视频

--讨论

-测验题--作业

-作业题

--第二章 作业题

第3章 单元测试

-3.1 单元测试概述

--讲课视频

-3.2 黑盒测试方法

--黑盒测试方法

-3.3 白盒测试方法

--基本概念

--代码覆盖标准

--基本路径测试

-3.4 单元测试工具

--单元测试工具

--html

-测验题--作业

-作业题

--第三章 作业题

--作业题附件

第4章 软件开发过程

-4.1 软件过程

--讲课视频

-4.2 软件过程模型

--讲课视频

-4.3 敏捷开发过程

--讲课视频

-4.4 微软公司开发过程

--邹欣经理自我介绍

--微软开发过程之一

--微软开发过程之二

-测验题--作业

第5章 团队开发管理

-5.1 团队组织与管理

--讲课视频

-5.2 项目沟通管理

--讲课视频

-5.3 软件项目计划

--讲课视频

-5.4 软件项目估算

--讲课视频

-测验题--作业

-讨论题

--讨论

第6章 敏捷开发与配置管理

-6.1 敏捷开发之Scrum

-- 敏捷开发之Scrum

--html

-6.2 用户故事与估算

--讲课视频

-6.3 团队协作工具Tower

--Tower工具介绍(1)

--Tower工具介绍(2)

-6.4 配置管理

--讲课视频

-6.5 配置管理工具Git

--讲课视频

-测验题--作业

-作业题--作业

第7章 需求获取

-7.1 需求工程师

--讲课视频

-7.2 需求定义

--讲课视频

-7.3 需求的类型

--讲课视频

--讲课视频(2)

-7.4 需求工程过程

--讲课视频

-7.5 需求的主要来源

--讲课视频

-7.6 需求获取技术

--讲课视频

--讲课视频二

--讲课视频三

-7.7 撰写需求文档

--讲课视频

-测验题--作业

-讨论题

--讨论

第8章 用例建模

-8.1 用例建模概念

--讲课视频

-8.2 用例建模过程

--讲课视频

-8.3 用例建模精讲

--讲课视频

-8.4 建模工具介绍

--讲课视频

-8.5 微信抢票应用案例

--讲课视频

-测验题--作业

-讨论题

--讨论

第9章 面向对象分析与设计

-9.1 面向对象分析

--讲课视频

-9.2 CRC卡片分拣法

--讲课视频-1

--讲课视频-2

-9.3 面向对象设计

--讲课视频-1

--讲课视频-2

-9.4 类图建模

--讲课视频-1

--讲课视频-2

-第9章 面向对象分析与设计--测验题

-讨论题

--讨论

第10章 行为建模

-10.1 顺序图概念

--讲课视频

-10.2 顺序图建模

--讲课视频

-10.3 顺序图风格

--讲义视频

-10.4 状态建模

--讲课视频

-10.5 状态图

--讲课视频

-10.6 状态图精讲

--讲义视频

-测验题--作业

-讨论题

--讨论

第11章 软件系统设计

-11.1 软件体系结构概念

--讲授视频

-11.2 软件设计原则

--讲授视频

-11.3 软件体系结构风格(一)

--讲授视频

-11.4 软件体系结构风格(二)

--讲授视频

-11.5 软件体系结构风格(三)

--讲授视频

-11.6 软件设计过程

--讲授视频

-11.7 Web系统架构设计

--讲授视频

-11.8 数据库选择策略

--讲授视频

-测验题--作业

-作业题

--html

--html

--html

-作业题--作业

第12章 软件交互设计

-12.1 交互设计概述

--讲授视频

-12.2 交互设计目标

--讲授视频

-12.3 GUI设计原则

--讲课视频

-12.4 KLM效率模型

--Video

-12.5 Fitts定律

--讲授视频

-12.6 交互设计过程

--讲授视频

-测验题--作业

第13章 软件系统测试

-13.1 软件测试概念

--讲课视频

-13.2 软件测试类型

--讲课视频

-13.3 软件功能测试

--讲课视频

-13.4 软件性能测试

--讲课视频

-测验题--作业

第14章 软件交付与维护

-14.1 软件部署与交付

--讲课视频

-14.2 软件演化与维护

--讲课视频

-测验题--作业

第15章 期末考试与总结

-第一部分:基础知识

-第二部分:编程与测试(选做)

--编程与测试(选做)

讲课视频笔记与讨论

也许你还感兴趣的课程:

© 柠檬大学-慕课导航 课程版权归原始院校所有,
本网站仅通过互联网进行慕课课程索引,不提供在线课程学习和视频,请同学们点击报名到课程提供网站进行学习。