向客户展示错误代码?


129

一位客户要求我重新设计他们的网站,这是另一位顾问开发的ASP.NET Webforms应用程序。这似乎是一个相对简单的工作,但是在查看了代码之后,显然并非如此。

该应用程序编写得不好。完全没有 它极易受到SQL注入攻击的影响,业务逻辑散布在整个应用程序中,重复很多,无用的代码无所作为。最重要的是,它不断抛出令人窒息的异常,因此站点看起来运行平稳。

我的工作是简单地更新HTML和CSS,但是许多HTML都是在业务逻辑中生成的,这将是一场噩梦。我对重新设计的估计比客户期望的时间更长。他们问为什么这么久。

我如何向客户解释这段代码有多糟糕?在他们看来,应用程序运行得很好,重新设计应该是一次性的。这是我对前任顾问的反对。我如何给出非技术客户会理解的简单而具体的示例?

更新资料

感谢您的所有回复。SQL注入攻击演示很有意义,我将在测试环境中进行演示。那只是该应用程序中许多问题的一部分。我一直在寻找方法来解释为什么其他部分(例如,在数据层中生成的html)需要用更好的实践来替换,以便进行html和css更新。这里有很多很好的建议,当我与客户交谈时,我会综合考虑。


97
演示SQL注入攻击?
奥斯汀·亨利

30
This application was not written well. At all.他们几乎从来没有。:)
haylem 2012年

15
除了像奥斯汀所说的那样展示问题。不要低估白板和记号笔的功能。大多数人对以图片形式说明的不良设计都反应良好。
Sirex 2012年

3
如果它不大-重写它,如果它不大-不要接受它
ren 2012年

4
客户说重新设计,他们认为是HTML / CSS。我会使用术语“缺乏模块化”,并强调“逻辑设计”与“演示”。建筑结构的隐喻是有用的。To make a change in the look of the living room, I had to go into the air-conditioning system.在良好的模块化设计中,此类事情不会发生。
Fuhrmanator 2012年

Answers:


144

非技术人员不是白痴(在大多数情况下)。如果您对技术论点保持足够的高水平,他们可以理解。选择一个您认为应该很简单的任务,然后逐步解释为什么并非如此。

我希望此更改是一个文件中的一个单词。更改它的最可能的地方似乎是在这里,但是当我在此处进行更改时,它只在一个地方起作用,而它在其他7个地方都坏了。当我修复一个位置时,它又打破了两个位置,从而产生了多米诺骨牌效应,所以我认为应该花10分钟才能完成的更改最终要花2个小时。那只是一个例子。那里还有很多意想不到的2小时任务。


10
鉴于存在如此多的错误报告,“它破了__个更多地方”确实似乎是描述多米诺骨牌效应的最佳方法……
Izkata 2012年

4
是的,我会在时间和成本之间建立更多联系。向他们展示您期望成本变化多少与最终导致成本变化多少有关。根据我的经验,除非您能证明他们的支出是其他支出的两倍,三倍或更多,否则客户很少会注意。
Tim O'Brien

87

代码结构,样式,技术债务是一件事-至少在最初,直到客户信任您之前-您将需要忍受。

安全漏洞是另一回事。

就个人而言,我会根据使用现有结构和样式所需的工作进行估算,同时明确代码库存在重大问题。我将单独提出安全隐患:在会议上演示数据库黑客攻击以将问题归宿。

当我与以前的客户使用忠诚礼品卡系统进行交易时,我感到非常高兴,当我在“我的”卡上放了5000英镑,并请他检查他的提款卡时。


38
+1演示SQL注入攻击的严重程度。在他们面前做。如果可能,视频记录他们的反应。
菲利普(Philip)

40
@Philip:...该演示最好应该在该应用程序的独立开发环境中。清除他们的生产数据库将证明这一点,但可能会丢失您的合同(并提起诉讼)。
FrustratedWithFormsDesigner 2012年

