您做出的最令人遗憾的设计或编程决策?[关闭]


57

我想听听您做出什么样的设计决策,以及它们如何适得其反。由于一个错误的设计决定,我最终不得不永远支持这个错误的决定(我也参与其中)。这使我意识到一个设计错误会永远困扰着您。我想向经验丰富的人们学习,他们经历了什么样的错误,以及从中学到了什么。

我确信这将通过帮助其他程序员不再重复这些决定而对他们有很大帮助。

感谢您分享您的体验。


19
在SO上花费太多时间!;)
Mitch Wheat

6
@George:似乎您的第一个链接是关于过度工程的,它可以与该线程切线相关,但不是重复的。第二和最后一个链接涉及编码错误和管理混乱,这两个都不是该线程的重复项。
朱丽叶2009年

1
这可能应该做成社区Wiki(编辑帖子时会有一个方框)。

3
我希望有一种投票的方式来对付结案。关闭投票?
Kieveli

5
所有封闭的选民怎么了?因此,如果不是CW,请提问者就问题提出一些表决。我对这个话题很感兴趣。不要让CW妨碍良好的主观问题。嘘,到处都是“ CW THIS”尖叫声。
syaz

Answers:



56

“稍后再做”
“以后”再也不会出现。


8
以后再也不会来。

从来没有。

有人说过,如果您现在没有时间进行此操作,是什么使您认为以后有时间进行修复?

4
我们称此为“永不重复”
NotMe,2009年

10
没有比临时解决方案更持久的解决方案了。
Dietbuddha 2011年


44

应用程序中的可配置性很好。太多的可配置性是使用和维护的噩梦。


2
是。真正。理想的做法是使所有内容都可配置,并告诉老板我们不再需要更改一行代码。

1
不幸的是,用户只能使用其中一个无限可配置的系统来进行我们的项目管理,我只能说,如果可以的话,我会向您投票一百万次。
HLGEM 2011年

配置中的过度灵活性通常是因为您无法在运行时执行任意代码,因此您需要预料所有事情。

与“硬编码”相对应,这称为“ spoftcoding”
deadalnix11年

42

从我的一个错误中,我学会了不要盲目地遵循数据库规范化。您可以,并且在某些情况下,您必须展平桌子。

我最终通过表来管理表的负载(通过模型),并且性能有些下降,而表却有些扁平化。


5
我完全不同意...我是一名软件工程师,我们被告知要始终规范化。真是糟透了。这仅仅是因为教师们还没有尝试使用真正复杂且性能依赖的数据库。

8
我可能会补充说,标准化当然也可以是非常积极的。

12
我认为程序员由于不充分的原因而无法快速进行规范化,但是,是的,盲从地遵守规范化规则是一个很大的错误。总的来说,我对软件开发的最大挫败之一就是有人说“我们必须做X”,而当我指出这将引起的所有问题时,他们回答:“那是不相关的。所有专家都认为X很好,因此,我们必须总是做X,没有例外。”

4
我的标准化方法总是直截了当的。我总是归一化,但是如果我发现少许展平可能会提高性能-我总是进行测试和基准测试,并且在大多数情况下要进行展平是值得的。
Eimantas

7
但是归一化就是乐趣!:)我是认真的,我喜欢设计数据结构。我要说的是,尽管很容易对规范化的架构进行非规范化,但事实并非如此。破坏它们之前,您需要了解规则。

36

在数据库中使用单个char来获取状态等信息。这一点都没有,与网络和任何SQL调用所引起的解析相比,使用更长的char()或nvarchar2()的开销微不足道。变得相当混乱或枯竭(不是为了状态,而是其他)。最好将人类可读的版本放进去,并且在您的Java模型中(以我为例)还具有一个带有匹配值的枚举。

我想这是过早的不必要和盲目的优化的一种形式。似乎使用单个字符可以拯救世界。除了不支持布尔值/位的数据库中的Y / N布尔值。


+1我们刚刚就此问题开会。我们得出了相同的结论。
APC

如果您的客户使用这样的缩写并且不想放弃它们怎么办?

