我如何在软件项目开始时就做好准备?[关闭]


64

我是一名有1年经验的程序员,最近我意识到我很少正确地启动一个项目(我的大部分副项目),通常项目周期会像

  1. 从一些用例开始
  2. 开始编码
  3. 意识到一些我不能很好处理的事情,并且在当前的代码库中不合适。
  4. 重写大部分代码

这可能会发生几次

所以我的问题是

  1. 这种做法是普遍的,还是暗示我没有能力?
  2. 我如何在这方面提高自己?

29
完善!这就是所谓的学习:)胜任!=第1天有效

6
您的有趣问题是题外话,因为它看起来像职业建议。顺便说一句,我也建议为一些现有的自由软件项目做出贡献,您会学到很多东西(从社区的开发人员那里,他们中的一些人今天比今天更专业)
Basile Starynkevitch

6
如果您找到完美启动每个项目的方法,请告诉我们。或写一本书,成为百万富翁。
2016年

1
@Qingwei,您说过从用例开始,而不是定义它们。定义它们将是一种分析,即。用户需求。我认为最好在早期对大多数用例进行更彻底,详细的了解。我的意思是,在稍后阶段仅找到一个新的用例,通常可能意味着大量的返工。最好在设计上比在实现上做返工。
布拉德·托马斯

1
我想这取决于您与谁交谈,但IMO用例仅是要求。应该完全没有任何设计决定地编写它们。分析主要包括设计/定义系统架构。因此,用例不属于分析阶段的一部分。话虽如此,通常发生的事情是编写一些用例详细信息,更新架构图,然后迭代回用例,以在进行架构图时识别出所做的更改,并根据用例的更改来更新图。然后,您将不断迭代,直到对两者都满意为止。
Dunk

Answers:


70

您描述的周期是正常的。改善情况的方法不是避免这种循环,而是精简循环。第一步是接受:

  1. 这几乎是不可能知道的一切都在一个项目上的一天。
  2. 即使您以某种方式知道了一切,到项目完成时,某些事情(客户的要求,他们所从事的市场,您正在使用的技术,客户的愿望)也会发生变化并在您知道的至少部分无效或不正确的内容。

因此,不可能预先计划所有事情,即使您可以,遵循该计划也会导致您构建不完善或过时的东西。知道了这一点,我们将变更纳入了我们的计划中。让我们看看您的步骤:

  1. 从一些用例开始
  2. 开始编码
  3. 意识到一些我不能很好处理的事情,并且在当前的代码库中不合适。
  4. 重写大部分代码

这实际上是一个很好的起点。这是我的处理方法:

1.从几个用例开始

好。通过说“用例”,您将专注于该软件的用途。通过说“几个”,您并没有试图发现所有东西。您要坚持可管理的工作量。我在这里添加的只是对它们进行优先级排序。与您的客户或最终用户一起,为这个问题找出答案:

我可以给您提供的最小,最简单的软件是什么,它可以改善您的状况?

这是您的最低可行产品 -小于此值的产品对您的用户无济于事,但任何较大的产品都可能计划得太早。获得足够的信息来进行构建,然后继续。请注意,此时您将一无所知。

2.开始编码。

大。您会尽快开始工作。在您编写代码之前,您的客户将获得零收益。您花在计划上的时间越长,客户等待无回报的时间就越长。

在这里,我会提醒您编写好的代码。记住并遵循SOLID原则,围绕易碎或复杂的事物编写体面的单元测试,对任何您可能会忘记或以后可能引起问题的事物进行记录。您希望对代码进行结构设计,以使更改不会引起问题。为此,每当您决定以这种方式(而不是那种方式)构建某些东西时,都要对代码进行结构化,以使尽可能少的代码受该决定的影响。通常,执行此操作的一个好方法是分离代码:

  • 使用简单的,离散的组件(取决于您的语言和情况,该组件可能是函数,类,程序集,模块,服务等。您可能还具有大型组件,这些组件是由较小的组件构建而成的,例如具有很多功能的类或具有很多类的程序集。)
  • 每个组件执行一项工作,或与一件事情相关的工作
  • 更改一个组件的内部工作方式不应导致其他组件发生变化
  • 应该组件使用或依赖的东西,而不是获取创建它们
  • 组件应向其他组件提供信息并要求他们进行工作,而不是获取信息并自己进行工作
  • 组件不应访问,使用或依赖其他组件的内部工作方式-只能使用其公共可访问的功能

