我想听听您做出什么样的设计决策,以及它们如何适得其反。由于一个错误的设计决定,我最终不得不永远支持这个错误的决定(我也参与其中)。这使我意识到一个设计错误会永远困扰着您。我想向经验丰富的人们学习,他们经历了什么样的错误,以及从中学到了什么。
我确信这将通过帮助其他程序员不再重复这些决定而对他们有很大帮助。
感谢您分享您的体验。
我想听听您做出什么样的设计决策,以及它们如何适得其反。由于一个错误的设计决定,我最终不得不永远支持这个错误的决定(我也参与其中)。这使我意识到一个设计错误会永远困扰着您。我想向经验丰富的人们学习,他们经历了什么样的错误,以及从中学到了什么。
我确信这将通过帮助其他程序员不再重复这些决定而对他们有很大帮助。
感谢您分享您的体验。
Answers:
C ++,菱形多重虚拟继承。你明白了。
应用程序中的可配置性很好。太多的可配置性是使用和维护的噩梦。
从我的一个错误中,我学会了不要盲目地遵循数据库规范化。您可以,并且在某些情况下,您必须展平桌子。
我最终通过表来管理表的负载(通过模型),并且性能有些下降,而表却有些扁平化。
在数据库中使用单个char来获取状态等信息。这一点都没有,与网络和任何SQL调用所引起的解析相比,使用更长的char()或nvarchar2()的开销微不足道。变得相当混乱或枯竭(不是为了状态,而是其他)。最好将人类可读的版本放进去,并且在您的Java模型中(以我为例)还具有一个带有匹配值的枚举。
我想这是过早的不必要和盲目的优化的一种形式。似乎使用单个字符可以拯救世界。除了不支持布尔值/位的数据库中的Y / N布尔值。
这不是我的决定(我后来才加入公司),但是我工作的地方有点过分,包括翻译他们的所有日志消息。
结果:
哎呀。
做太多的设计。为每个单独的操作创建许多UML图,尤其是序列图,其中许多最终被证明是无用的。最后,事实证明,跳过不必要的详细设计/图表并直接开始编码,可以节省大量时间。
我最糟糕的设计决定是什么?早在1980年代,我就在一个项目中,我们有一个绝妙的主意,就是为我们的数据输入屏幕创建一种模板,该模板可以在运行时进行解释。这是一个不错的决定:它使输入屏幕的设计变得容易。基本上,只需创建一个类似于数据输入屏幕的文件,并使用一些特殊代码来识别什么是标签与什么是输入字段,并识别输入字段是字母还是数字。然后,我决定向这些文件添加一些其他特殊代码,以标识应执行的验证。然后,我添加了更多代码以允许有条件地构建屏幕,仅当某些条件为真时才包含字段X,等等。然后,我添加了更多代码以对输入进行一些简单处理。等等 最终,我们将屏幕模板变成了一种新的编程语言,包括表达式,控件结构和I / O库。那又是为了什么呢?我们做了很多工作来重新发明FORTRAN。我们摆满了许多编译器,这些编译器用于更好地设计和测试的语言。如果我们在实际拥有专业知识的产品上投入大量精力,那么该公司可能今天仍在营业。
过分热心YAGNI(这被称为应用通过枚举设计在面向对象开发的陷阱的环境下任何理智的人可以告诉大家的要求是)绝对不会改变。并不断变化。
如果您已将所有内容完全(硬)编码为当前要求,同时又打败了任何人说“这难道不是更通用吗?” 使用您的YAGNI槌,然后需求发生巨大变化(但可以合理预期的方式),这可能是需要2周的适应时间与20分钟的适应时间之间的差异。
更新:澄清一下,这是一个虚构的示例,与发生的事情相距不远。Stack Overflow旨在支持徽章,但是假设他们一开始只能想到四个徽章。只有四个,这是一个很小的数目,因此他们对站点中所有逻辑中的四个徽章进行了硬编码支持。在数据库中,在用户信息中,在所有显示代码中。因为“您将不需要”您不会想到的任何徽章,对吗?然后假设该站点上线,并且人们开始建议新徽章。每个徽章最多需要两周的时间才能完成添加,因为整个地方要进行大量的硬编码调整。但是,“不需要”徽章的数量超过了今天的列表,因此,从来没有任何重构来支持通用的徽章收藏。这样的通用集合会花更多时间吗?不多,如果有的话。
YAGNI是一个有价值的原则,但不应用作滥用不良设计和不适当的硬编码的借口。有一种平衡,凭经验,我相信自己正在接近。
我不希望对我最大的敌人如此。
在过去两个月中构建了多个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。
我公司具有瀑布式的开发模型,我们的业务用户和业务分析师将在其中定义项目的需求。在我们的一个“大”项目中,我们获得了一堆需求,我注意到许多需求包含实现细节,特别是与会计系统使用的数据库架构相关的信息。
我向业务用户评论说,实现是我的领域,不应包含在需求中。他们不愿意更改要求,因为毕竟它们是企业,并且只有会计师才能设计会计软件。作为一个卑微的开发谁是太远图腾民意调查,我支付给做的,而不是思考。就我所进行的努力而言,我无法说服他们重新编写要求-更改中有太多的文书工作和繁文tape节,这太麻烦了。
所以,我给了他们他们想要的东西。至少,它可以工作,但是数据库的设计很奇怪:
很多不必要的规范化。包含5或10个字段的单个记录被分为3或4个表。我可以解决这个问题,但我个人希望将所有1:1字段都放入一个表中。
很多不当的非规范化。我们有一个存储发票数据的表,该表存储的数据多于发票数据。即使该标志与InvoiceData表在逻辑上不相关,我们也会在InvoiceData表中存储许多其他标志,以使每个标志都有一个魔术的硬编码主键值,并且所有其他字段在InvoiceData表中为空。由于该标志在表中表示为记录,因此我建议将标志拉到其自己的表中。
还有更多不适当的非规范化。某些应用程序范围的标志作为列存储在不合适的表中,因此,更改应用程序的标志需要更新表中的每个记录。
主键包含元数据,因此,如果varchar主键以“ D”结尾,则我们使用一组值来计算发票,否则使用另一组值来计算发票。将此元数据拉到单独的列中,或拉出一组要计算的值到另一个表中,将更有意义。
外键通常会转到多个表,因此以“ M”结尾的外键可能会链接到我们的抵押帐户表,而以“ A”结尾的外键可能会链接到我们的自动帐户表。将数据分为两个表,MortageData和AutoInsuranceData会更容易。
我所有的建议都因大哭大叫而被拒绝。该应用程序按设计工作,尽管有很多泥泞,但所有讨厌的骇客,特例和怪异的业务规则都在源代码中讽刺地幽默地记录在案。
回到大学时,我正在从事高级设计项目。我和另一个人正在编写一个基于Web的错误跟踪系统。(没什么开创性的,但是我们俩都希望获得一些Web体验。)我们使用Java servlet进行了此操作,并且运行良好,但是出于某些愚蠢的原因,我们选择不使用Exceptions作为错误处理机制,而是选择了使用错误代码。
当我们提出一个年级的项目时,一位教职员工就不可避免地问:“如果您不得不再次做,那您会做些什么?” 我立即知道了答案:“我会使用异常,这就是它们的作用。”