软件工程总结

软件工程(英语:software engineering[1]),是软件开发领域里对工程方法的系统应用。

1968年秋季,NATO(北约)的科技委员会召集了近50名一流的编程人员、计算机科学家和工业界巨头,讨论和制定摆脱“软件危机”的对策。在那次会议上第一次提出了软件工程(software engineering)这个概念,研究和应用如何以系统性的、规范化的、可定量的过程化方法去开发和维护软件,以及如何把经过时间考验而证明正确的管理技术和当前能够得到的最好的技术方法结合起来的学科。它涉及到程序设计语言数据库软件开发工具系统平台、标准、设计模式等方面。其后的几十年里,各种有关软件工程的技术、思想、方法和概念不断被提出,软件工程逐步发展为一门独立的科学

1993年,电气电子工程师学会(IEEE)给出了一个更加综合的定义:“将系统化的、规范的、可度量的方法用于软件的开发、运行和维护的过程,即将工程化应用于软件开发中”。此后,IEEE多次给出软件工程的定义。

在现代社会中,软件应用于多个方面。典型的软件比如有电子邮件嵌入式系统人机界面办公包操作系统网页编译器数据库游戏等。同时,各个行业几乎都有计算机软件的应用,比如工业农业银行航空政府部门等。这些应用促进了经济和社会的发展,提高人们的工作效率,同时提升了生活质量。

软件工程师是对应用软件创造软件的人们的统称,软件工程师按照所处的领域不同可以分为系统分析师系统架构师前端和后端工程师、程序员测试工程师用户界面设计师等等。各种软件工程师人们俗称程序员。

名称由来与定义

软件工程包括两种构面:软件开发技术和软件项目管理。[1]

  1. 软件开发技术:软件开发方法学软件工具软件工程环境。[1]
  2. 软件项目管理软件度量项目估算进度控制人员组织配置管理项目项目等。[1]

软件危机

主条目:软件危机

1970年代和1980年代的软件危机。在那个时代,许多软件最后都得到了一个悲惨的结局,软件项目开发时间大大超出了规划的时间表。一些项目导致了财产的流失,甚至某些软件导致了人员伤亡。同时软件开发人员也发现软 软件开发的难度越来越大。在软件工程界被大量引用的案例是Therac-25的意外:在1985年六月到1987年一月之间,六个已知的医疗事故来自于Therac-25错误地超过剂量,导致患者死亡或严重辐射灼伤[2]

由来

鉴于软件开发时所遭遇困境,北大西洋公约组织(NATO)在1968年举办了首次软件工程学术会议[3],并于会中提出“软件工程”来界定软件开发所需相关知识,并建议“软件开发应该是类似工程的活动”。软件工程自1968年正式提出至今,这段时间累积了大量的研究成果,广泛地进行大量的技术实践,借由学术界和产业界的共同努力,软件工程正逐渐发展成为一门专业学科

定义

关于软件工程的定义,在GB/T11457-2006《消息技术 软件工程术语》中将其定义为"应用计算机科学理论和技术以及工程管理原则和方法,按预算和进度,实现满足用户要求的软件产品的定义、开发、和维护的工程或进行研究的学科"。

包括:

  • 创立与使用健全的工程原则,以便经济地获得可靠且高效率的软件。[4]
  • 应用系统化,遵从原则,可被计量的方法来发展、操作及维护软件;也就是把工程应用到软件上。[5]
  • 与开发、管理及更新软件产品有关的理论、方法及工具。[6]
  • 一种知识或学科,目标是生产质量良好、准时交货、符合预算,并满足用户所需的软件。[7]
  • 实际应用科学知识在设计、建构计算机程序,与相伴而来所产生的文件,以及后续的操作和维护上。[8]
  • 使用与系统化生产和维护软件产品有关之技术与管理的知识,使软件开发与修改可在有限的时间与费用下进行。[9]
  • 建造由工程师团队所开发之大型软件系统有关的知识学科。[10]
  • 对软件分析、设计、实施及维护的一种系统化方法。[11]
  • 系统化地应用工具和技术于开发以计算机为主的应用。[12]
  • 软件工程是关于设计和开发优质软件。[13]

软件工程的核心知识(SWEBOK)

ACM与IEEE Computer Society联合修定的SWEBOK[14](Software Engineering Body of Knowledge)提到,软件工程领域中的核心知识包括:

软件工程与计算机科学

参见:软件工程主题列表