通过这样做,您可以隔离变更的影响,以便在大多数情况下,您可以在一个地方解决问题,而其余代码则不会注意到。

3.在设计中遇到问题或不足。

这会发生。这是不可避免的。接受这个。当您遇到这些问题之一时,请确定是哪种问题。

有些问题是您的代码或设计中的问题,使他们难以执行软件应做的事情。对于这些问题,您需要返回并更改设计以解决该问题。

某些问题是由于没有足够的信息或以前没有想到的东西引起的。对于这些问题,您需要回到您的用户或客户端,并询问他们如何解决该问题。找到答案后,您便可以更新设计以进行处理。

在这两种情况下,您都应注意代码的哪些部分必须更改,并且在编写更多代码时,应考虑将来可能需要更改的部分。这样可以更轻松地确定哪些部分可能过于互连,哪些部分可能需要更隔离。

4.重写部分代码

一旦确定了更改代码的方式,就可以进行更改。如果您的代码结构合理,则通常只涉及更改一个组件,但是在某些情况下,可能还涉及添加一些组件。如果发现必须在许多地方进行很多更改,请考虑一下原因。您是否可以添加一个将所有这些代码都保留在内部的组件,然后让所有这些地方都使用该组件?如果可以,可以这样做,下次您必须更改此功能时,可以在一个地方进行。

5.测试

软件问题的常见原因是对要求的了解不足。这通常不是开发人员的错-通常,用户不确定他们也需要什么。解决此问题的最简单方法是扭转问题。每次执行这些步骤时,不问“您需要软件做什么?”,而是向用户提供您到目前为止所构建的内容,并询问他们“我是否构建了它-它可以满足您的要求吗?”。如果他们回答“是”,那么您就可以解决他们的问题,并且可以停止工作!如果他们拒绝,那么他们将可以更具体地告诉您您的软件出了什么问题,然后您可以改进该特定问题并返回以获得更多反馈。

6.学习

当您经历此周期时,请注意发现的问题和所做的更改。有模式吗?你可以改善吗?

一些例子:

  • 如果您发现自己忽略了某个用户的观点,是否可以让该用户更多地参与设计阶段?
  • 如果您必须更改某些东西以使其与某种技术兼容,那么您是否可以构建一些东西来在您的代码和该技术之间建立接口,而只需要更改该接口?
  • 如果用户对UI中的文字,颜色,图片或其他事物不断改变主意,您是否可以构建一个组件来为应用程序的其余部分提供这些组件,以便它们全部集中在一个地方?
  • 如果您发现很多更改都在同一组件中,那么您确定该组件仅坚持一项工作吗?你能把它分成几小块吗?您可以更改此组件而无需接触其他任何组件吗?

敏捷

您正在朝着这里迈进的是一种称为敏捷的工作方式。敏捷不是一种方法论,它是一整套方法论,其中包含了全部事物(Scrum,XP,看板,仅举几例),但它们的共同点是事物会发生变化,并且作为软件开发人员,应该计划适应变化,而不是避免或忽略它们。以下是其一些核心原则,尤其是与您的情况相关的原则:

  • 不要做比您可以自信地预测的进一步计划
  • 让事情随你而去
  • 与其一口气制造大型产品,不如先制造小型产品,然后逐步改进它
  • 让最终用户参与该过程,并获得及时,定期的反馈
  • 检查自己的工作和进度,并从错误中学习

5
“太好了。您将尽快开始工作。在您编写代码之前,您的客户将获得零收益。您花费在计划上的时间越长,客户花费在等待无偿回报上的时间就越长。” 完全不同意这一点。您花在计划上的时间越少,客户花费在等待真正有效且无回报的事情上的时间就越长。
Lightness Races in Orbit

4
@RobCrawford:在“无计划”和“过度计划”之间有一个完整的连续体。完全放弃“计划”或“愿景”可能会让您陷入困境。敏捷不是要“不计划”,而是要避免依赖不确定的元素并能够随心所欲地更改目标:即使模糊/不精确,您仍然需要某种总体目标,否则就无法衡量您发展的是进步还是外向。
Matthieu M.

7
我认为所有反对“缺乏计划”的人都完全掩盖了第一步是确定最低限度可行产品的事实。这必然需要一些计划。在我看来,这篇文章的重点在于不鼓励尝试先获得完美的设计。取而代之的是,所以要进行一些计划,不要花太多时间试图预先确定所有内容。
jpmc26 2016年