对于现有系统,您当然需要兼容(我仍然会使用<code> MyEnum fromChar(char c)</ code>方法创建适当值的Java枚举)。对于新设计,请不要去那里!

一些数据库支持枚举,这些枚举既紧凑又可读,还可以很好地禁止意外值。如果可以,请使用它们。
巴特尔

2
几乎同样糟糕:在发现它不能成为索引的一部分之前,在MS SQL Server中使用BIT类型。
finnw

32

没有开发适当的数据访问层,而是在我的代码中到处都是sql,只是为了“快速”启动并运行它们。后来,随着项目的开始扩展和需求的变化,这成了一场噩梦。我当时不知道DAL是什么。

……很高兴我已经过去了,尽管我仍然看到拥有20多年“经验”的程序员这样做。


16
不记得我在哪里读的书,但是20年的经验和一年的经验重复19次之间是有区别的。
2009年

@乍得:在乔尔·斯波斯基的作品中。

+1:是的。然后尝试重构与该SQL捆绑在一起的所有逻辑……无论是内联,自由形式的SQL还是存储的proc。[是的-我不害怕那场圣战。]
吉姆·G

26

认为我可以成为同一项目的建筑师,开发人员和PM。

每晚睡2个月3个小时,这告诉了我您做不到。


15
所以,别再睡觉了!哦,等等...你的意思是那不正常... ?? 嗯,我要在这个项目上让我一些其他人……
AviD

听起来像PM,您需要进行一些估计的培训:)


20

这不是我的决定(我后来才加入公司),但是我工作的地方有点过分,包括翻译他们的所有日志消息。

结果:

  • 添加新的日志记录比较麻烦
  • 翻译费用更高
  • 日志之后很难阅读

哎呀。


我在这里做一些i18n,并试图弄清楚什么会进入用户以及什么会进入日志。我希望所有面向用户的输出都可以本地化,但是我希望日志保持不变。在此过程中,我需要做更多的事来弄清楚异常的去向。
David Thornley 2009年

1
我猜,你的美国人?如果不是,您只会说英语吗?在英文的新日志条目处使用国际化,如果有其他语言可用,则显示用户语言。提示:在这里使用错误代码会有所帮助,因为这意味着无论使用哪种语言,您都可以始终grep / scan日志。

2
@Jacob:我是英语,但只会说英语。但这是针对整个工程基地都在英格兰的公司,因此使用其他语言的日志文件(用于诊断目的,而不是用户可见的信息)只会浪费资源。我同意使用错误代码代替文本可以进行即时翻译-但这比仅仅使用一种语言开头还要麻烦。通过确定听起来有用的地方实际上不会提供任何重大价值来减少工作量。
乔恩·斯基特

10
我是瑞典人。我不得不对任何甚至建议代码/注释/日志不应该使用英语的人感到中世纪。英语是除了用户界面以外的所有语言。其他所有内容都使得代码难以阅读和讨论。使用本地语言是荒谬的,因为您使用的任何其他框架/库都是英语。
jgauffin

1
+1英语是编程的通用语言。翻译它只是在附加的一层,您需要的层数最少且清晰度更高。


19

做太多的设计。为每个单独的操作创建许多UML图,尤其是序列图,其中许多最终被证明是无用的。最后,事实证明,跳过不必要的详细设计/图表并直接开始编码,可以节省大量时间。


如果问题是:“您见过的最令人遗憾的设计或编程决策是什么?” 与我们自己犯的错误相反,我将“ UML”放在列表的顶部。在“ Windows注册表”下方。

2
UML可以在团队成员之间进行讨论,但是当涉及到设计然后根据设计实现时,UML总是很糟糕。这是某些公司的梦想,但是确实,软件的编写绝对无法做到这一点。+1!
deadalnix

17

相信客户知道他们想要什么,然后在与客户核对之前做得太多。


15

