软件开发过程 - 科学、工程、艺术,还是技艺?





5.00/5 (40投票s)
我们行业的一种有见地的看法
引言
普遍认为,软件开发过程是不完美的,有时甚至是极其糟糕的,原因可能涉及许多人为因素(管理、技能、沟通、清晰度等)和技术因素(工具、支持、文档、可靠性等)。然而,当我们谈论软件开发时,我们却会用到各种科学/正式的术语。
- 几乎所有大学都有计算机科学课程。
- 我们在简历上使用“软件工程师”这样的术语。
- 我们使用“艺术”(如“软件开发的艺术”)一词来承认其创造/创作过程(唐纳德·克努特的《计算机程序设计艺术》第一卷于1968年出版)。
- 甚至在2009年还诞生了一个“软件技艺宣言”(“拓展阅读”链接比宣言本身有趣得多)。
关于软件开发的文献充斥着关于方法论的短语,这给了无知的群众、新手程序员、经理甚至资深开发人员一种温暖而虚幻的错觉,认为软件开发存在某种可重复的过程,足以配得上“科学”和“工程师”这样的词汇。那些认识到这些方法论松散本质的人,可能会觉得将软件开发过程描述为一门“艺术”或一门“技艺”更自在,甚至可能接近于“巫术”。
我们所用术语的词源
作为引言,我们将使用这些术语的词源作为意义的基础。
科学
“已知的、通过学习获得的(某事)知识;信息;” 还表示“知识的保证、确定性、确实性”,源自古法语 science “知识、学习、应用;人类知识的集合”(12世纪),源自拉丁语 scientia “知识、了解;专家能力”,源自 sciens(属格 scientis)“有智力的、熟练的”,是 scire “知道”的现在分词,可能最初意为“将一件事物与其他事物分开、辨别”,与 scindere “切割、分割”有关,源自 PIE 词根 *skei- “切割、分裂”(也是希腊语 skhizein “分裂、撕裂、劈开”,哥特语 skaidan,古英语 sceadan “分割、分离”的来源;参见 shed (v.))。
自14世纪末在英语中表示“书本知识”,也表示“一个特定的知识或学习分支”;还表示“熟练、灵巧;狡猾”。自1400年左右表示“经验知识”;也表示“一项技能、手工艺;一个行业”。自14世纪末表示“人类知识的集合”(尤其指“通过系统观察、实验和推理获得的知识”)。现代(有限的)含义“关于特定主题或推测的、有规律的或系统性的观察或命题的集合”可追溯至1725年;在17-18世纪,这个概念通常被称为哲学。自1670年代起,有“非艺术类学科”的含义。
(来源)
工程师
14世纪中期,enginour,“军事引擎的建造者”,源自古法语 engigneor “工程师、建筑师、战争引擎制造者;策划者”(12世纪),源自晚期拉丁语 ingeniare(参见 engine);“发明家、设计者”的普遍含义可追溯至15世纪初;民事含义,指公共工程,可追溯至1600年左右,但在19世纪才成为该词的常用含义(因此有民用工程师的持续区别)。“火车司机”的含义最早可追溯至1832年,美式英语。古希腊的“引擎制造者”是 mekhanopoios。
(来源)
艺术
13世纪初,“因学习或实践而获得的技能”,源自古法语 art(10世纪),源自拉丁语 artem(主格 ars)“艺术品;实用技能;一项业务、技艺”,源自 PIE *ar-ti-(也是梵语 rtih “方式、模式”;希腊语 arti “刚刚”,artios “完整、合适”,artizein “准备”;拉丁语 artus “关节”;亚美尼亚语 arnam “制造”;德语 art “方式、模式”的来源),源自词根 *ar- “组合、连接”(参见 arm (n.1))。
在中世纪英语中通常带有“学术和学习的技能”的含义(约1300年),尤其指七门科学或博雅教育。这个含义在文学学士等学位中仍然存在。人类“工艺”(与自然相对)的含义可追溯至14世纪末。 “狡猾和诡计”的含义最早可追溯至1600年左右。“创意艺术的技能”的含义首次记录于1610年代;尤其是绘画、雕塑等,从1660年代开始。该词的更广泛含义在 artless(无技巧的)中仍然存在。
(来源)
技艺
古英语 cræft (威塞克斯方言、诺森布里亚方言),-creft (肯特方言),最初意为“力量、体能、威力”,源自原始日耳曼语 *krab-/*kraf-(也是古弗里西亚语 kreft,古高地德语 chraft,德语 Kraft “力量、技能”;古诺尔斯语 kraptr “力量、美德”的来源)。在古英语中,其含义扩展到包括“技能、灵巧;艺术、科学、天赋”(通过“心智力量”的概念),这导致晚期古英语中出现了“行业、手工艺、职业”的含义,也表示“被建造或制作的东西”。该词在中世纪英语中仍用于表示“威力、力量”。
(来源)
方法论(方法)
另外再说一句
15世纪初,“对疾病的规律、系统性治疗”,源自拉丁语 methodus “教学或前进的方式”,源自希腊语 methodos “科学探究,探究方法,调查”,最初意为“追求,跟随”,由 meta- “之后”(参见 meta-)+ hodos “旅行,道路”(参见 cede)组成。 “做事的方式”的含义可追溯至1580年代;“有序性、规律性”的含义可追溯至1610年代。指与俄罗斯导演康斯坦丁·斯坦尼斯拉夫斯基相关的表演理论,可追溯至1923年。
(来源)
共同主题
查看这些词的词源,可以看出一些共同的主题(使用令人惊叹的在线思维导图工具MindMup创建)
我们从中得到了什么联想?
- 科学:技能
- 艺术:技艺、技能
- 技艺:艺术、技能、科学
- 方法论:科学
有趣的是,“工程师”一词并不直接与科学、艺术、技艺或方法论的词源相关联,但可以说这些概念是“工程”的组成部分(图表使用旧的Visio绘制)
这只是任意的,并不意味着我们立即暗示软件开发就是工程,但它确实给了我们对称自己为“软件工程师”可能意味着什么的 ধারণা(dàrná - 想法、概念)。
科学方法
https://en.wikipedia.org/wiki/Scientific_method
有多少软件开发人员能够脱口而出地描述科学方法?这里有一个描述
(http://idea.ucr.edu/documents/flash/scientific_method/story.htm)
科学方法是一个持续的过程,通常始于对自然界的观察。人类天生好奇,因此他们常常对看到或听到的事物提出疑问,并常常提出(假设)解释事物为何如此。最好的假设会带来可被各种方式测试的预测,包括对自然界进行进一步的观察。总的来说,对假设最强的检验来自仔细控制和重复的实验,以收集经验数据。根据测试与预测的匹配程度,最初的假设可能需要进行修正、改变、扩展甚至拒绝。如果某个假设得到非常充分的支持,就可能发展出普遍的理论。
尽管程序因研究领域不同而异,但它们之间经常共享可识别的特征。科学方法的总体过程包括提出猜测(假设),从中推导出逻辑结果的预测,然后基于这些预测进行实验。假设是基于形成问题时获得的知识提出的猜测。假设可能非常具体,也可能很广泛。然后,科学家通过进行实验来检验假设。根据现代解释,科学假设必须是可证伪的,这意味着有可能确定一个实验的可能结果与从假设推导出的预测相冲突;否则,该假设就无法有意义地检验。
我们可以将其总结为一个迭代过程:
- 观察
- 提问
- 假设
- 创建测试
- 收集数据
- 修正假设(返回第3步)
- 发展普遍理论并检验其与其他理论及现有数据的相符性
软件开发:知识获取和原型/概念验证
我们可以将科学方法的步骤映射到包括知识获取和原型的软件开发过程中
- 观察当前流程。
- 就当前流程提问,以建立模式。
- 假设如何自动化和/或改进这些流程。
- 创建一些测试,以衡量成功/失败以及性能/准确性的提高。
- 为我们的测试收集一些测试数据。
- 创建一些原型/概念验证,并根据反馈(关于新流程是否满足现有流程要求、是否成功、以及/或是否提高了性能/准确性)来修正我们的假设。
- 将原型提炼成通用解决方案,并验证它们与其他流程和数据的一致性。
我们在哪里失败
软件开发实际上在这些步骤中的大部分或全部都失败了。科学方法通常应用于对自然的观察。就像对自然界的观察一样,我们的观察有时会得出错误的结论。正如我们观察到太阳围绕地球运行并错误地提出了地心说理论一样,我们对流程的理解也充满了错误和遗漏。就像观察自然界一样,我们最终会遇到现实的严峻考验,即我们对该过程的理解是不完整或不正确的。一个陷阱是,与自然界不同,我们还有一个缺点,即在我们进行原型制作和试图证明我们的新软件流程更好时,旧流程也在不断发展,所以当我们发布应用程序时,它就像一辆新车驶离展厅一样,已经过时了。
此外,软件开发过程总体上,尤其是知识获取阶段,通常无法确定如何衡量现有流程的成功/失败和性能提高/准确性,仅仅因为我们作为开发人员缺乏测量现有流程的工具和资源(当然也有例外)。毕竟,我们试图替换一个流程,而不仅仅是理解一个现有、不可变的流程并在此基础上积累知识。在我们几乎无法描述现有流程时,如何准确衡量新流程带来的成本/时间节省?当我们每个人都对旧流程有“文化知识”时,如何比较使用新流程所需的培训?我们如何克服对新技术的阻力?大自然并不关心我们通过创造疫苗和基因疗法来治愈癌症是否能改善生物过程,但秘书和固守陈规的工程师 alike 都非常关心需要新技能和可能威胁到他们工作的新流程。
而且,现有流程的改进想法往往来自不完整(或完全遗漏)的观察和问题,但从第3步开始,就想象出了某个软件解决方案,可以“修复”经理或 CEO 认为可以改进的任何概念,是的,在许多情况下,工程师也认为可以改进——我们看到市场上充斥着新的框架、新语言和分叉的 GitHub 仓库,它们都声称能改进别人对一个所谓有缺陷的流程的解决方案。其结果是纸牌屋般的文档不清、bug 满载的实现。其结果就是 Stack Overflow 的存在。
至于最后一步,将原型抽象为通用解决方案,这是软件开发中最大的失败——重用。正如 Douglas Schmidt 在《C++ Report》杂志上所写,在1999年
尽管近年来计算能力和网络带宽已大幅提高,但网络应用程序的设计和实现仍然成本高昂且容易出错。大部分成本和精力来自于整个软件行业核心模式和框架组件的不断重新发现和重新发明。
请注意,他写于17年前(本文撰写时),而这句话今天仍然适用。
并且
重用在软件社区已经是一个热门话题,讨论了30多年。许多开发人员通过机会主义地应用重用,例如通过复制粘贴代码片段从现有程序到新程序中,成功地进行了重用。机会主义重用对个人程序员或小团队来说在有限范围内效果很好。然而,它无法跨越业务部门或企业进行扩展,以提供系统的软件重用。系统的软件重用是缩短开发周期和成本、提高软件质量以及通过构建和应用多用途资产(如架构、模式、组件和框架)来利用现有成果的有前途的途径。
然而,像历史上许多其他有前景的技术一样,软件的系统重用并未普遍带来质量和生产力的显著提高。
一线希望,勉强算是
当然,我们可以将各种 Linux 发行版安装到从台式机到树莓派或 Beaglebone 等单板计算机的任何设备上。交叉编译器允许我们在多个处理器和硬件架构上编译和重用代码。.NET Core 是开源的,可以在 Windows、Mac 和 Linux 上运行。Python、Ruby 和 JavaScript 等脚本语言将底层编译实现隐藏在程序的潜意识中,从而为我们的定制应用程序提供代码可移植性。然而,我们仍然陷入施密特先生所说的“组件和基于框架的中间件技术”的领域。使用这些技术,我们仍然需要“重新发现和重新发明”大量将这些组件粘合在一起的“胶水”。
工程方法
什么是工程?
工程是将数学、经验证据以及科学、经济、社会和实践知识应用于发明、创新、设计、建造、维护、研究和改进结构、机器、工具、系统、组件、材料、流程和组织。(来源)
真的吗?我们就有脸称我们所做的是软件工程?
-
“应用”只能假设对所适用列表项有深刻的理解。
-
“为了”只能假设在必要技能集上的熟练。
-
而“新事物”当然假设1)它能正常工作,2)它能足够好地被使用,3)人们会想要它并且知道如何使用它。
工程意味着知识、技能以及最终产品的成功采用。为此,已经开发了正式的方法论,例如,能源部系统工程方法论(SEM)
能源部系统工程方法论(SEM)为信息系统工程、项目管理和质量保证实践和程序提供指导。该方法论的主要目的是促进开发可靠、经济高效的基于计算机的解决方案,同时高效利用资源。使用该方法论还将有助于项目的状态跟踪、管理控制和文档工作。(来源)
工程流程概述
(来源)
注意一些措辞
- 促进开发
- 可靠的
- 经济高效的
- 基于计算机的解决方案
并且
- 该方法论还将有助于
- 状态跟踪
- 管理控制
- 以及文档工作
这实际上听起来像是尝试成功地将科学方法应用于软件开发。
另一个工程模型 - 螺旋模型
有许多工程模型可供选择,但这里再介绍一个,螺旋模型。它由阶段、评审和迭代组成(来源)
- 阶段
- 初始阶段
- 细化阶段
- 构建阶段
- 过渡阶段
- 审查里程碑流程
- 生命周期目标审查
- 生命周期架构审查
- 初始运行能力审查
- 产品就绪审查+功能配置审计
- 迭代
- 迭代结构描述:8周迭代的构成
- 设计期活动
- 开发期活动
- 收尾期活动
在每个阶段,定制工程组(CEG)与客户密切合作,建立明确的里程碑来衡量进展和成功。(来源)
这稍微有点像敏捷的“客户协作”,但请再次注意以下概念:
- 项目计划
- 测试计划
- 支持文档
- 客户签署规范
以及隐含的正式性
- 调查
- 设计
- 开发
- 测试和用户验收
真正的软件工程几乎需要熟练的专业人员,无论他们是开发人员、经理、技术撰稿人、合同谈判代表等。当然,各种技能水平的人都有空间,但一个真正的工程团队的结构是“初级”人员受到指导、监督,并获得与其技能水平相适应的任务,事实上,即使是“资深”人员也会互相审查工作。
我们在哪里失败
相反,我们有了敏捷开发及其宣言(来源,粗体为我添加)
- 个体和互动超越流程和工具
- 可工作的软件超越全面的文档
- 客户合作超越合同谈判
- 响应变化超越遵循计划
我们如何能不得出结论,敏捷开发完全不是工程?
敏捷宣言似乎专门淡化了软件开发的科学方法,也淡化了实际工程对软件开发人员和经理所需技能的要求,而是强调一种定义不清的涉及人员、互动、协作和灵活性的软件开发心理学方法。虽然这些也是必要的技能,但它们并不比软件开发所需的技能和正式流程更重要。事实上,敏捷在每个要点上都创造了两种对立的局面,常常导致过度倾向于左侧,例如,“代码就是文档”。
从实际经验来看,宣言最好是这样写,将“超越”一词替换为“和”
- 个体和互动和流程和工具
- 可工作的软件和全面的文档
- 客户合作和合同谈判
- 响应变化和遵循计划
然而,这种方法很少被那些急于使用新潮技术开始编码的“过度热情的编码者”所接受,也不被那些(错误地)认为“超越”能降低成本和上市时间,而“和”会(错误地)增加成本和上市时间的管理者所接受。与任何方法一样,必须在适合业务领域和待交付产品的基础上达成平衡,但这种对话很少发生。
无论如何,敏捷开发不是工程。但它是一种方法论吗?
软件开发方法论:它们真的算吗?
正如 Chris Hohmann 所写
我选择了Macmillan在线词典,找到了以下定义:
方法(名词):思考或处理某事的一种特定方式
哲学:影响某人决策和行为的一套信念。一个人用来应对生活的普遍信念或态度
方法论:用于完成特定类型工作的方法和原则,特别是科学或学术研究
我们将强加给软件开发过程的任何结构视为一种方法、一种哲学,还是一种方法论?
所谓的“方法论”
维基百科有一个页面这里和这里列出了数十种哲学,IT知识门户列出了13种软件开发方法论这里。
- 敏捷
- Crystal
- 动态系统开发
- 极限编程
- 特性驱动开发
- 联合应用开发
- 精益开发
- 快速应用开发
- 统一过程
- Scrum
- 螺旋(不是前面描述的螺旋开发模型)
- 系统开发生命周期
- 瀑布(又称传统)
甚至这个列表也遗漏了所谓的测试驱动开发和模型驱动开发等方法论。
由于方法论源自希腊语methodos:“科学探究,探究方法,调查”,Macmillan对方法论的定义似乎足够合理。让我们看看两种最常见(且被视为对立)的所谓方法论:瀑布和敏捷。
瀑布
瀑布模型是一种顺序的(非迭代的)设计过程,用于软件开发过程,在该过程中,进展被视为稳定地从概念、启动、分析、设计、构建、测试、生产/实现和维护等阶段向下流动(如同瀑布)。瀑布开发模型起源于制造业和建筑业:高度结构化的物理环境,在这些环境中,事后更改成本高昂,甚至不可能。由于当时没有正式的软件开发方法论,这个面向硬件的模型被简单地应用于软件开发。
瀑布模型的第一个正式描述通常被引用为Winston W. Royce在1970年的一篇文章,尽管Royce在那篇文章中并没有使用瀑布一词。Royce将该模型呈现为一个有缺陷的、无效的模型;这在关于软件开发的写作中通常用来描述对常用软件开发实践的批评性观点。
“瀑布”一词最早的使用可能是在Bell和Thayer 1976年的一篇论文中。
1985年,美国国防部在其与软件开发承包商合作的标准DOD-STD-2167A中捕获了这种方法,该标准规定“承包商应实施一个软件开发周期,包括以下六个阶段:初步设计、详细设计、编码和单元测试、集成和测试。”(来源)
瀑布模型实际上可以归类为一种方法,因为上面提到的六个阶段没有具体的指导——它们需要成为开发周期的一部分,但对每个阶段应用的任何具体科学严谨性完全缺失。具有讽刺意味的是,该过程起源于制造业和建筑业,这些行业在施工开始前通常会进行大量的数学分析/建模。当然,在20世纪60年代,电子硬件的建造成本很高,而且,通过科学方法进行的严格的电气电路分析可以大大降低事后更改的成本。
敏捷
有各种各样的敏捷软件开发图示,我选择了一个与上面“科学方法”大致对应的图示
(来源)
讽刺的是,IT知识门户将敏捷描述为“一个用于进行软件工程项目的概念框架。”很难理解一个概念框架如何被描述为方法论。充其量它似乎是一种方法。但更有说服力的是,当谈到软件开发过程时,“方法论”一词似乎与“科学探究,探究方法,调查”没有关联。
软件开发作为一门技艺
技艺是一项需要特定技能和熟练工作知识的业余爱好或职业。(来源)
历史上,一个人在技艺方面的技能分为三个等级:
- 学徒
- 熟练工
- 技艺大师
当我们把软件开发看作一门技艺时,一个优点是我们可以摆脱科学方法及其对自然世界和物理过程的强调。我们也摆脱了将某种方法、哲学或方法论应用于软件开发过程的困境。相反,将软件开发视为一种技艺,强调的是工匠(男或女)的技能。我们还可以开始根据上面工程部分讨论的普遍技能来建立“技艺技能”的排名。
学徒
学徒期是一种培训新一代从业者从事某一行业或职业的体系,包括在职培训和通常伴随的学习(课堂工作和阅读)。学徒期还使从业者能够获得在受监管的职业中执业的许可。他们的大部分培训是在为雇主工作期间完成的,雇主帮助学徒学习他们的行业或职业,以换取他们在达到可衡量能力后继续为期一段时间的劳动。学徒期通常持续3到6年。成功完成学徒期的人达到“熟练工”或专业认证能力水平。(来源)
熟练工
“熟练工”是指成功完成了建筑行业或技艺的官方学徒资格的熟练工人。他们被认为具备能力并被授权在该领域作为完全合格的雇员工作。熟练工通过教育、监督经验和考试获得执照。[1] 尽管熟练工已完成行业证书并能够作为雇员工作,但他们还不能作为自雇的技艺大师工作。[2] “熟练工”一词最初用于中世纪的行业公会。熟练工每天都获得报酬,‘journey’这个词就是由此而来——在法语中,journée 的意思是“一天”。每个独立的公会通常承认三个等级的工人:学徒、熟练工和大师。熟练工,作为一名合格的技工,可以成为大师,经营自己的企业,尽管大多数人继续作为雇员工作。(来源)
技艺大师
技艺大师或技工大师(有时只称为大师或宗师)是公会成员。在中世纪的公会体系中,只有大师和熟练工才能成为公会成员。有抱负的大师必须经历从学徒到熟练工的职业链,然后才能被选举成为技艺大师。然后,他必须提交一笔钱和一个杰作,才能实际加入公会。如果杰作未被大师们接受,他就不能加入公会,可能余生都将是一名熟练工。起初,在中世纪大学中,获得“文学硕士”学术学位的人也被视为他们各自学术领域的技艺大师。(来源)
我们在这种体系中处于什么位置?
虽然我们都从学徒开始,“培训”通常通过书籍和互联网的匿名性以及代码营、同事和查看他人代码来实现,但我们最终会发展出各种技术和人际交往能力。软件开发作为一种贸易技艺,有点独特,因为我们总是根据我们试图使用的技术处于不同的水平。所以当我们使用“高级开发人员”这个词时,我们实际上是在暗示我们拥有至少相当于熟练工的技能。这三个贸易技艺等级的常见联系之一是,有一位技艺大师与学徒和熟练工一起工作,并实际上认证他们进入下一步。此外,成为一名技艺大师需要开发一个“杰作”,这很讽刺,因为我知道一些自认为是“高级”但只有失败软件项目经验的软件开发人员。
正如 Donald Knuth 在《计算机程序设计艺术》的序言中所写
这本书……旨在培养读者掌握程序员技艺的各种技能。
我们在哪里失败
与软件开发过程的类比包括代码审查、结对编程,甚至是雇员与合同工或企业主的区别。不幸的是,软件开发的技艺模式并没有真正被采纳,也许是因为雇主不想使用一个可以追溯到中世纪时代的体系。代码审查,如果进行了,也可能非常肤浅,并非系统开发过程的一部分。结对编程通常被认为是浪费资源。公司很少提供相当于“成就证书”的东西,当人们不再上学,学习学校从未教过的技能时(整个计算机科学学位课程在培养至少一名软件开发熟练工方面也存在疑问)。
此外,鉴于软件开发领域的新颖性以及快速变化的工具和技术,与技艺大师一起工作的机会往往很难获得。在许多情况下,人们最多只能将从其他技术中获得的通用原则应用于新技术中的学徒工作(除了“读书”和在 Stack Overflow 上查找简单问题这一历来做法)。在许多情况下,成为熟练工或技艺大师的过程是与同行进行自助式学习的过程。
软件开发作为一门艺术
(抱歉打扰读者,但克努特先生将此事表达得如此精妙,我无法做得更好。)
再次引用 Donald Knuth
“为数字计算机准备程序的这个过程尤其吸引人,不仅因为它在经济上和科学上都有益,而且因为它是一种美学体验,很像创作诗歌或音乐。”以及:“我试图包含所有关于顺序计算机编程的、既优美又易于表述的已知思想。”
因此,编程伴随着一种美学体验,程序可以具有优美的特质,也许代码的美学体验在于其能够轻松地描述(或自我描述)算法。在他的精彩演讲《计算机程序设计艺术》(在线 PDF)中,克努特说道:
“与此同时,我们实际上已经成功地将我们的学科变成了一门科学,而且方式非常简单:仅仅将其称为‘计算机科学’。”他提出了关于科学与艺术的鲜明观点:“科学是我们如此深刻理解以至于可以教给计算机的知识;如果我们不完全理解某事,那么处理它就是一门艺术。鉴于算法或计算机程序的概念为我们提供了检验我们对任何主题知识深度的极其有用的方法,从艺术走向科学的过程意味着我们学会了如何自动化某些东西。”
对软件开发作为一门艺术的简洁描述——学习某事的程度足以自动化的过程!但还有更多。
“……我们应该不断努力,将每一门艺术转化为科学:在这个过程中,我们提升了艺术。”一个有趣的观点。他还引用了 Emma Lehmer(1906年11月6日 - 2007年5月7日,数学家),她在1956年写道,她发现编码是“一门严谨的科学,也是一门引人入胜的艺术。”克努特说:“我作为教育家和作家工作的目标是帮助人们学会编写优美的程序……即使是汇编语言,编写优美程序的可能性也是我最初热衷于编程的原因。”
还有:
“有些程序很优雅,有些很精致,有些闪闪发光。我的主张是,可以编写出宏伟的程序,高尚的程序,真正壮丽的程序!”
克努特接着讨论了程序美学的具体元素:
- 它当然必须正确运行。
- 它不会很难更改。
- 它易于阅读和理解。
- 它应该以优雅的方式与用户交互,尤其是在从人为输入错误中恢复时,以及在提供有意义的错误消息或灵活的输入格式时。
- 它应该有效地利用计算机资源(但要在正确的地方和正确的时间,并且不要过早优化程序。)
- 美学满足感是通过有限的工具实现的。
- “使用我们的大型机器及其花哨的操作系统和语言似乎并没有真正激起对编程的热爱,至少一开始是这样。”
- “……我们自己的教育应该利用有限资源的思想。”
- “请给我们提供易于使用的工具,尤其是用于我们日常任务的工具,而不是提供我们需要与之搏斗的东西。请给我们提供鼓励我们编写更好程序的工具,通过增强我们在这样做时的乐趣。”
克努特在他的演讲中总结道:
“我们已经看到,计算机编程是一门艺术,因为它将积累的知识应用于世界,因为它需要技能和独创性,尤其因为它能产生美的对象。一个下意识地将自己视为艺术家(或女艺术家)的程序员会享受他所做的事情,并且做得更好。”
读完克努特的话,人们可以理解在6502处理器和第一代Apple II、Commodore PET和TRS-80出现时所经历的热情。人们可以看到这种热情在树莓派、Arduino和Beaglebone等单板计算机上的复苏。事实上,每当有新技术出现(例如物联网)时,我们经常会看到业余爱好者对其充满热情。为什么?因为作为一个新想法,它触动了我们的想象力。同样,新的语言和框架也会点燃一些程序员的热情,原因同样是新颖事物所具有的想象力、创造性。
我们在哪里失败
不幸的是,我们也未能将艺术性带入软件开发。复制粘贴不是艺术。不一致的代码风格不美观。产生16字节十六进制错误代码的操作系统的用户界面不优雅。NPM(举例)依赖关系(这里有很好的例子)的噩梦并不优雅、不美观,当然也不好用。克努特提醒我们,编程在很大程度上应该是愉快的。那么,为什么我们创造了像VB和JavaScript这样我们爱恨交加的语言,使用了像HTML和CSS这样复杂且在各种浏览器和浏览器版本中支持不完整的语法,为什么我们容忍它们?但更糟糕的是,为什么我们自己编写丑陋、难以阅读、难以维护的代码?我们是否曾从审美的角度看待编程?不幸的是,在最后期限和绩效评估的世界里,我们似乎已经失去了(如果曾经有过的话)艺术性地编程的能力。
结论:那么,软件开发过程是什么?
大多数软件开发过程试图复制经过充分开发的与自然和物理建筑打交道的过程。这是错误的方法。软件通常不涉及事物,因为人们(通常)可以就观察和“科学”达成一致。相反,软件开发涉及人(以及他们的怪癖)和概念(人们常常对此有分歧)。一个显著的方面是当软件被设计来控制硬件(一个事物)时,无论是 ATM 的出钞机、自动驾驶汽车还是航天器。因为“事物”是已知的,所以软件开发过程就有了坚实的构建基础。然而,软件开发中的许多方面缺乏坚实的基础。关于哪种方法论最佳的辩论是不恰当的,因为多年来提出的所谓方法论中,没有一种是真正的方法论。谈论方法和哲学在喝啤酒时可能很有趣,但这真的能促进过程的进步吗?
事实上,定义软件开发过程的问题本身就是错误的,因为根本没有正确答案。重点应该放在开发人员自身的技能上,以及他们如何以艺术性的方式将未知转化为已知。如果非要说的话,软件开发过程需要像一门技艺一样对待,在这种技艺中,熟练的人指导不熟练的人,并且技艺大师以某种有形的方式认可学徒或熟练工的“升级”。“过程”最好被描述为通过形式化和可以与他人分享的知识,将艺术转化为科学的过程。在过程中,我们所做的工作必须是个人满意的。虽然“它能工作”能带来满足感,但真正的工匠也能从创造美观的事物中获得个人满足感,无论是(举几个例子)在他们的编码风格中、编写优美的算法,还是优雅地应用某种技术或语言特性来解决复杂问题。当我们批评别人的作品时,仅仅计算通过单元测试的数量是不够的。真正的杰作包括过程、代码和用户体验,所有这些都应该结合艺术和科学的方面。如果我们以这种方式看待软件开发,我们最终可能会到达一个更好的地方,在那里,过程可以真正被称为方法论,并且我们可以说语言和工具是真正被工程化的。
那么,什么是高级开发人员或软件工程师?
也许:一个高级人员或自称为软件工程师的人,能够应用科学方法,并且拥有正式的工作流程方法论,展示出在该领域、工具和语言方面的技能,被视为技艺大师(即,有可靠的往绩记录,能够教导他人等),并且还视开发为一门艺术,这意味着它需要创造力、想象力、跳出 said 技能的思维能力,并且这些技能是以审美感来应用的。
历史
- 2016年9月21日:初始版本