软件开发:导言
关于软件开发、SDLC 和流程的一些想法。
尝试一种方法,并实践它。
如果失败了,就坦诚承认,然后尝试另一种。
但无论如何,一定要尝试些什么。
— 富兰克林·D·罗斯福
背景
我是一名软件开发团队负责人,我经常需要解释我们在更大的图景中做什么。这是我关于如何向新入职的开发人员解释我们所做的一切的思考实验。
博客一本书:软件开发
我想到一个捕捉我 25 年职业生涯中吸取的教训的好方法,那就是挑战自己写成一本书。这是我的尝试,我决定在**正式**自费出版整本书之前,先把这本书写成博客。
这是导言,它**太长了**,但我添加了一些自然的断点和图片,以便您可以在几个不同的会话中阅读它。
我在 IT 行业工作了二十五年,其中大部分时间是软件开发人员。我注意到大多数初级软件开发人员(以及许多经验丰富的开发人员)认为他们的工作是编写代码。然而,实际上,您作为开发人员所能做的最有价值的事情之一就是**警告不要编写代码**。
对于软件开发人员来说,关于他们的角色从哪里开始到哪里结束的指导并不多,但成长意味着您的角色必须拓宽(成为高级软件开发人员、软件架构师或解决方案设计师)。然而,角色之间的界限模糊,使得公司和个人难以确定任何特定软件开发人员的定位。
本书的目的
由于角色的模糊性,关于软件开发人员做什么以及如何做的分歧常常很多。软件开发有流程吗?有些公司倾向于认为软件开发是有机的事情,开发人员是需要创造性自由的艺术家。直接动手干,看看能得到什么。其他公司则认为开发人员是流水线工人,应该坐在隔间里,按照指示编写代码。真相可能介于两者之间。
提供指导的灵活流程
我们需要一个灵活的流程,它可以在不扼杀创造力的前提下提供指导。这个流程可以为个人开发人员提供一个松散的工作结构,即使公司中没有人遵循特定的方法论。读完本导言后,您将对我提出的流程有一个更好的理解。我相信(也希望)您会看到这种松散结构可以为软件开发过程带来巨大的好处。
即使您决定不再继续阅读本书,我希望您会发现本导言是一个有趣的讨论,为软件开发作为一个流程带来了新的视角。为了开始我们的讨论,让我们回归基础。
软件开发人员做什么?
我相信我们需要一个简单、单一的定义来概括软件开发人员的工作。这个定义将成为我们在这本书中不断回归的基础,以确定我们现在的位置。
软件开发的第一原则
软件开发人员编写代码,将手动流程转化为自动化流程。
我们所做的就是这些。
您可能会认为这过于简单,无法涵盖所有软件。然而,如果您从抽象的角度考虑任何软件,即使是游戏,您也会发现它实际上只是一个已经转化为自动化流程的手动流程。
吃豆人作为一个手动流程
看看吃豆人电子游戏。最初,吃豆人可能是一个棋盘游戏,玩家掷骰子来移动吃豆人和幽灵。玩家可以决定吃豆人的方向,您可以转动一个指示器来确定每个幽灵的移动方向。当您沿着棋盘上的路径移动吃豆人时,您只需计算它每次掷骰子吃了多少点。接下来,您为每个幽灵掷骰子,并转动指示器以指示移动方向。每一轮,幽灵都有可能落在吃豆人棋子的位置并将其消灭。
当然,目标是让您的吃豆人吃掉所有的点,然后被幽灵吃掉。(有关吃豆人电子游戏的更多信息,请参阅 https://en.wikipedia.org/wiki/Pac-Man。)
现在我们知道了这些,编写电子游戏就会容易得多。电子游戏只是自动化了这个过程。代码是在后台“掷骰子”和“转动指示器”来移动幽灵。它还会更新幽灵的位置,使其看起来像是它们在移动。您看到了吗?这真的只是自动化。然而,您还学到了另一个与软件开发相关的で重要公理。
软件开发的第二原则
软件开发的第二原则程序预期执行的**所有**事情都必须为软件开发人员所了解。
就像棋盘游戏的设计者必须确切地了解规则如何运作才能创建游戏一样,软件开发人员也必须知道程序将要做什么,才能创建代码。
问题立即出现
这是问题所在。刚才我们谈到的关于吃豆人棋盘游戏的描述中,很多内容似乎很明显。这是人脑工作的方式。
“当然要掷骰子,”有人说。“否则你怎么知道每次吃豆人和幽灵要移动多远?”团队中的一个人可能觉得事情应该这样很明显。那些看起来很明显的**需求**甚至可能不会被过多地讨论。问题后来才出现,当**显而易见的假设**在许多团队成员心中实际上是不同的。
没有详细定义,开发人员会按自己的方式去做
也许吃豆人棋盘游戏根本不使用骰子。也许幽灵每次移动 X 个单位。重点是,如果没有实际的解释和描述,游戏构建者(类似于软件开发人员)可能会按照他自己的方式去做。然而,他的方式可能是完全错误的。
如果设计者和构建者是两个人,那么构建者的决定可能完全错误。此外,除非设计元素被恰当地描述,否则它可能会迫使开发人员(构建者)做出他认为正确的决定。例如,假设移动的描述如下:
每一轮,每个幽灵都会向随机方向移动随机数量的单位。
没有定义最大移动距离,所以现在任何幽灵都可以向一个方向移动无限个单位。所以现在,游戏创建了,吃豆人移动,然后一个幽灵会以无限的速度朝吃豆人移动,每次都消灭他。
我知道,这很荒谬。但让我们回到软件开发人员所做的原始定义:
开发人员编写代码,将手动流程转化为自动化流程。
自动化错误的流程
现在我们看到,如果手动流程没有被正确描述,或者根本没有被描述,软件开发人员(构建者)可能会自动化错误的流程。
这就是为什么在**制作软件**中,一个重要的部分是:**沟通**。
当然,沟通是所有业务挑战的根源。这是因为即使我们直接与某人沟通,我们也永远不知道对方知道什么,或者确切地在想什么。对于软件开发,我们可以关注两件事,以使我们的项目更顺利地进行。
沟通的两个核心挑战
- 建立共同的理解
- 捕捉适当的细节
建立共同的理解
我们为什么要开会?是为了讨论事情。我们为什么要讨论事情?
讨论事情的三个原因
以下三个方面很可能是大多数会议的基本驱动因素。
- **获得理解的基线**:确定其他人对主题的看法或了解
- **就讨论的主题达成共同理解**
- **决定行动计划** - 会议后我们将做什么?
会议失败
经常发生的问题是,一个团队可以在一次短时间的会议中产生成千上万的文字和数百个想法。通常,一个利益相关者可能会带一个开发团队开会,解释她对产品的期望。会讨论许多想法,人们点头表示同意,会议感觉很成功。然而,没有人能确定他们都对利益相关者想要的东西有相同的理解。他们很可能没有共同的理解。
有捕获到重要的细节吗?
另外,考虑一下大多数团队是如何捕获会议细节的。也许有人潦草地记下一些笔记。利益相关者可能会停下来问:“开发人员是否理解了这些,以便他们可以创建功能?”
非常聪明、经验丰富的开发人员可能能够“即兴发挥”,并且相当接近所需功能的一部分。问题在于细节太多了。你如何全部捕获?
其他开发人员对此整个过程完全不感兴趣。
唉!沟通
设计师/创意型人才(软件开发人员、肖像画家、歌曲作者等)通常不想多说话。因为他们忙于制作东西。这些开发人员**知道**讨论细节和收集需求是业务分析师的工作。
有时软件开发人员需要极其具体的细节,而创建和收集这类细节可能会
- 难以从业务用户那里获得
- (从开发人员的角度来看)很无聊
- 极难跟踪
- 很容易忘记
- 我提到过无聊吗?:)
出于所有这些原因(以及更多原因),软件开发人员试图忽略这些事情。毕竟,软件开发人员想要做的是编写代码。然而,**编写错误的代码是没有帮助的**,即使它能带来进展。“嘿,我写了一些代码,做了一些事情。”
你不能等到万事俱备才开始
反驳的是,在你开始编写代码之前,你**永远不可能拥有所有东西**。
再次,让我们回到我关于软件开发的第二原则:
软件开发的第二原则程序预期执行的**所有**事情都必须为软件开发人员所了解。
作为一名软件开发人员,你不能只是开始输入代码。好吧,你可以。不幸的是,许多软件开发人员(和开发团队)就是这样做的。但这通常是一个糟糕的主意。我的意思是,如果你对项目一无所知,而且你已经在编写代码,那么你成功的几率就很小。你必须至少对你试图创造的东西有一个初步的想法。
请记住,软件开发人员必须编写代码来创建软件,这些软件
- 满足利益相关者的期望
但是,正如我们所说,在你开始构建之前,你永远不会知道软件将做什么。这难道不是一个悖论吗?我承认感觉确实如此,但实际上有一个摆脱这个困境的方法。
团队需要一个流程
我到目前为止解释的所有内容都说明了为什么你必须拥有
- 一个流程(方法)
- 结构化但灵活的设计,允许您随时间更改内容
这两项内容在页面上看起来如此简短,但它们各自都包含着整本书。您中许多在 IT 行业经验更丰富的人,在阅读“方法”一词时可能感到不适。请注意,该词没有大写,也不是旨在唤起任何已定义的“方法论”(ISO 9000、Six Sigma、Agile Scrum)。
Jack Ganssle,嵌入式系统设计(2003 年 9 月)一种识别任何类型的业余组织的方法,无论是会计师、律师、手工艺品店还是软件开发人员,就是缺乏流程。
我指的是“方法”一词更基本的意思。
Dictionary.com 为我们的目的完美地定义了“方法”:
Dictionary.com“一种做事程序、技术或方式,尤其是按照确定的计划”
为了我们的目的,在《**软件开发**》中,我们将稍微修改该定义,以显示本书的重点。
软件开发 - 方法论一种通过适当的计划指导下的系统(软件)开发方式。
解决这两个问题的流程
在本文开头,我提到了两个问题:
- 建立共同的理解
- 捕捉适当的细节
《软件开发》通过展示使用特定工件和用户故事来有效捕捉适当细节的方法,指导您解决这两个挑战。第一章将把这一切说清楚。
您可以做三件事来立即提高沟通效率:
- **使用通用语言** - 每个角色都必须使用相同的术语来讨论期望的业务解决方案(无技术术语)
- **专注于名词**(系统中需要的东西)
- **专注于动词**(系统所需的功能)
在我们学习《软件开发》的过程中,我们将更详细地讨论这些内容。
击中你的目标
如果您的开发人员对产品的理解与利益相关者不同,您将永远无法达到目标。如果您没有以建立对预期结果的共同理解的方式捕获适当的细节,您将永远无法达到目标。
再次,这一切都基于软件开发的第二原则:
软件开发的第二原则程序预期执行的**所有**事情都必须为软件开发人员所了解。
《软件开发》有助于创建一个提供指导的流程,就像一张地图。
软件开发地图
《软件开发》将提供一张地图,让您能够为开发特定系统创建适当的计划。
地图会不会太受限制?
我相信“地图”一词在这里非常合适。考虑一张地理地图。它提供了具体的细节,但它并没有告诉你去哪里。地图也没有告诉你如何到达目的地。相反,它以现实的更简单抽象的形式展现了当前情况。
地图使用者决定目的地和到达目的地的路径。
地图提供指导,但它不强制执行特定路线。地图可能会标出更简单的路线(铺好的道路),或者它可能标出汽车无法通行的区域(山崖)。但是,如果地图使用者决定他将使用降落伞跳下悬崖,然后降落到下面的城镇,地图并不会阻止他。
《软件开发》的工作方式正是如此。它将为您提供沿途的指路标,显示最简单的方式——大多数旅行者最顺畅的路线。但是,您和您的团队可能会决定不走的路径。有很多时候您只是想抄近道,而且这样做很有意义。但是,您会清楚地知道自己抄了近道,并且能够解释为什么这样做。
《软件开发》将提供地图
《软件开发》将提供更大的地图作为指导。然而,每个读者将自己梳理出确切的路线,决定将使用哪些具体工件来描述软件的创建过程以及在此过程中做出了哪些决定。
地图的某些部分是每个软件开发团队都会使用的。
这些项目的例子包括:
- 数据库架构
- 类图
- 需求文档(由用户故事组成)
请暂时不要过于纠结于特定类型的工件,因为如果您这样做,您可能会认为我只是在谈论写大量的文档,并且我只是在伪装某种方法论,认为它们都一样,为什么还要费心。
不必要的文档扼杀创造力
我根本不是在谈论这个,我相信您在完成本导言章节时会同意。我首先是一名软件开发人员,我也讨厌不必要的文档。它扼杀创造力。
软件开发人员真正需要什么?
每个软件开发人员都需要一些东西:
- **一个基本的起点** - 我们应该构建的基本内容是什么?
- **前进的方向** - 代码应该如何创建?
- **继续的方式** - 软件开发人员将进行的日常工作的基本流程
- **回顾的方式** - 我们实际做了什么来创建软件?
-
- 在回顾时您可能需要了解的事物的示例:
- 配置 - 以便您可以部署
- 面向对象设计——以便您可以添加增强功能,或者更容易确定错误发生的原因
- 数据库架构——以便您知道数据存储在哪里,以便进行检查
- 等等。
- 在回顾时您可能需要了解的事物的示例:
《软件开发》将专注于满足这些需求,以指导软件开发人员始终了解她在整个系统开发生命周期中所处的位置以及她应该关注什么。
现在,让我们完成我们列表中的另一项(结构化但灵活的设计),并讨论它在我们《软件开发》中的含义。
结构化但灵活的设计
这里描述的特殊项,即结构化但灵活的设计,为软件开发人员提供了前进的方向。
软件设计:庞大且不断增长的知识体系
创建结构化但灵活的设计的能力促使开发人员学习一套特定的概念,这些概念来自一个庞大且不断增长的知识体系。
《软件开发》将重点关注学习 OOP 原则和设计模式等,但始终关注我们选择一种设计而不是另一种设计的原因。我们将始终专注于将设计作为创建工作软件的前进方向。只有在理解了为什么选择特定的前进方向并理解了我们所做的权衡之后,我们才会继续进行设计。
我们在《软件开发》中学到的内容将帮助您创建各种软件系统。
以下是我们将在书中涵盖的一些内容(完成的书籍中将包含更多内容):
- 需求:它们对开发人员意味着什么?
- 我以为 BA(业务分析师)会提供这些。(在此插入经验丰富的软件开发人员的狂笑。)
- 如何让人们告诉我他们真正想要什么?
- 有没有简单的方法可以获得系统摘要?
- 如何轻松跟踪需求(因为没有人跟踪)?
- 真正的面向对象编程(OOP)
- OOP 是为人类设计的,处理器不在乎(OOP 是一种组织代码的方式)
- SOLID 原则
- 使用接口实现灵活设计的强大功能
- 编写更少的代码意味着你在进步
- 像阅读书籍一样阅读你的代码——可读的源代码意味着更少的文档。
- 代码重用:圣杯!
- 处理错误,因为你知道它们的存在
- TDD、BDD - 在设计中构建质量
- 代码覆盖率 - 触及所有代码并知道哪些代码未被触及
- 软件开发模式
- 思考模式的新方式——许多开发人员认为这些是 GoF(四人帮设计模式书)中所写的某种魔法。在这里,您将学习模式背后的“为什么”。
- 可重用的 OOP 结构,可以帮助您快速解决问题并与开发人员沟通解决方案;MVC - 重点强调现代软件的关注点分离(SoC)。
- 真正的软件设计
- 真正的前进方向:将需求(用户故事)分解为领域模型类
- 便利贴方法:名词和动词
- 数据库作为开发人员
- 关系数据库的意义是什么?答案:结构
- 基本数据库设计、连接等
- 仓储模式
- 提高效率的工具
- Roundhouse
- Localdb(Microsoft“文件”数据库)
- SQLite 专章
- 版本控制(Mercurial 或 Git)
- VCS(版本控制系统)对于专业开发人员来说是不可或缺的。它不是开销,良好的 VCS 是开发人员最好的朋友。
- 企业模式
- 可重用的系统结构,帮助您解决企业挑战
- 集成解决方案 - 主要挑战之一是数据以不同的格式存储,但企业需要与各种系统共享某些数据元素。
- 可交付成果/里程碑
- 工作软件(最小可行产品 MVP)
- 持续交付和工具(构建和部署)的必要性
- 适当的 UML 文档
- 您需要向不同角色的人解释事物。这是您选择适当文档来向该人展示的方式。
- 首先是最高级别的抽象,只有在必要时才深入细节——这会加快沟通速度,使会议更高效!
- 您必须使用业务领域语言。您必须让每个人都使用相同的语言(通用语言),以便每个人都可以以相同的方式谈论事物。
- 这些 UML 文档将有助于创建我们的软件开发地图。
- 创建 UML 的最佳软件——Enterprise Architect——如果您是专业开发人员,则必不可少。
- 还提供良好的代码逆向工程和代码生成。
- 每个 UML 文档都带有“为什么”的解释——为什么您应该生成该文档。
- 大部分开发人员不知道他们为什么创建这些文档。阅读完《软件开发》后,您将能够生成和解释涵盖的每个 UML 文档,并在您决定不创建特定文档时为您的理由辩护。
我将如何向您展示我刚刚列出的所有这些内容?《软件开发》是否只会提供关于您在开发软件时会做什么的枯燥描述?不。
软件开发:设计和编写真实应用程序
在阅读《软件开发》的过程中,我们将设计和编写实际代码,这些代码我将在 GitHub 上提供。所有这些应用程序都将以某种方式链接在一起。换句话说,它们将共享数据,并且可以通过桌面应用程序访问,还可以通过 Web 和/或 Android 和 iPhone/iPad 应用程序访问。这将使我们能够看到软件开发地图的实际应用,并看到某些组件(OOP 结构)如何轻松地跨语言和平台边界重用。这就是流程和出色的 OOP 的力量。
现在,让我们结束这个导言。
这是某种敏捷技巧吗?
我之前告诉过您,这本书并非基于某种巨大的方法论。然而,经过大量阅读最佳实践和各种方法论后,我在我所有的基本流程理念上都与敏捷宣言的原始原则保持一致。在您皱眉并认为我试图强行推销敏捷之前,请阅读敏捷宣言的十二条简单原则:http://agilemanifesto.org/principles.html
它们确实很棒,因为它们很简单。它们很短。它们没有被包装在某种五百页的书里。我提到它们是因为《软件开发》非常侧重于该宣言中的一个特定原则。这是所有软件开发人员最应该关心的原则。
软件开发:始终关注工作软件
《软件开发》方法将始终关注有助于我们交付工作软件的内容。
这是十二条原始敏捷宣言原则之一。
敏捷原则可工作的软件是衡量进展的主要标志。
在我们学习本书的过程中,我们将始终关注 MVP(最小可行产品)和工作软件。我希望这将使《软件开发》成为一本生动的读物,因为读者将始终专注于开发一个可工作的软件系统。
我们在这里讲了很多内容,因为企业软件开发涉及许多领域。我试图创建一些讨论,让您从不同的角度思考流程,并希望这能让您想读更多。如果那样,让我们进入第一章,我们将从头开始:需求。我保证这将是一个快速的章节,它会让您以不同的方式思考需求。
历史
首次发布:2017-05-03 -- 最初发布于我的网站:http://raddev.us/CraftSW/post/introduction-what-s-it-all-about