我最糟糕的设计决定是什么?早在1980年代,我就在一个项目中,我们有一个绝妙的主意,就是为我们的数据输入屏幕创建一种模板,该模板可以在运行时进行解释。这是一个不错的决定:它使输入屏幕的设计变得容易。基本上,只需创建一个类似于数据输入屏幕的文件,并使用一些特殊代码来识别什么是标签与什么是输入字段,并识别输入字段是字母还是数字。然后,我决定向这些文件添加一些其他特殊代码,以标识应执行的验证。然后,我添加了更多代码以允许有条件地构建屏幕,仅当某些条件为真时才包含字段X,等等。然后,我添加了更多代码以对输入进行一些简单处理。等等 最终,我们将屏幕模板变成了一种新的编程语言,包括表达式,控件结构和I / O库。那又是为了什么呢?我们做了很多工作来重新发明FORTRAN。我们摆满了许多编译器,这些编译器用于更好地设计和测试的语言。如果我们在实际拥有专业知识的产品上投入大量精力,那么该公司可能今天仍在营业。


这既有趣又悲惨:)

可悲的是,这种方法有时是最好的方法。客户可以选择“可以立即更改屏幕”,也可以选择“屏幕可以做任何事情,包括泡茶”,但不能同时选择两者!

3
我不反对使用模板或其他通用代码。错误在于将一段通用代码转换成一种语言。

我在2004年就已经看到这件事了!所有的业务逻辑分布在大约15个配置表中,并多次尝试对动态“语言”进行半熟尝试(请参阅Greenspun的第十条规则)!

1
您不是说COBOL而不是FORTRAN吗?
finnw

15

过分热心YAGNI(这被称为应用通过枚举设计面向对象开发的陷阱的环境下任何理智的人可以告诉大家的要求是)绝对不会改变。并不断变化。

如果您已将所有内容完全(硬)编码为当前要求,同时又打败了任何人说“这难道不是更通用吗?” 使用您的YAGNI槌,然后需求发生巨大变化(但可以合理预期的方式),这可能是需要2周的适应时间与20分钟的适应时间之间的差异。

更新:澄清一下,这是一个虚构的示例,与发生的事情相距不远。Stack Overflow旨在支持徽章,但是假设他们一开始只能想到四个徽章。只有四个,这是一个很小的数目,因此他们对站点中所有逻辑中的四个徽章进行硬编码支持。在数据库中,在用户信息中,在所有显示代码中。因为“您将不需要”您不会想到的任何徽章,对吗?然后假设该站点上线,并且人们开始建议新徽章。每个徽章最多需要两周的时间才能完成添加,因为整个地方要进行大量的硬编码调整。但是,“不需要”徽章的数量超过了今天的列表,因此,从来没有任何重构来支持通用的徽章收藏。这样的通用集合会花更多时间吗?不多,如果有的话。

YAGNI是一个有价值的原则,但不应用作滥用不良设计和不适当的硬编码的借口。有一种平衡,凭经验,我相信自己正在接近。


1
是的,不是,您能预测它会朝哪个方向变化吗?我经历过痛苦的复杂系统,事实证明,这些系统完全不能满足第一次重用的要求,而这与预测的通用性
不符

^是的,我宁愿跟YAGNI打交道,也不要胡扯。

因此,您认为您应该已经花了2个星期的时间?
finnw

4
这个例子根本不是YAGNI。DRY是YAGNI的一部分,没有它,您将无法保持对变化的响应。

3
斯蒂芬(Stephan)的例子显示了轻描淡写和不恰当地使用了流行语的观点,这就是我的观点。DRY(及其变体OAOO)也是一个很好的原则,但又非常独立:c2.com/cgi/wiki?OaooBalancesYagni。但是,我找不到任何地方可以支持您的主张“ DRY是YAGNI的一部分”。芥末酱与热狗搭配得很好,但这并不意味着芥末酱是热狗的一部分。如果您能澄清一下,也许参考一下,也许我会理解的。
80x24控制台

15

人力资源不足

尝试与错误的人做对的事情,伟大的事情!
即使他们扮演着多余的自我PM的角色(这种情况也很普遍,尤其是在大公司中,他们的无能承受的时间会更长一些)。