软件的开发到底是一门科学还是一门工程,这是一个被争论了很久的问题。实际上,软件开发兼有两者的特点。但是这并不意味着它们可以被互相混淆。很多人认为软件工程基于计算机科学信息科学就如传统意义上的工程学之于物理化学一样。在美国,大约40%的软件工程师具有计算机科学的学位。在世界其他地方,这个比例也差不多。他们并不一定会每天使用计算机科学方面的知识,但是他们每天都会使用软件工程方面的知识。

软件工程计算机科学
目标时间资源、人员这3个主要限制条件下构建满足用户需求的软件系统。探索正确的计算和建模方法,从而改进计算方法本身。
产品软件(比如办公包和编译器)。算法(比如希尔排序法)和抽象的问题(比如哲学家进餐问题)。
进度与时间表软件项目都有特定的进度与时间表研究项目一般不具有设置的进度与时间表
关注点软件工程关注如何为用户实现价值软件理论关注的是软件本身运行的原理,比如时间复杂度空间复杂度,和算法的正确性。
变化程度随着技术和用户需求的不断变化,软件开发人员必须时刻调整自己的开发以适应当前的需求。同时软件工程本身也处于不断的发展中。对于某一种特定问题的正确解决方法将永远不会改变。
需要的其他知识相关领域的知识。数学
著名的探索者和教育家巴里·勃姆戴维·帕纳斯佛瑞德·布鲁克斯艾兹赫尔·戴克斯特拉高德纳罗伯特·塔扬彼得·斯莱特艾伦·图灵姚期智
著名的实践者约翰·巴科斯丹·布里克林蒂姆·伯纳斯-李林纳斯·托瓦兹理查德·马修·斯托曼无。

例如彼得·麦克布尔(Peter McBreen)认为,软件工程意味着更高程度的严谨性与经过验证的流程,并不适合现阶段各类型的软件开发。麦克布尔在著作《Software Craftsmanship: The New Imperative》提出了所谓“craftsmanship”的说法,认为现阶段软件开发成功的关键因素,是开发者的技能,而不是“manufacturing”软件的流程

软件工程的现况

Capers Jones曾对美国软件组织的绩效做过评估,所得到结论是:软件工程的专业分工不足,是造成质量低落、时程延误、预算超支的最关键因素。[16]

2003年,The Standish Group年度报告指出,在他们调查的13522个项目中,有66%的软件项目失败、82%超出时程、48%推出时缺乏必需的功能,总计约550亿美元浪费在不良的项目、预算或软件估算上。[17]

没有银弹与人月神话

主条目:没有银弹人月神话

在1986年,IBM大型机之父佛瑞德·布鲁克斯发表了他的著名论文《没有银弹》,在这篇著名的论文中他断言:“在10年内无法找到解决软件危机的灵丹妙药”。从软件危机被提出以来。人们一直在查找解决它的方法。于是一系列的方法被提出并且加以应用。比如结构化程序设计面向对象的开发CMMUML等等。佛瑞德·布鲁克斯著名作品还有《人月神话》。

布鲁克斯在《人月神话:软件项目管理之道(The Mythical Man-Month)》提到,将没有**灵丹妙药(silver bullet)**可以一蹴而就,开发软件的困难是内生的,只能渐进式的改善。整体环境没有改变以前,唯一可能的解,是依靠的素质,培养优秀的工程师。[18]

软件工程与计算机程序设计

软件工程存在于各种应用中,存在于软件开发的各个方面。而程序设计通常包含了程序设计和编码的反复迭代的过程,它是软件开发的一个阶段。

软件工程力图对软件项目的各个方面作出指导,从软件的可行性分析直到软件完成以后的维护工作。软件工程认为软件开发与各种市场活动密切相关。比如软件的销售,用户培训,与之相关的软件和硬件安装等。软件工程的方法学认为一个独立的程序员不应当脱离团队而进行开发,同时程序的编写不能够脱离软件的需求,设计,以及客户的利益。

软件工程的发展是计算机程序设计工业化的体现。

软件开发过程

主条目:软件开发过程

软件开发过程是随着开发技术的演化而随之改进的。从早期的瀑布式(Waterfall)的开发模型到后来出现的螺旋式的迭代(Spiral)开发,以致最近开始兴起的敏捷软件开发(Agile),他们展示出了在不同的时代软件产业对于开发过程的不同的认识,以及对于不同类型项目的理解方法。

注意区分软件开发过程和软件过程改进之间的重要区别。诸如像ISO 15504, ISO 9000, CMM, CMMI这样的名词阐述的是一些软件过程改进框架,他们提供了一系列的标准和策略来指导软件组织如何提升软件开发过程的质量、软件组织的能力,而不是给出具体的开发过程的定义。

