软件工程的三个环境因素
综述
- 三个因素分别为:虚拟计算机、抽象软件实体、现实问题
其中,虚拟计算机与抽象软件实体是软件工程的基础,现实问题是软件工程的服务目标 - 图示,三者与软件工程的关系
用抽象软件实体保证正确性,在虚拟计算机上实现,用来解决现实世界的问题
现实问题
抽象软件实体
虚拟计算机
软件工程发展图示
Before 1950’s
软件是硬件的一部分
- 想法:软件工程就是硬件工程;软件是以机器为导向的
- 应用基础:科学研究(尤其是在军事方面)
- 理论基础:lambda计算(by Church)和图灵机(by Turing)
- 实现基础:冯诺伊曼架构
- 软件是硬件的一部分
- 图示
1950’s
软件开发与硬件开发是一回事
-
想法:计算机上的应用都是以机器为中心的
-
出现第一代语言(01语言)、第二代语言(一些汇编语言)
-
研究用大型计算机(research mainframe),用来计算研究中的科学计算问题;研究型大型计算机数量有限,没有人为他开发系统软件,所有程序的编写都是基于输入输出系统(Basic Input Output System, BIOS),甚至是直接基于硬件的,编译环境也只有汇编语言的编译器
-
软件开发以硬件开发为导向
-
出现了编译器
-
图示
-
虚拟计算机:第一台商用计算机 UNIVAC I;是以机器为中心的
-
抽象软件实体
1952年出现首个编译器
出现1GL、2GL -
软件开发流程:以面向硬件的瀑布模型
如图
-
Summary
科学计算机
机器为中心的科学计算机
第一代语言、第二代语言
软件工程同于硬件工程
面向硬件的软件开发
强调回顾与测试
科学家、硬件工程师
1960’s
软件不是硬件
-
现实应用:商用软件、业务应用
-
抽象软件实体:出现第三代语言(3GL)(语句、函数、数据类型)
ASCii码(美国信息交换标准码) -
虚拟计算机:商用大型机
更好的基础结构:操作系统,编译器(“function” concept),utilities
产品系列:OS-360,CAD/CAM,math/statistics libraries
大项目如Apollo的成功(航空)
信用卡、ATM -
软件工程的工艺方法
-
图示
-
两个重要的诉讼案
一项裁定ENIAC专利不再有效(1973),使计算机体系结构进入公共领域
作为反垄断诉讼的结果,IBM同意分类定价软件,使得软件不再依附于计算机硬件,独立存在(原本的软件和硬件打包一起卖) -
以应用为中心
-
软件与硬件的区别
软件与现实世界关系更加密切,对需求的规格化更加困难
软件比硬件容易修改的多,并且不需要昂贵的生产线复制产品
软件没有损耗(维护主要是人力成本)
软件不可见(不容易监测、度量) -
软件危机
对软件开发成本和进度的估计常常不准确,开发成本超出预算,实际进度比预定计划一再拖延
用户对已完成系统不满意
软件产品质量不可靠
软件可维护程度低
软件通常没有适当的文档资料
软件成本不断提高
软件开发生产率无法满足人们对软件的生产要求,软件开发生产率的提高落后于硬件的发展 -
60年代的软件爱你开发都是工艺式的开发,即软件开发在总体上依靠程序员个人能力的开发
到了60年代后期,认识到工艺式开发的问题,研究者从编程入手研究解决软件危机的办法,这些促成了70年代结构化编程方法的建立 -
软件开发过程
建立-修补
工艺式开发
英雄式,牛仔式 -
问题
面条式代码——一整块
许多问题
大项目的管理与计划的缺乏 -
Summary
商业应用
以应用为中心的商用计算机
第三代语言
软件并非硬件
工艺式软件
计算机系
软件危机
对软件工程师的需求
开始办法图灵奖
1970’s
结构化方法、瀑布模型、形式化方法
-
现实应用:业务应用控制、复杂性
-
抽象软件实体:结构化编程语言
C在1969到1973年之间开发出来,一直流行
Pascal(过程), Smalltallk(面向对象), Prolog(逻辑), Scheme, SQL(数据库)
方法,块结构,数组,分支,循环 -
虚拟计算机:商用微型机
操作系统
DBMS
高级语言编译器
开发环境
软盘、软盘驱动器 -
图示
-
70年代的软件开发方法
结构化编程语言(函数的概念,块、分支、循环等)
自顶向下,逐步求精
结构化方法
模块化与信息隐藏
抽象数据类型 -
形式化方法
为解决bug太多的问题
没办法说明一段程序代码没问题,只能说没找到而已
想法:用数学方法证明一段代码没问题
已达成:一万行代码内可证明(有的时候)(小规模)
无法大规模证明,只能用在最关键之处 -
解决项目不可控:瀑布模型,Do it Twice
按部就班从上到下做事情,再从下往上找问题;每个阶段都有一个里程碑式的点,便于返工
需要文档,但是这个模型下文档很多,难以维护
过于重视过程
图示
-
三种逻辑结构:顺序、循环、分支
-
做量化工作:统计、分析各种指标
软硬件代价比
错误修复随项目进度的代价变化趋势(越早修复代价越小)
-
Summary
单纯的软件产品
商用微型机
结构化语言和方法
瀑布模型
形式化方法
量化方法
1980’s
生产力,面向对象,重用,软件过程模型
-
个人机(PC),面向个人消费者市场的应用
-
面向对象方法与成熟的结构化方法
-
GUI(可见用户界面)
-
现实应用:业务应用,大众软件追求生产力
-
虚拟计算机
PC
商用微型机、操作系统
数据库管理系统
更好的编译器
可视化界面的编程环境
光盘CDROM -
抽象软件实体
语句、类型、函数、模块、对象与类
GUI
面向对象的编程语言 -
图示
-
面向对象编程广泛使用在C++语言
-
随着软件规模、软件复杂度变大,就需要重用;该概念从50年代就开始出现了
-
应用在软件复杂度、独立消费者市场等方面指数增长
-
生产力和效率方面形成世界性竞争
-
80年代的重用体现在面向对象
-
软件过程
70年代只有瀑布模型
80年代有过程模型等一系列的模型 -
软件开发方法
分析和设计一起考虑
软件重用
面向对象地分析和设计 -
分析设计同时考虑的发展
70年代中后期给予结构化编程建立了早期的结构化方法(包括结构化分析和结构化设计,更多的还是在关注软件程序的构建)
80年代人们逐步开始将结构化分析与设计的关注点转向问题解决和系统构建,产生了现代结构化方法(信息工程,结构的系统分析与设计方法,现代结构化分析等);更注重系统构建而不是程序构建,所以更重视问题分析、需求规格和系统总体结构组织而不是让分析与设计结果符合结构化程序设计理论;更重视阶段递进的系统化开发过程,而不是一切围绕最后的编程进行 -
面向对象编程的发展
最早面向对象编程思想可以追溯到60年代的Similar-67语言,它使用了类、对象、协作、继承、多态(子类型)等最基础的面向对象概念
70年代的Smalltalk就是完全基于面向对象思想的程序设计语言,他强化了一切皆是对象和对象封装的思想,发展了继承和多态
80年代中期,C++的出现和广泛使用使面向对象成为程序设计的主流(C++只是在C语言中加入面向对象的特性,并不是纯粹的面向对象的语言) -
面向对象的特性
面向对象本身不是像结构化一样有基于数学的程序设计理论的支撑
模块化、信息隐藏等设计思想和数据库模型的进步都是促使面向对象概念演进的重要因素
可复用性满足了大生产力的需求,提高了GUI的编程能力 -
面向对象与结构化对比
结构化:学术化,严谨,足够的数学支持
面向对象:商业化,原则的必要性与流派的复杂性(有的程序员使用着面向对象的语言写着过程式的程序;只有专家级程序员才能用好)
工业界与学术界的鸿沟 -
重用与面向对象的发展
50年代:数学方法
60年代:Simula-67
70年代:ADT
80年代:Smalltalk,Eiffel,C++,OO方法,重用库
90年代:领域内工程,生产线,UML
00年代:模型驱动开发,面向服务结构 -
软件重用:OO,第四代语言,购买商用组件,程序产生器(自动化编程)
-
软件模型:过程模型(原型,渐进交付,演化式开发,螺旋)
-
过程评价:组织们有标准
-
实用工具支持过程:计算机辅助软件工程
-
没有银弹:软件开发的根本困难在于软件产品的内在特性,他们无法回避
-
人的因素逐渐影响加大
-
Summary
生产力需求
个人消费者
PC
GUI
现代化结构方法
面向对象
重用
软件过程
没有银弹
人的因素
1990’s
Internet,软件架构,RUP,Process Improvement
-
现实应用:大规模业务应用,大众产品(web应用),大规模复杂度控制,时间压力,可变性和用户价值
-
抽象软件实体:语句,类型,函数,模块,对象与类,包,组件,进程,物理单元,部件,连接件,部署
Java
软件架构 -
虚拟计算机:商业微型机与PC,局域网与Internet,网络操作系统,数据库管理平台,中间件平台
中间件(CORBA, DCOM, RMI) -
图示
-
以企业为中心
整合从前的“应用孤岛”,实现整个企业管理
解决信息孤岛问题,低成本适配到各个企业
-
大规模软件开发
复杂度:90年代的一个发展主题就是建立能够开发大规模软件系统的方法与技术
可修改性:90年代出现了对软件可变更性的持续追求,这种态势延续至今
开发周期:人们必须解决大规模软件开发周期过长的问题,并在90年代中后期提出了市场驱动开发的口号
用户价值:人们意识到用户价值的重要性,人机交互、涉众分析等很多新的方法与技术都出现 -
软件开发方法
面向对象:三巨头提出各自的方法融合
软件架构
人机交互
需求工程
基于重用的大规模软件开发方法
网络应用开发方法 -
面向对象的统一建模语言(UML)
UML有4层:
画出的图:最底层,遵从UML语言
图例(图的语法):第三层(图例中有很多构建)
第三层图例的表达模型:第二层
定义第二层的源模型:第一层 -
设计模式,面向对象设计原则等有效的面向对象实践经验
-
软件架构的发展
70年代:开发复杂软件系统的初步尝试使人们明确和发展了独立的软件设计体系,提出了模块化、信息隐藏等最为基础设计思想
80年代中期,这些思想成熟,成功融入软件开发过程;出现新的探索,如面向对象设计,大规模软件设计的一些总结和思考
90年代初Perry和Garlan正式推出软件体系结构的主题
00年代初建立一个比较系统的软件系统结构方法体系 -
基于重用的大规模软件开发
框架:领域特定的复用技术;基本思想是根据应用领域的共性和特点建立体系结构,实现其中比较固定的部分;留下变化的部分等待开发者补充
构件:代码实现层次上的复用技术;基本思想是给所有的构建定义一个接口标准,这样就可以忽略每个部件内部的因素,实现不同构件的通信和交互(COM和JavaBean就是90年代产生并流行起来的构建标准) -
web应用的开发方法
90年代早期,人们使用html开发静态的web站点
90年代中后期,ASP,JSP,PHP,JavaScript等动态web开发技术开始流行
90年代后期,人们建立了web程序的数据描述标准XML -
软件过程
过程模型:RUP,敏捷,产品线
过程改进:CMMI
开源软件有所发展;遗留软件;商用货价商品
反向工程
螺旋模型和并行开发(颜色条带的宽度表示所做工作的多少)
-
开源软件
-
Summary
以商业为目的,以企业为中心,解决信息孤岛
大规模软件
web应用
软件架构
特定领域方法
重用
风险驱动
RUP
CMMI
2000’s
互联网,敏捷,计划驱动
-
图示
-
以消费者为中心
-
虚拟计算机
Internet
嵌入式设备
.Net,J2EE,Web Service
Linux,WinCE,iOS,Android
团队开发 -
抽象软件实体
UML2.0
模型驱动的开发和面向服务的架构
敏捷 -
软件开发方法
延续90年代技术进展
web技术发展
领域特定的软件工程方法(以网络为中心的系统,信息系统,金融和电子商务系统,高可信系统,嵌入式和实时系统,多媒体、游戏和娱乐系统,小型移动平台系统) -
软件过程
敏捷,平衡
-
软件从商业到职业
-
Summary
大规模web
更大规模消费群体
领域
敏捷
2010’s later
- 云
- 众包
- 社交媒体
- 大数据
- AI
- 可穿戴设备
- 最近热门概念
开发运维放在一起
Devops
微服务
CI/CD持续集成和持续交互
Service Mesh(如图)
混沌工程
Summary
- 50年代
不要忽视科学
Look before you leap(avoid premature commitments)
Avoid inflexible sequential processes - 60年代
Think outside the box
Respect software’s defferences
Avoid cowboy programming - 70年代
尽早避错
Determine the system’s purpose
Avoid top-down development and reductionism - 80年代
提升生产力很多办法
对过程有利的对产品也有利
小心银弹 - 90年代
时间很宝贵
软件应该对人有好处
快但不要急 - 00年代
If change is rapid, adaptability trumps repeatablity
Consider and satisfy all of your stakeholders’ value propositions
Avoid falling in love with your slogans - 10年代
Keep your reach within your grasp
Have an exist strategy
别尽信