软件工程中的非形式化与形式化问题及工程实践
立即解锁
发布时间: 2025-10-27 00:21:04 阅读量: 8 订阅数: 19 AIGC 

软件工程的本质与实践
### 软件工程中的非形式化与形式化问题及工程实践
#### 1. 非形式化问题域
软件密集型系统要解决的具体问题所处的问题世界几乎总是异质且非形式化的。其组成部分来源广泛,主要包括以下几类:
| 来源类型 | 示例 |
| ---- | ---- |
| 自然世界 | 航空电子系统中的地球大气层 |
| 人类参与者 | 借阅图书馆的工作人员和用户、汽车驾驶员 |
| 电气和机械设备 | 电梯或自动取款机的物理组件 |
| 其他软件密集型系统 | 银行和电信服务系统 |
| 人造静态部分 | 铁路网络线路、机场跑道 |
| 具体词汇组件 | 信用卡、条形码标签 |
这些不同部分是科学理论和研究的对象,但并非形式化系统,软件工程师使用的形式化描述只是近似。它们具有众多不同的给定和潜在属性,需要多种语言来充分表达。在对软件密集型系统有重要意义的粒度上,即使问题世界中最可靠的部分也不如桌面计算机的 CPU 可靠,这部分是由于其固有性质,部分是因为其功能更易受与之交互的其他部分影响。
由于问题世界对软件密集型系统至关重要,其给定属性 W 和期望属性 R 是描述和推理的必要主题。然而,形式化描述和推理在非形式化领域的解释具有不同特点。
#### 2. 非形式化领域的推理
形式化推理依赖于抽象,即选择公理和字母表,利用公理对字母表元素进行推理,期望得到能揭示初始不明显或需更强说服力的真理的定理。在形式化世界中,该过程的可靠性取决于正确推理的能力。
但在非形式化世界中,形式化推理存在诸多可靠性障碍:
- **建立对应关系困难**:以道路交通控制系统为例,若要对行人及其使用人行横道的情况进行推理,确定“行人”的准确定义并非易事,如踏板车上的儿童、推着带拖车自行车的骑行者、机动轮椅使用者等,很难判断他们是否能用“行人”这一形式化术语恰当表示。我们应选择使这类难题尽量少的字母表,这种字母表的选择及其非形式化解释(即字母表与现实现象的映射)是任何形式化的基础。
- **定理适用性问题**:在交通系统中,对于两端有传感器的路段,通常认为路段内车辆数量等于进入车辆数减去离开车辆数。但当卡车运输汽车进入路段并卸载汽车时,该定理就不成立。因此,要选择在大多数实际情况中适用的定理。
- **抽象过程易出错**:选择字母表的抽象过程可能排除一些会影响推理的现象,这种错误在安全或安保推理中很常见。例如,TENEX 操作系统的连接调用检查密码字符串时,扫描遇到已分配和未分配页面边界会报告页面错误,攻击者可利用此漏洞将破解密码的复杂度从指数级降低到线性级,这体现了“无界相关性原则”带来的不确定性。
在非形式化世界中,所选字母表的元素基础不确定,且必然会遗漏一些可能使抽象和计算失效的现象。我们在描述和推理过程中需认识到所做的假设,如字母表难题少、公理常为真、定理不受被忽略现象影响等。将这些脆弱的假设基础构建成能支撑系统可靠性信心的结构,是软件工程的重要关注点。
#### 3. 形式化与非形式化的关联
软件密集型系统的开发涉及程序构建的形式化问题以及对需求和问题世界属性理解、描述与分析的非形式化问题。如何将程序构建的形式化方法与非形式化问题世界及机器非形式化方面的处理相关联,是理解软件工程的核心问题。
以下是两种不同的处理方式:
- **分离形式化与非形式化方面**:Dijkstra 认为应在软件工程的形式化和非形式化方面保持明确分离。功能规格说明书的作用是作为逻辑防火墙,分隔“愉悦性问题”(即满足规格的引擎是否是我们想要的)和“正确性问题”(即如何设计满足规格的引擎)。在问题图中,逻辑防火墙大致位于机器与问题世界共享现象的接口处,可适当调整位置以排除接口现象中不可简化的非形式化方面。这样程序员的任务可避免非形式化问题,采用纯形式化方法解决;问题世界专家则用非形式化技术处理防火墙另一侧的非形式化属性。这种分离的前提是能构建形式化规格说明书,问题世界专家负责开发与给定属性 W 一致且满足 S,W ⊆ R 的规格 S,程序员负责开发属性 M 满足 M ⊆ S 的机器。
- **将非形式化问题世界形式化处理**:
- 一种方法是将机器和问题世界视为一个形式化系统。完全形式化的需求用问题世界的现实变量表示,其值通常是随时间变化的函数。需求和问题世界属性用形式化系统内的现实变量方程表示,程序通过类似 Dijkstra 最弱前置条件演算的细化过程开发,从用现实变量表达的需求出发,最终得到程序文本。
- 另一种方法是“四变量模型”,将机器和问题世界分别称为系统和环境,通过传感器和执行器进行交互。定义了四组变量:环境的监测变量集 m、控制变量集 c,机器从传感器读取的值集 i 和写入执行器的值集 o。还定义了五个关于这些变量集时间函数向量的关系:
- SOF: i ↔ o,捕获机器行为的规格;
- IN: m ↔ i 和 OUT: o ↔ c,分别捕获传感器和执行器的属性;
- NAT: m ↔ c,捕获给定的环境属性;
- REQ: m ↔ c,捕获需求。
公式 NAT ∩ (IN•SOF•OUT) ⊆ REQ 用于表征系统的可接受性。与前一种方法相比,它提出了问题在其上下文中的显式通用结构,且方法性不太明显,未提出具体的软件开发演算或细化结构,但已成为多种具体开发技术的基础。
这些形式化方法对理解软件工程有重要贡献,但形式化推理在非形式化问题世界中的局限性仍然显著。开发成功的软件密集型系统不仅需要形式化描述和推理,还可从成熟工程分支的实践中学习。
#### 4. 工程实践中的专业化
在人类技术领域,专业化是随时间改进的基本前提。当取得进展时,领域的成功发展需要能够捕捉、整合和利用这些知识。在发展初期,少数杰出人才可掌握一个或多个领域的所有知识,但随着知识的深度和广度增加,个人掌握的范围变小,知识需由专业社区保管和传承,否则可能因被大量其他知识掩盖或普遍忽视而丢失。
成熟工程分支高度体现了专业化的过程,专业化的维度包括:
- **按工程制品**:如汽车工程、航空工程、化学工程等;
- **按问题世界**:如土木工程、采矿工程;
- **按需求类别**:如工业工程、运输工程;
- **按适用理论基础**:如控制工程、结构工程;
- **按产品组件**:如电动机、内燃机、TFT 屏幕;
- **按技术**:如焊接、钢筋混凝土、导电塑料等。
这些专业化是对不断变化的需求和机会的响应,不呈简单的层次结构,在多个维度上聚焦于不同粒度的重叠领域,涵盖从实用到严谨学术的各个方面,从接近手工艺的工程到依赖数学和科学的工程。
#### 5. 常规设计
专业化的根本好处是产生了常规设计。常规设计与激进设计有明显区别:
- **常规设计**:大多数工程实践属于常规设计,工程师在已知产品类别的标准设计基础上进行渐进式改进。例如,在涡轮喷气发动机出现前设计常规飞机发动机,工程师会默认发动机采用汽油燃料的四冲程内燃机循环,高功率发动机的气缸排列方式(风冷为径向,液冷为直列)等特征也会被视为给定。设计问题通常是在减轻重量、降低油耗或提高功率输出等方面进行改进。
- **激进设计**:在激进设计中,设备的结构和工作原理大多未知,设计师没有成功的预设,任务是设计出能正常工作以值得进一步开发的东西。
常规设计有两层含义:一是特定类别的所有制品共有的结构和属性;二是设计师开发新制品时遵循的实践规范。实践规范为设计师提供了选择选项和设置参数的范围,在某些极端情况下(如小型电力变压器设计),参数值由固定程序确定。常规规范还包含对设计方案的分析知识(如土木工程中特定类型承重结构的应力计算技术)以及从过去失败中吸取的经验教训(如分析悬索桥路面的空气动力学特性和垂直振荡模式以避免类似塔科马海峡大桥的失败)。
#### 6. 专业化的成果
常规设计是长期演变的产物,只能从专业化中产生,因为它需要专业社区长期的专注。以汽车为例,从卡尔·本茨 1886 年设计的三轮汽车的激进设计,经过约 35 年演变为常规设计。到 1920 年,常规汽车设计规定了四轮、内燃机、变速箱、电动启动马达、封闭驾驶室(运动型和部分旅行车除外)、充气轮胎和四轮鼓式制动器等特征。此时,汽车设计师清楚汽车的常规特征并能合理配置,有很大可能生产出可靠的车辆。
产品类别的常规设计确立并非发展的终点,而是为可靠的进一步发展奠定了稳定基础。自 1920 年以来的九十多年里,汽车不断稳步发展,达到了如今的精致水平,这是汽车行业一百二十年集中专业化的成果。
综上所述,软件工程在处理非形式化问题世界时面临诸多挑战,可借鉴工程实践中的专业化和常规设计理念,以提高软件系统的可靠性和开发效率。
### 软件工程中的非形式化与形式化问题及工程实践
#### 7. 软件工程借鉴工程实践的意义
软件工程与传统工程领域虽有不同,但在很多方面可以借鉴工程实践的经验。专业化和常规设计在传统工程中取得了显著成效,对于软件工程而言,同样具有重要的借鉴价值。
- **提高开发效率**:通过专业化,软件工程可以将不同的任务和领域进行细分,让专业人员专注于特定的方向,从而提高开发效率。例如,在软件开发中,可以有专门的前端开发人员、后端开发人员、测试人员等,他们在各自的领域积累经验,能够更高效地完成工作。
- **增强系统可靠性**:常规设计为软件系统的可靠性提供了保障。在软件工程中,建立一套成熟的设计规范和标准,让开发人员在这个基础上进行渐进式改进,避免了从头开始设计带来的不确定性和风险。例如,在设计软件架构时,遵循一些通用的架构模式,如 MVC(Model-View-Controller)模式,可以提高软件的可维护性和可靠性。
- **知识传承和积累**:专业化使得知识能够在专业社区中得到传承和积累。在软件工程中,开发人员可以将自己的经验和知识分享给团队成员,形成一种知识共享的文化。这样,新的开发人员可以快速学习和掌握前人的经验,避免重复劳动,同时也有助于推动整个行业的发展。
#### 8. 软件工程中专业化和常规设计的实施步骤
在软件工程中实施专业化和常规设计,可以按照以下步骤进行:
1. **确定专业化方向**:根据软件项目的特点和需求,确定专业化的方向。可以从技术、业务领域、功能模块等方面进行划分。例如,对于一个电商系统,可以有前端开发、后端开发、数据库管理、安全测试等专业化方向。
2. **培养专业人才**:针对确定的专业化方向,培养相应的专业人才。可以通过培训、学习、实践等方式,提高开发人员的专业技能。例如,组织内部培训课程、鼓励开发人员参加外部技术交流活动等。
3. **建立常规设计规范**:根据以往的项目经验和行业标准,建立一套常规设计规范。规范可以包括软件架构设计、代码编写规范、测试流程等方面。例如,制定统一的代码风格规范,让开发人员在编写代码时遵循相同的标准,提高代码的可读性和可维护性。
4. **进行渐进式改进**:在常规设计的基础上,进行渐进式改进。开发人员可以根据项目的需求和用户反馈,对软件系统进行优化和升级。例如,定期对软件进行性能测试,发现性能瓶颈并进行优化。
5. **持续学习和创新**:软件工程是一个不断发展的领域,开发人员需要持续学习和创新。专业社区可以组织技术分享会、研讨会等活动,让开发人员了解最新的技术和趋势,不断提升自己的能力。
#### 9. 软件工程中面临的挑战及应对策略
虽然专业化和常规设计在软件工程中有很多好处,但也面临一些挑战,以下是一些常见的挑战及应对策略:
| 挑战 | 应对策略 |
| ---- | ---- |
| 技术更新快 | 鼓励开发人员持续学习,参加培训和技术交流活动,及时掌握最新的技术。 |
| 需求变化频繁 | 采用敏捷开发方法,快速响应需求变化,及时调整开发计划。 |
| 团队协作困难 | 建立良好的沟通机制,加强团队成员之间的交流和协作。例如,定期召开团队会议,分享项目进展和遇到的问题。 |
| 知识传承困难 | 建立知识管理系统,记录和分享开发人员的经验和知识。例如,创建内部技术博客,让开发人员可以分享自己的技术文章和经验总结。 |
#### 10. 未来发展趋势
随着科技的不断发展,软件工程也将面临新的机遇和挑战。以下是一些未来的发展趋势:
- **人工智能和机器学习的应用**:人工智能和机器学习技术将在软件工程中得到更广泛的应用。例如,利用机器学习算法进行软件缺陷预测、自动化测试等。
- **云计算和大数据**:云计算和大数据技术将为软件工程提供更强大的计算和存储能力。软件开发人员可以利用云计算平台进行开发和部署,同时利用大数据分析技术对用户数据进行挖掘和分析。
- **低代码和无代码开发**:低代码和无代码开发平台将降低软件开发的门槛,让更多非专业的人员也能够参与到软件开发中来。这将加速软件的开发速度,提高开发效率。
- **开源软件的发展**:开源软件将继续在软件工程中发挥重要作用。开源社区将不断涌现出更多优秀的开源项目,开发人员可以利用这些开源项目快速搭建自己的软件系统。
#### 11. 总结
软件工程在处理非形式化问题世界时,面临着诸多挑战。通过借鉴工程实践中的专业化和常规设计理念,可以提高软件系统的可靠性和开发效率。在实施专业化和常规设计时,需要确定专业化方向、培养专业人才、建立常规设计规范、进行渐进式改进和持续学习创新。同时,要应对技术更新快、需求变化频繁、团队协作困难等挑战。未来,软件工程将朝着人工智能和机器学习应用、云计算和大数据、低代码和无代码开发、开源软件发展等方向发展。
通过不断地学习和实践,软件开发人员可以更好地应对这些挑战,推动软件工程的发展,为社会创造出更优质的软件产品。
```mermaid
graph LR
A[软件工程发展] --> B[专业化和常规设计]
B --> C[提高开发效率]
B --> D[增强系统可靠性]
B --> E[知识传承和积累]
A --> F[面临挑战]
F --> G[技术更新快]
F --> H[需求变化频繁]
F --> I[团队协作困难]
F --> J[知识传承困难]
A --> K[未来发展趋势]
K --> L[人工智能和机器学习应用]
K --> M[云计算和大数据]
K --> N[低代码和无代码开发]
K --> O[开源软件发展]
```
以上流程图展示了软件工程发展过程中专业化和常规设计的作用、面临的挑战以及未来的发展趋势之间的关系。通过专业化和常规设计可以提高开发效率、增强系统可靠性和实现知识传承积累,但同时也会面临一些挑战,而未来软件工程将朝着多个方向发展。
0
0
复制全文