方法学

软件工程的方法有很多方面的意义。包括项目管理,分析,设计,程序的编写,测试和质量控制。

软件设计方法可以区别为重量级的方法轻量级的方法。重量级的方法中产生大量的正式文档

著名的重量级开发方法包括ISO 9000CMM,和统一软件开发过程(RUP)。

轻量级的开发过程没有对大量正式文档的要求。著名的轻量级开发方法包括极限编程(XP)和敏捷过程(Agile Processes)。

根据《新方法学》这篇文章的说法,重量级方法呈现的是一种“防御型”的姿态。在应用“重量级方法”的软件组织中,由于软件项目经理不参与或者很少参与程序设计,无法从细节上把握项目进度,因而会对项目产生“恐惧感”,不得不要求程序员不断撰写很多“软件开发文档”。而轻量级方法则呈现“进攻型”的姿态,这一点从XP方法特别强调的四个准则—“沟通、简单、反馈和勇气”上有所体现。目前有一些人认为,“重量级方法”适合于大型的软件团队(数十人以上)使用,而“轻量级方法”适合小型的软件团队(几人、十几人)使用。当然,关于重量级方法轻量级方法的优劣存在很多争论,而各种方法也在不断进化中。

一些方法论者认为人们在开发中应当严格遵循并且实施这些方法。但是一些人并不具有实施这些方法的条件。实际上,采用何种方法开发软件取决于很多因素,同时受到环境的制约。

软件工程的发展方向

敏捷开发”(Agile Development)被认为是软件工程的一个重要的发展。它强调软件开发应当是能够对未来可能出现的变化和不确定性作出全面反应的。

敏捷开发被认为是一种“轻量级”的方法。在轻量级方法中最负盛名的应该是“极限编程”(Extreme Programming,简称为XP)。而与轻量级方法相对应的是“重量级方法”的存在。重量级方法强调以开发过程为中心,而不是以人为中心。重量级方法的例子比如CMM/PSP/TSP

面向方面的程序设计(Aspect Oriented Programming,简称AOP)被认为是近年来软件工程的另外一个重要发展。这里的方面指的是完成一个功能的对象和函数的集合。在这一方面相关的内容有泛型编程(Generic Programming)和模板


软件工程的最大难题

转载于:https://www.ruanyifeng.com/blog/2021/05/scaling-problem.html

一、引言

大学有一门课程《软件工程》,研究如何组织和管理软件项目。

img

说实话,这门课不适合本科生,因为学生可能体会不到,课程到底要解决什么问题。只有亲身参与过大项目的开发,经历过大团队,才能感受为什么软件工程很重要,又很难做对。

软件开发有一个难题,叫做"扩展"(scaling),即怎样服务更多的用户。 你有10000个并发用户,跟你有10个并发用户,这是完全不同的概念,哪怕功能完全相同,背后的实现是完全不一样的。并发用户数上升一个数量级,软件就必须重构,大量问题随之产生。

img

大项目的技术难度高,管理难度更高,而且大团队的生产率往往很低,行动缓慢。 《软件工程》就是研究,如何扩展软件和团队,适应大项目的需要。

国外有很多专著,研究这个问题。前些日子,我读到一篇文章,推荐了两本书。第一本叫做《加速:构建和扩展高性能技术组织》,第二本叫做《规模:生物,城市和公司的普遍法则》。

img

img

我看了这两本书的介绍,觉得很有启发,下面就做一些摘录。

二、大项目的困境

一个典型的大型软件项目,开发过程通常是下面这样。

最开始的时候,它是一个小项目,开发人员就是两三个人,甚至可能只有一个人。产品比较简单,功能很有限。

img

第一版发布后,拿给客户使用,反响不错。客户要求的新功能,能够很快开发出来,Bug 修补也很快,因为早期客户往往可以与开发人员直接沟通,快速反馈。

公司于是决定投入更多人员,开发这个项目。团队慢慢变大了,软件开始变得复杂,开发速度逐渐变慢了,2.0 版花费的时间比预期要长一点。Bug 的修复难度开始增加。总之,新功能的开发日程变久了。

公司的自然反应是进一步扩充团队。但是更多的新成员其实会降低其他人的生产率,一个普遍现象是团队规模越大,每个人的平均生产率越低。

img

几年以后,代码逐渐老化,复杂性不断增加,项目开始停滞不前。某些极端的情况下,软件的维护成本变得非常高昂,并且几乎不可能进行更改。