19
@FrustratedWithFormsDesigner,如果他们甚至有可用的开发环境...
棘手的怪胎

3
@FrustratedWithFormsDesigner:当然,不建议擦除数据库,无论多么容易和剧烈。但是提取私人数据,然后(小心地)更改一些金额(例如@Michael制作的礼品卡上的余额),可能对他们来说同样令人惊讶。对于其他几点,请明显地使您不需要看代码。首先转储表列表,选择一些有趣的名称,然后转储内容。如此脆弱的观点应该花不了太多。
哈维尔

76

这里有一些关于如何传达和传达给客户的很棒的建议。希望他们能为您还清。

主要红旗在这里!

如果客户要求您除了您同意的内容(HTML和CSS)之外不要进行任何其他更改,我将通过该项目并撤回我的出价。

即使对所有缺陷和安全性问题进行了书面且传达良好的概述,但潜在的责任仍然让我感到难以承受。即使客户在遭到黑客入侵或破坏后从未采取任何法律行动或要求修复;您的姓名和声誉仍然与工作相关!

您可能损失的远远超过获得的收益。


14
+1用于查看更宽的图像。如果您处理它并说完成了,则即使您仅继承了它们,也可能对错误和安全问题承担一些责任。如果有人操纵了我的制动器,而机械师修理了我的自行车,只是耸了耸肩,我可能还会考虑起诉他们……
sleske 2012年

2
+1这是一堂课程顾问需要花费太长时间来学习(而且,在经济困难时期,要继续学习这是一个困难的概念)。专业知识的价值既取决于您所做的工作,也取决于您拒绝的工作。
Tim O'Brien

2
+1这是我学到的艰辛教训,因此我的第一笔生意差点倒闭。在这些情况下,列出所有“缺陷”并报价以解决这些问题的成本通常要比客户愿意支付的精力更多。
Catharz

30

解释并可能证明其缺陷
当您对他说脏话时,就他们而言,您所说的一切可能都是热闹的。一旦向他们展示了如何通过SQL注入滥用他们的应用程序,那么您就突然成为一个值得信赖的人。您需要信誉才能重新谈判。这足以改变游戏规则,将其带给您。

对您的前任抱有慈善之心
这并不意味着假装错误不存在,但是如果您屈尊自大,就会失去信誉。除了可能给他带来疑问的好处外,不要对程序员说一句话。专注于代码,而不是编码器。让他们觉得您是“好人”会给您更多的谈判余地。“好人”从不说卑鄙的话。在向客户端解释现有的安全错误(例如SQL注入漏洞)时,我更喜欢这样说:

Web应用程序安全性是一个快速发展的领域。人们直到今天仍了解许多开发工具和技术,这些技术和工具在大多数这些利用尚未被很好地理解之前就已经进化了。为了保持安全开发的领先地位,您必须密切关注该领域,有时甚至更改您的整个开发风格。大多数程序员都不这样做。

好了 没有关于开发商的恶意话;他只是“大多数程序员”,这意味着他在相当不错的公司中。现在,您已经证明您不是 “大多数程序员”,这给了您一点信誉,并且也许是他们给您更多钱的原因。

协商新的安排
一旦客户了解他的应用程序可以被公众滥用,他将希望对其进行修复。您可能是他要问解决此问题的人。您可能会或可能不会想要这份工作,因此在与他们交谈之前,请仔细考虑一下。

至少,您希望有更多时间完成他们已经给您的工作。您已经为他们设置了足够的措手不及的漏洞内容,以至于它们可能无法使您达到最初的估计。但是,请确保客户知道您的身份,并且不会因为这种安排而将要解决的问题。

通常,开发人员(您)希望从头开始重做整个事情。在这种情况下,甚至可以选择。但是即使那样,客户仍然需要一些可以使他的业务保持运转的东西,直到新的应用程序被构建。这意味着,即使您从头开始,也可能需要对旧应用程序进行一些更新。


8
+1永不屈居。只要让事实说明一切……
sleske