3
哇,所以炸了。正如评论员指出的,我不主张进行零计划。我要说的是-以及敏捷所说的-不要做太多的计划。我明确地说:“不要比您可以自信地预测到更进一步地计划”。人们说我主张“直接进行编码”应该注意,编码是步骤2,步骤1是…… 计划中。诀窍是要进行足够的计划,以确定对用户有帮助的最小产品,然后再为他们提供该产品
anaximander '16

3
最后,Agile同意计划太少了。它仅表明还有太多这样的事情。
anaximander '16

14

这很正常。

您可以采用以下两种方法之一:

  1. 欢迎变化

如果您认为自己做错了,则必须建立一个开放的代码库以供更改。通常,这涉及到在有关重构的书的结尾处获取代码,并从一开始就以这种方式构建代码(可分解性,良好的测试覆盖范围……)。

  1. 避免改变

在这种情况下,您必须先进行BDUF(大设计)。您必须做很多纸上的原型制作工作,与潜在的用户或自己通过橡皮鸭来讨论想法,在原型或模型中尝试各种事情,写下完整的规范,只有当您确定了解决方案后,才最终可以开始编码了。这样做实际上并不能消除意料之外的变化,只是在第一年左右就减少了一点。因此,您仍然必须构建代码以使其易于更改。

因此,基本上,改变是必然的。假设它将发生。相应地构建您的代码。在实践中,您可以在前期设计和刚刚开始编码的方法之间找到中间立场,避免不必要的更改而不会陷入分析瘫痪。只需要一点经验。


11

软件开发已被描述为一系列固有的“邪恶”问题

霍斯特·里特尔(Horst Rittel)和梅尔文·韦伯(Melvin Webber)将“邪恶”问题定义为只有解决或部分解决*才能明确定义的问题。从本质上讲,该悖论意味着您必须“解决”该问题一次才能清楚地定义问题,然后再次解决它以创建可行的解决方案。数十年来,这个过程一直是软件开发中的母性和苹果派。

这完美地描述了您所面临的问题。从根本上讲,我们的工作很难。如果有一部分可以描述为“常规”,随着时间的流逝,我们将其隔离并自动化。因此,剩下的就是新的还是困难的。

还有其他方法可以克服此类问题。有些人花大量时间事先考虑问题,直到对设计满意后才编写代码。其他人则通过结对编程或仅是这样的站点,从已经解决了此类问题的人们那里寻求指导。

但是可以肯定的是,您的方法并不意味着无能。唯一的问题可能是,当您返回时是否没有在思考为什么选择以这种方式开始做事,以及是否可以在没有提示的情况下看到“更好”的方式。改写。

在很多情况下,您可以将其合并到下一次的设计过程中。在某些情况下,成本并没有(或者成本会比其他方法的成本高或高),您可以放心。


8
  1. 是的,这很普遍,除了“重写大部分代码”部分。您一开始就永远无法满足所有需求,因此,妥善应对变化非常重要。这就是“代码可维护性”概念的全部内容。当然,这也有助于花费更多时间来确定需求和设计。
  2. 首先,考虑一下过去的项目中需要进行哪些更改,以及如何预见或更好地进行准备。在项目开始时,请更多考虑用例的细节。在开始实施之前,请进行一些抽象设计(什么是代码的主要组件以及它们如何进行通信,它们的API是什么)。最重要的是,请尝试使代码尽可能简单,易于更改,并通读SOLID,DRY,KISS和YAGNI等概念。

6

这种做法是普遍的,还是暗示我没有能力?

这些不是互斥的。这种模式可能很常见,但您仍然可能不称职。您可以通过根据目标衡量绩效来确定您的能力。您达到目标了吗?

这种模式常见吗?不幸的是。许多人潜入项目中,却不清楚他们正在解决什么问题,如何设计正确的解决方案以及什么指标将构成成功。

我如何在这方面提高自己?

如果您决定去某个地方开始步行,然后发现一天的真正需要做的是将一头大象从开普敦运到纽约市,那么您花在步行上的所有时间都是浪费的。开始做之前,先弄清楚自己在做什么。

一旦开始做,请考虑:不必重写的代码看起来像什么?该代码:

  • 做一件有用的事。
  • 是否正确。
  • 是否具有足够的性能。

因此:您编写的代码越多,正确地完成一项有用的事情,就具有良好的性能,那么您将不得不重写的代码就越少。


1

我认为可以肯定地说,您离更好的工作方式还差得很远,而且您不是这条船上唯一的人。