1
我了解您的痛苦:(

13

每次我都会因为技术问题而产生技术债务,编写程序代码,跳过编写测试等。几乎不可避免地,我发现这会给我带来痛苦。


13

使用SQL Server集成服务(SSIS)。

我不希望对我最大的敌人如此。

在过去两个月中构建了多个SSIS软件包之后,才发现我开发的软件包不可分发和不可部署。特别是在非Web,非SQL Server许可的环境中。

当您有不到48小时的时间用纯.NET POCO代码重新编写SSIS包或错过了预定的期限时,这是一个非常糟糕的情况。

令我惊讶的是,我能够用OLEDB适配器和SQL Adapaters在纯.NET代码中在12小时内重写三个SSIS包(花了我两个月的时间进行测试和开发)。

SSIS不可分发,并且如果未在其中安装SQL Server许可证(特别是DTSPipeline.dll),则不会从客户端计算机执行软件包。提前知道会很棒。我确实在MSDN上看到了免责声明(精装本)。当您使用Internet上所有使用SQL许可的仅机器代码的示例代码时,这样做没有用。基本上,您必须创建一个将与SQL Server通信的Web服务,以便以编程方式运行SSIS包。除非确实在执行计算机上安装了SQL许可证,否则无法从纯.NET代码执行它们。那是多么不现实?Microsoft是否真的希望从需要安装SQL Server的计算机上使用SSIS?完全浪费了两个月。

由于这种小字样,我的公司将永远不会再使用SSIS。


也许您应该完全避免使用“精细打印”软件!例如Talend是一个开源ETL IDE。

+1:是的。SSIS开发经验也是一场噩梦。至少有六种更好的执行ETL的方法。
Jim G.


10

在放假2周之前,将一些“有趣的”复活节彩蛋投入到我编写的代码中。我以为我回来时会是唯一阅读它的人,这会让我发笑并准备重新编码。

不用说,当我不在时,我的老板给他留下深刻的印象,而当一个“复活节彩蛋”涉及用ASCII有趣地卡通化他的脸时,他的印象就不那么深刻了。

嗯...


1
海事组织,那是“好工作先生!”

18
最近,我的团队嘲笑了我的跟踪消息,例如“添加值(p)表”!我说,看,他们让我在“像海盗一样的日子”上工作,他们应得的回报。

3
没错,您的loggs正在寻找“龙骨”!

10

仅在普通的CSS文件夹中使用ASP.Net主题就可以了。


大声笑,是的!

1
答案可以简化为“使用ASP.NET”
finnw

外观对于设置默认的CssClass很有用。

8

采取快速的方法来使一些代码起作用,而不是正确的方法(一般,但是我们将其称为抽象,因此是“正确”的答案)。


7

我公司具有瀑布式的开发模型,我们的业务用户和业务分析师将在其中定义项目的需求。在我们的一个“大”项目中,我们获得了一堆需求,我注意到许多需求包含实现细节,特别是与会计系统使用的数据库架构相关的信息。

我向业务用户评论说,实现是我的领域,不应包含在需求中。他们不愿意更改要求,因为毕竟它们是企业,并且只有会计师才能设计会计软件。作为一个卑微的开发谁是太远图腾民意调查,我支付给的,而不是思考。就我所进行的努力而言,我无法说服他们重新编写要求-更改中有太多的文书工作和繁文tape节,这太麻烦了。

所以,我给了他们他们想要的东西。至少,它可以工作,但是数据库的设计很奇怪:

  • 很多不必要的规范化。包含5或10个字段的单个记录被分为3或4个表。我可以解决这个问题,但我个人希望将所有1:1字段都放入一个表中。

  • 很多不当的非规范化。我们有一个存储发票数据的表,该表存储的数据多于发票数据。即使该标志与InvoiceData表在逻辑上不相关,我们也会在InvoiceData表中存储许多其他标志,以使每个标志都有一个魔术的硬编码主键值,并且所有其他字段在InvoiceData表中为空。由于该标志在表中表示为记录,因此我建议将标志拉到其自己的表中。

  • 还有更多不适当的非规范化。某些应用程序范围的标志作为列存储在不合适的表中,因此,更改应用程序的标志需要更新表中的每个记录。

  • 主键包含元数据,因此,如果varchar主键以“ D”结尾,则我们使用一组值来计算发票,否则使用另一组值来计算发票。将此元数据拉到单独的列中,或拉出一组要计算的值到另一个表中,将更有意义。

  • 外键通常会转到多个表,因此以“ M”结尾的外键可能会链接到我们的抵押帐户表,而以“ A”结尾的外键可能会链接到我们的自动帐户表。将数据分为两个表,MortageData和AutoInsuranceData会更容易。

我所有的建议都因大哭大叫而被拒绝。该应用程序按设计工作,尽管有很多泥泞,但所有讨厌的骇客,特例和怪异的业务规则都在源代码中讽刺地幽默地记录在案。


3
天哪,希望您的简历很好,并且在大泥球屈服于重力之前能够快速逃脱!
Benjol

7

坚持使用较旧的技术,因为让您的客户升级到新的.NET Framework版本似乎太麻烦了,但是实际上创建该软件会花费更多的开发时间,因为您无法利用其中的某些(节省时间的)组件。较新的框架版本。


+1:是的-我去过那里...当我意识到n00bs不会升级时,我开始计划逃往绿色牧场的计划。
Jim G.

我做到了,就在下个月退休!
葡萄树

6

回到大学时,我正在从事高级设计项目。我和另一个人正在编写一个基于Web的错误跟踪系统。(没什么开创性的,但是我们俩都希望获得一些Web体验。)我们使用Java servlet进行了此操作,并且运行良好,但是出于某些愚蠢的原因,我们选择不使用Exceptions作为错误处理机制,而是选择了使用错误代码。

当我们提出一个年级的项目时,一位教职员工就不可避免地问:“如果您不得不再次做,那您会做些什么?” 我立即知道了答案:“我会使用异常,这就是它们的作用。”


啊,重塑车轮的乐趣!:-) 那很好笑。