4
为“对您的前任感到慈善” +1。
msanford 2012年

19

我以评论开始,因为起初我认为这是一个问题,但实际上可能并非如此。

我将充分记录您应该重新设计的所有内容,原因(如果他们不做更改会发生什么)以及对解决此问题的估计。对于您认为有安全隐患的任何事情,我都会格外谨慎。

在联系任何代码之前,我会这样做,并确保您的客户拥有此报告的副本,最好带有某种时间戳。这可能需要一些时间,但是如果其中一种安全风险得以实现,它也将为您提供帮助。如果您能获得表明他们已收到文档的签名,那就更好了。

当然,如果确实发生了,您可以指向您继承的原始代码的源代码控制,但是指向此文档并以一种更专业的方式说“看?我告诉过您”会容易得多。

该文档可以作为进一步讨论的起点,甚至可以由您的客户用来获得“合适的人”的许可以进行部分或全部更改。

话虽这么说,一旦客户无法理解风险,无论他们说要干活还是走开,他们都应该笑着承担。


希望他们实际上正在使用源代码控制。
伯纳德

6
好答案。但是,由于曾因类似情况(包括完整的文档和客户签字)而向法院提起诉讼,这仍然使我付出了很多金钱和头痛。
史蒂夫

5
原则上讲是个好主意-但是,请注意,这可能需要大量工作。这可能是只对大的工作实际,否则你会花50小时记录问题的一份工作,你只能法案20
sleske

@sleske:同意将进行大量工作,但如果发生最坏情况并且存在安全漏洞,希望也能对您有所帮助。至少,您需要说明您看到安全风险并且不想对这些预先存在的风险负责的内容。
桑科旺科(Wonko the Sane),2012年

2
@WonkotheSane:的确如此,但前提是您接受了该项目。如果问题很大,而您的计划工作很小,那么最好拒绝该项目。当然,您仍然应该记录您的顾虑(安全性和其他方面),但是,如果您从未参与过该项目,那么就不会有承担责任的风险。最终,您必须衡量您的客户是否愿意支付清理费用。
sleske 2012年

14

请记住,客户端会在维护他们的应用程序时向您寻求帮助。指出您对其应用程序发现的任何问题是您的专业工作。客户可能不知道这些问题是否存在,应该让他们知道。以他们可以理解的方式解释这些问题,并让他们决定如何进行。

使用真实的例子来说明这些问题,例如汽车抛锚或需要维修的洗衣机。重点是使用他们已经熟悉的示例。为了解释SQL注入,我将仅演示这是什么以及为什么会引起问题。

最后,您要传达的是,您关心被要求处理的应用程序的成功。


3
这完全不是一辆故障车,除非该车是由业余机械师用随机零件制造的。这就像一个无能的承包商建造的车库,业主希望OP放入自动开门器。OP发现车库不安全,需要立即进行大修。
凯文·克莱恩

2
想象一下一辆故障车,它使用胶带将零件固定在一起,并使仪表板无法向驾驶员显示任何警报或警告,而方向盘随时可能掉落。这需要一些创造力,但是可以使用不同的类比来说明问题。
伯纳德

或注意“定制”的缠绕麻绳加速器电缆,您可以将其绑在控制台上以进行手动加速。.“电传飞行”技术便宜。他们在“红色绿色秀”上所做的一切都可能适用。他们所拥有的“作品”,但它并不漂亮,经过粗略的检查,它似乎很脆弱,并且放大了任何更改的风险。
JustinC

1
如果我可以为此增加额外的票数,那纯粹是因为“记住客户会在维护他们的应用程序时向您寻求帮助”。
Daniel Hollinrake 2012年

7

我喜欢使用客户可以关联的类比。我为赢得工作而预先投入的工作量取决于客户打算花费的金额(100美元与20,000美元相差甚远)。注意我说“打算”。如果您没有得到所要的东西,那么您对所涉及的价值的个人估计就没有多大意义。