我认为你缺少的是,虽然你确定是什么你想要的,你不停止做了同样的过程如何,你会做到这一点。

停止并思考如何整体解决问题的这一步骤称为设计,这是使您花费一些时间来开发系统的结构或体系结构的步骤,这样您所做的一切都将为最终解决方案做出贡献,例如一旦确定了边缘,就可以将拼图拼成拼图。

许多人没有执行此步骤,但是当我开始编码时,它是强制性的。我认为区别在于开发工具-虽然我是从文本编辑器开始的,但现在您拥有各种功能,可以跳入并键入内容。

因此,花一点时间找出它们之间的广泛领域,组件和互操作性,并在开始编写代码之前定义将构成您的解决方案的对象。它不必非常详细,并且可以理解,一开始它不会完全正确,所以它会随着时间的推移而发展,但是这样做的目的是帮助您避免浪费精力重新审视那些本不应该的事情。无需太多更改。


1

您已经有了一些不错的答案,但是您的问题使我想到了一些我想尝试解决的问题。

  1. 正如您提到的即将发生的变更一样,我建议您考虑一下事情如何影响您的项目,以及如何通过设计/编码选择最大程度地减少影响,同时生成人们经常在哪里进行后期变更的思维导图。凭借经验,您可以预知并编写一些灵活的代码来处理您认为重要的事情-尽管行业中对此概念存在分歧,因为有些人会反驳您在本身未明确要求的领域进行投资。

  2. 一个测试方面,为您的项目涉众准备一个原型可能是完善需求的好方法。但是,在开发过程中,您可以寻找“查看”代码中发生的情况的方法,而又不会引起很多混乱或复杂性。当然有可用的工具可以帮助您,但是如果您愿意的话,也可以在没有它们的情况下做很多事情。不管哪种方式,从代码中出来以敏锐的眼光看待正在发生的事情,都可能会提供各种类型的见解。

  3. 寻找共同的活动。您将发现自己一遍又一遍地处理相同的问题。一段时间后,您应该发现各种选择的不足或折衷,并采用一种可以帮助您避免这些选择的方法进行零投入。当然,如果您使用的是框架,则其中的某些问题可能已包含在您已经使用的工具中。

  4. 如果您在框架内工作,请花点时间,如果可以的话,请考虑如何从头开始。例如,您可以轻松地汇编请求消息,打开套接字并手动发出GET或POST请求。如果愿意,可以手动解析XML消息。无论您做什么,产生的问题和找到的答案都会提高您的技能。当然,您可以选择哪些类型的重要或重要的潜在问题。我会考虑这种个人发展,不希望在这里花很多时间。

  5. 银弹,方法和高嗡嗡声问题无处不在。基本上,使用信息的潜在现实并没有很快改变。请注意现有的框架,工具集或方法是在各种情况下的帮助还是阻碍。在大型公司中,尽管公司无法有效执行它们,但我已经尝试了许多方法。就像框架一样,方法论并不是基于高层功能团队实践的高安全性方法。

很难总结经验并使之易于获取。我猜想,将所有这些内容放在一起的一种简单方法是睁大眼睛,思考所看到的,永不停止学习。


1

我想添加一些指针

1)我个人发现从可视化内容开始非常有用。绘制框,箭头,线...不用管您使用哪种建模语言。首先,您要自己做。它应该有助于您的思想交流。

2)找到陪练伙伴 -从上方拿杯咖啡和活动挂图/图表等,然后到镇上。恕我直言,如果您没有匹配的技术技能,那就更好了。您来回反弹实现用例的想法。您发现一两个死胡同-找到了解决方案。头脑敏捷,与编写代码相比,在此阶段花费的时间通常更少,因为这样做不起作用,因此您必须杀死大量工作或重做它们

3)找到一个可以理解您可能从未完成过改进书面软件的老板。如果您总是插入新的功能/要求,而这些新功能/要求遗忘在您的办公桌上,而不关心您的软件,那么它将以错误,维护不友好和大量的毛发拖回您身边。获取此软件维护时间/预算分配!我想知道,魔术数字大约是每年开发该软件所需的20%的时间,以使其在使用期内保持其状态。

4)这个增量学习的过程永远不会停止(而且不应该)!您将在10年后回头微笑。

希望这对您有所帮助,并祝您好运!


应该读为“随便什么”。编辑了上面的帖子。
ChristianMeißler'16

很棒的建议!
2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.