最终,这个项目成为技术债务,等待被新项目替换。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-n2utsTlK-1660326005941)(https://cdn.beekka.com/blogimg/asset/202105/bg2021050819.jpg)]

三、为什么大项目的开发效率低?

大项目就像一头大象,让人望而生畏。可是一旦需要奔跑,大象就会步履蹒跚,被猎犬远远甩在后头。它快不起来的原因有两个。

(1)代码复杂度

随着代码量的增长,单个开发者想要理解整个代码库,变得越来越困难。如果团队超过五个人,每个人负责一个功能,那么单个人几乎不可能追踪系统的所有工作进度。

当你中途加入团队,整个项目是一个紧密耦合的大型系统,你又不理解系统的每一个工作细节。这时,你就不太敢修改以前的代码,因为不知道随之而来的全部影响。

img

你不真正理解系统,也就不会感到自己是代码的主人。你会很犹豫要不要重构,过时的代码开始累积,技术债务就这样出现了。长此以往,开发变得越来越不愉快和令人无法满意,最终导致人才流失。后面接手的新人,更难于重构那些遗留下来的代码。

(2)团队原因

随着团队成员的增加,交流成本开始指数式上升。如果整个团队有 n 个程序员,为了了解其他人的工作,你需要跟 n - 1 个人逐一交流(口头或者书面),那么整个团队的交流路径总数就是 n * (n - 1) / 2。这意味着,交流成本的增长速度是人员增长速度的平方,团队人数越多,协同的难度就越大。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5yGPhOiI-1660326005942)(https://cdn.beekka.com/blogimg/asset/202105/bg2021050822.jpg)]

大团队保持扁平化管理,也会越来越困难,必须拆分成较小的群体。这时,对等的交流会被自上而下的交流所取代。团队成员会感觉,自己从平等的利益相关者,转变为普通的工作人员,工作动机受到了影响,责任感和主人翁意识都会淡漠。

img

管理层为了解决问题,会尝试组建新团队和新的管理架构。但是,不管怎么做,大型组织都很难保持所有成员的积极参与。

四、解决方法:代码解耦

大项目的开发效率不高,把这个问题归咎于程序员的技术水平低和管理不善,都是没用的。 根本原因是软件规模的增长,必然使得代码和团队变得笨重。 除非很早就认识到问题的根据,采取缓解对策,否则前面描述的情况,迟早都会出现。

解决这个问题,要从代码和团队两方面着手。

代码层面的解决方法是,将软件解耦,拆分成组件或者模块,防止各个部分紧密地耦合在一起。每个组件和模块,都可以独立开发,通过公开的接口被其它部分调用。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-b1IbVWHX-1660326005943)(https://cdn.beekka.com/blogimg/asset/202105/bg2021050824.jpg)]

这样的话,就大大减轻了开发者的负担,只需要负责自己的代码即可,不需要关心其他部分的实现。每个部分都可以单独重构,不担心影响到其他部分。

五、解决方法:团队解耦

除了代码解耦,团队层面也需要解耦,要把人员分开。

这可以参考互联网的架构。互联网是迄今为止最成功的大型软件解耦实例,它之所以能够扩展,是因为它由一个个独立的节点组成。为了防止节点之间互相依赖,各个节点都遵循以下规则。

  • 遵守公开的通信协议。
  • 不需要了解其它节点的内部实现,就可以与之通信。
  • 节点之间不直接共享状态,只通过通信交换数据。
  • 每个节点单独开发和部署。

大团队也应该遵循类似的原则,进行解耦。

  • 每个子团队都可以独立运作,不依赖外部人员。
  • 子团队内部的运作,不需要被外部知道。
  • 子团队之间的协调,应该按照公开的协议和规则,最好能够自动完成,避免私下协商。

六、团队解耦的注意点

团队解耦有一些注意点。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-I9z5rNAl-1660326005943)(https://cdn.beekka.com/blogimg/asset/202105/bg2021050825.jpg)]

(1)子团队的人数不宜过多,每个子团队最好不要超过5个人。

(2)子团队应该是一个小型的全功能软件开发组织。

很多大团队按照人员角色分组,比如架构组、开发组、DBA 组、测试组、工程组等等,这是错误的。这样完全没有解耦,还是瀑布式流程,各组之间依然互相依赖,工作时必须与别组单独协商。而且,可能会产生利益冲突,比如,开发组希望尽快交付,而测试组希望多一点时间测试。

正确做法是按照软件的业务功能分组,每组负责一个全流程的软件大功能,设计、编码、测试、部署、支持等人员都在同一组。这样才能做到解耦,以及独立的交付和重构。每组内部使用什么工具、如何实现某个功能,都是自己决定,各组之间不需要共享内部细节,也不依赖别组的工作。

(3)大团队应该保障子团队的自主权,按照子团队提供的功能和商业价值,进行资源分配。

(4)软件架构师的角色很重要。

软件架构师的关注点,不应该是团队使用的工具和技术,而是各种服务与整个系统运行状况之间的协议和通信,保证代码和团队可以正确解耦。

(5)代码解耦和团队解耦的关系。

理想情况下,代码解耦与团队解耦保持一致,形成一对一的关系,一个子团队负责一个独立的模块。实际运作中,一个子团队负责几个模块也可以,但是一个模块不能由多个子团队来参与。

(6)通信(模块之间的、子团队之间的)尽量规范化,争取做到过程简单、文档充分,最好有规范的 API,这样无需任何人员交流,就能建立通信。


寻找软件工程化之路

转载于:https://zhuanlan.zhihu.com/p/371723195

工程,这两个字不知出于何处,但凡与之扯上关系,则表示得规规矩矩做事,按照科学的办法来搞。

近日图书馆逛,偶然看到一套搞桥梁工程的老前辈写的文集,遍历一遍,感受颇深,桥梁设计事关人命,必须依赖科学方法进行设计,施工,所以必要的设计图纸,建造方法一个也不能少,否则失去工程的意义,草台班子搭桥也叫工程吗?

又闻有句话:结果与过程的关系,有过程没结果是放屁,有结果没过程是垃圾。要做好事,做成事,必须讲究过程与结果,只有按照工程化的思想做事才能有好的结果,诚然不按照此也能做成事,但做成与做好,产品与精品绝不是一个字的差异,其可能比人与狗的差异还大吧。

又问:努力重要还是选择重要?我觉得是努力的选择重要,选择确定方向,否则逆风而行,南辕北辙,再多的努力都是白费力气,选择对方向并不意味着成功指日可待,不努力去实践会慢慢丧失机遇,机遇可得不可求,稍纵即逝,它不会等你准备好了再给你,机不可失,所以努力与选择缺一不可。

扯这么多与软件工程化有何关系?

自觉已搞软件多年,但始终与软件工程化相距甚远,设计20%时间,编码80%时间,期间需求不停变化,做的身心俱疲。

我理想的软件开发,一定是工程化的软件开发,首先是精心的软件设计,合理的编码开发,可测试,可扩展,软件才能好用。

近日看到canjs文档,自觉其是按照工程化的思维去做的,人家首先提出一个软件方面的挑战:创新与稳定的矛盾性。

大家都知道软件开发的技术日新月异,层出不穷的新技术逐渐淘汰老技术,在这种环境如何保持软件的稳定还能再创新不落后?微软的产品稳定性就很差,比如silverlight,WPF,WCF等,常常追求创新却干一段时间不干了,把别人丢在那不管了,又要别人学习新技术,但该软件试图平衡这种矛盾。

它是怎么做的呢?首先split to pieces,拆分成很小的块,然后再对不同的块进行assemble,组合,这样的好处是

1,小块的复用性很好;

2,可按照需求进行不同组合;

3,每个小块都有自己的版本,不断往前升级,推陈出新;

3,如果某些小块不合时宜或者落后于时代可以弃用,减少软件失效成本,也可以开发用新小块,与时俱进,这样来进行软件迭代升级。

4,注重测试,由于每个小块很小,很容易测试,这样就规避了应用过大集成测试带了的风险。

5,注重生成脚手架,这样规范了项目结构,便于批量化生产。

6,注重用户可定制,用户可以自定义,便于扩展。

还有很多可以借鉴的地方,就不再赘述,其创始人从全球最大的IT咨询公司—埃森哲出来,应该对于软件工程化有自己的主见与想法。

看得出软件做的很努力,但这么一个有这好思想的软件不火,就是我说的选择大于努力吧(也许有人说你说的xx都有,好吧,正如上所述产品与精品的区别,或者我孤陋寡闻),目前vue,react,angular三大马车之光芒掩饰其珍,但其软件工程化的思想值得借鉴。

看到这里的兄弟姐妹们,如果你也有这一方面的思考,可以私信我一起探讨,说不定哪一天可以一起开源个项目,共创软件工程化开发的一片天。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小熊coder

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值