在您的情况下-再次取决于金钱-我可能会画一个盒子,从每一侧伸出一条线,然后对客户说:“这就是您现在如何可视化该软件。数据在一端输出而另一端全部输出看起来不错,干净简洁”。“这就是您认为软件在内部的外观”,然后绘制第三条线,将盒子内的两条线连接起来。

然后,我会像第一个一样画另一个盒子,外面有输入和输出线,除了这次我会说:“这就是软件现在盒子里真正的样子。” 然后这次将两条线连接起来,我会随机绘制一堆意大利面条,可能带有断点,连接点和涂鸦。

最后,我会说:“现在您要我做的是...”,然后在第一个框内画一个简单的形状,也许会碰到一个小半圈,然后说:“但是要做到,我d必须这样做...”,并在直线上画出一种看起来像螺旋形的龙卷风,然后继续...“以便绕过所有这些.....”,然后指向另一个盒子中的意大利面。

我认为这将在大约2分钟的时间内将问题带回家。如果他们仍然坚持要您这样做,请像上面其他人一样记录下来。


6

我如何向客户解释这段代码有多糟糕?

也许您可以使用类似房屋中的管道这样的类比,随着时间的流逝,在修复和改建后,它们变得如此善变和耦合,以至于在修复一件事时,会影响甚至破坏其他需要修复的东西,而您就无从得知所有发生这种情况的地方。

这是我对前任顾问的反对,所以我实际上如何给出非技术客户可以理解的简单而具体的示例?

没错,这是对前顾问在他们脑海中创造的任何视觉效果的反感。我的建议是按照您的要求做,并给出简单而具体的示例。由于这是重新设计,因此说明如何在已编译的代码中定义的HTML片段与HTML页面的其余部分一起显示,以及更改如何影响或不影响页面的其余部分。也许相同的编译代码在应用一些“业务”规则后会呈现标记。显示差异。

这是一个非常困难的普遍问题。祝你好运。


6

诚实坦率。

但最重要的是,不要从事无法满足您期望的工作。大多数人没有意识到承包商可以解雇客户,如果这项工作比其应有的麻烦多,他们会并且应该这样做。


3

这是我使用过的一个比喻(尽管我不保证它的有效性):想象他们的网站是一台物理机器,就像某种机械印刷机以某种方式接受输入。

他们可能认为这台机器具有在组件上执行X且在另一个组件上执行Y的组件。实际上,这是大约20台最相似的机器。他们中的一些不再做任何事情,他们都尝试执行其他人已经执行的功能,除了前一位顾问以外,没有人见过像他们之前完全一样的东西。

“在这里看到这个gizmo,它解析了post变量,然后将该组件发送到if-elses的兔子洞中?不仅有其中之一,而且每页(或其他内容)中都有其中之一,其中一些清理输入内容,有些不(或全部不),而且没有阅读我不知道的全部内容。”


“想象一下他们的网站是一台物理机器,就像一台机械印刷机”-这就是印钱!但是,由于它已经坏了,所以它没有印出尽可能多的钱……应该吸引他们,-)
Mawg 2015年

2

尚未真正提到的一点是,在这种情况下,您可能只是超越了客户真正想要的。过度成就感很棒,可以使您获得很多工作满意度。但是,如果客户根本不在乎,认为当前性能“足够好”并且只希望进行一些小更新,则可能无法说服他们在您的代码上进行大笔投资。

到那时,您可能需要决定是否坚持原则并拒绝从事会迫使您在尴尬的代码混乱中树立好名声的工作,或者是否可以nose之以鼻,参与进来,完成工作用一些胶带,然后付款。

如果您确实决定继续进行胶带工作,请确保进行记录,记录并保持尽可能透明。您想要做的最后一件事是,将来会因您警告客户端的应用程序缺陷而出了错,但该客户端当时认为不足以解决该问题。

就SQL注入风险而言,正如其他人所说的那样,您应该能够以显示风险的方式向他们证明这种风险,而无需在生产中实际进行任何破坏性工作。但是,如果他们看到了它,但又不在乎付钱给您修复它,那么您在这种情况下就已经做好了尽职调查。