我称其为故意缺陷,以便您可以在下一次迭代中对其进行改进。
whatnick

2
异常仅用于处理异常。太多的人通过将所有内容变为异常来滥用异常。

@jacob-我同意您的观点,即应该将异常用于可以预测的事物(即特殊情况),但是从我所看到的(不是Java程序员)的角度来看,Java似乎在阳光下对所有事物都使用了异常。因此,可以考虑在Java代码中不使用异常会违背该语言的潮流。

6

不是我选择的方法,而是创建了一个XSLT来将基于行的XML文件转换为基于列的HTML报告。

它仅在IE中有效,完全无法解码其工作原理。每当我们需要扩展它时,都很难做到,而且花了很多年。

最后,我用一个很小的C#脚本代替了,它执行相同的操作。


我也做到了 我使用XSL实现了一个电子邮件模板引擎,发现它很难阅读和维护。
TrueWill

是的 用一些简单的VB.NET函数替换了某人巨大的XSLT文件树。非常令人满足,尤其是当XSLT不可能完成下一个客户更改请求时。

我发现大多数程序员认为XSLT是一个不好的选择,仅仅是因为他们没有得到它。它对于少数问题非常有用,比许多其他解决方案效率更高。另一方面,它使用得太频繁了,大多数情况下都不会使用它...
AviD

6

即使确实需要,也要尝试使用所有新技术(以学习新技术)。


5

我没有花足够的时间来评估业务模型。我按照客户的要求做了,但是6到12个月后,我们俩都得出结论,应该做的与众不同。


4

没有规范的设计。


3
始终没有规格-Jacob

应该是“在不询问客户是否就是他们想要的情况下实施解决方案”;这通常意味着您已遵循规格。
Dietbuddha 2011年

3

我根据要求实现了应用程序的一个小节。

事实证明,这些要求是肿的,镀金的,我的代码是过度设计的。我本该设计小节,使其仅能与当时添加的内容一起使用,但计划从一开始就添加所有其他内容,而无需对其提供通用支持。

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.