0

进入项目并建议重写第一件事,执行一些小的修改子集,并使用这些子集来说明它本来可以更简单,更便宜,这真是小菜一碟。然后您将得到一个明显的案例,说明为什么在字体成本偏低的情况下,从长远来看,清洁剂开发成本的增加会导致较低的维护成本和更快的开发速度。

永远不要忘记,从根本上说,您是在要求他们付款,以使您的生活变得更轻松,在他们看来,只需要找到可以X功能,花费Y成本并放大项目复杂性的“家伙”,就可以消除机会。为了你。当您需要一个月的重写时间并且与原始开发人员会面时,才意识到这是一条艰难的路,只是要意识到整个应用程序是由开发人员在极其紧凑的窗口中编写的,他完全理解了所做出的所有折衷。如您所说,如果该应用程序内部看起来很糟糕,但外部功能很好,那么很有可能会这样。通常,代码库中的技术负担是代码开发所依赖的资源限制的产物,如果他们没有建立团队而是将事情外包出去的话...

我只是在说


0

我将在这里扮演魔鬼的拥护者(有点类似@khrome所说的话:“您没有付钱给客户以使您的生活更轻松”)。我什至会说您提出的案子过于单一,因为您以一般方式描述了该案。大多数新项目的新进顾问会对上一个项目产生不利影响...我并不是说这就是您正在做的事情,但是在我们看到示例之前,我不能简单地相信您的意思。

也就是说,我将尝试一点一点地解决您的问题:

  • SQL注入。好的,所以我想程序员正在使用字符串连接而不是参数化查询和/或存储过程。这非常容易修复,尤其是在ADO.NET中...我个人会向客户端提及它,但不会在其中带来太多麻烦。
  • HTML正在业务逻辑中生成,要解决它将是一场噩梦。好吧,伙计,这是您给我提供更多细节的地方之一。除非您使用的是MVC,否则这种趋势很容易发生……但这不一定是一件坏事……这是大多数程序员会说“ goto不好;从不使用”的东西之一,但是您知道吗?我在有意义的地方使用过goto!因此,您确定他们没有使用碰巧与业务代码DLL共享相同名称空间的帮助程序类吗?同样,隔离起来并不难。
  • 业务逻辑散布在整个应用程序中,有很多重复,无用的代码无所作为。。和?客户只是要求您更改HTML / CSS。您为什么要完全关心这些问题?
  • 它会不断抛出令人窒息的异常,因此站点似乎运行平稳。再次,非常模糊。在任何应用程序中异常都是正常的,这就是为什么我们在代码中包含try / catch子句的原因。除非它们在UI中冒出气泡并破坏用户体验(例如不必要地显示HTTP 500),否则我也不认为这是您应该关心的事情。

简而言之,我建议您走高路。如果您认为这不值得花时间,并且想以牺牲客户为代价来重写它,那么就放弃工作。认真地说,最后,客户花了您的时间使整个事情以最少的$$$运转。

根据我在该领域的多年经验,我总是说,我遇到的最好的程序员是那些可以通过编写最少的代码而不是重写整个代码来使系统稳定的程序员。

编辑:我已经看到我的答案不是最受欢迎的答案(我已经期望如此),但我坚持我的回答。我对此进行了编辑,以使其不那么狡猾。;-)


-1

当然,SQL注入攻击和应用程序中的其他功能缺陷已得到优先考虑,但您也可以“演示”不良的代码质量和做法。使用代码度量工具,您可以清楚地演示代码有多糟糕,并向他显示代码对于将来的任何更改和错误修复将增加多少成本。我不熟悉.net环境,但是我敢肯定有几个可以借鉴的。


为什么对此表示不满?当然,客户可能不是技术人员,但是代码指标会产生数字,每个人都可以理解。特别是如果有一个有据可查的,但不是太
讲究技巧的
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.