您曾经喜欢的编程习惯让您改变了主意?

LBu*_*kin 99 language-agnostic

在我们编程时,我们都会开发我们使用和依赖的实践和模式.然而,随着时间的推移,随着我们的理解,成熟,甚至技术使用的变化,我们逐渐意识到我们曾经认为很棒的一些实践并不(或不再适用).

我曾经经常使用但最近几年改变的一种做法的例子是使用Singleton对象模式.

通过我自己的经验和与同事的长时间辩论,我逐渐意识到单身人士并不总是令人满意 - 他们可以使测试更加困难(通过抑制嘲讽等技术)并且可以在系统的各个部分之间产生不希望的耦合.相反,我现在使用对象工厂(通常使用IoC容器)来隐藏系统中不关心或需要知道的部分单体的性质和存在.相反,他们依靠工厂(或服务定位器)来获取对这些对象的访问权.

我本着自我改善的精神向社会提出的问题是:

  • 您最近重新考虑了哪些编程模式或实践,现在尽量避免?
  • 你决定用什么代替它们?

Luk*_*lch 159


//Coming out of university, we were taught to ensure we always had an abundance 
//of commenting around our code. But applying that to the real world, made it 
//clear that over-commenting not only has the potential to confuse/complicate 
//things but can make the code hard to follow. Now I spend more time on 
//improving the simplicity and readability of the code and inserting fewer yet 
//relevant comments, instead of spending that time writing overly-descriptive 
//commentaries all throughout the code.
Run Code Online (Sandbox Code Playgroud)


  • 听起来像你评论*错误*,而不是太多.代码本身并不代表.不,它确实没有.阅读最新的NT Insider,对此有一个很好的咆哮.如果您认为评论是多余的,那么您错了或者您做错了.大学似乎没有正确的评论(或错误跟踪,或版本控制......\*叹息\*).那里的评论太少了.(少了好的) (32认同)
  • 应该使用注释来描述*为什么*代码执行它所做的事情(如果它不明显),而不是*代码的作用.一个可能的例外是疯狂的比特/语言黑客,比如Carmack的幻数0x5f3759df. (20认同)
  • @Thomas:我个人认为问题在于,教授好的评论不是大学可以向学生展示的.几乎所有学校的课程都是一次性的; 学生们没有体验回顾他们一年前写的代码而根本不理解它.此外,低级课程教授非常简单的编码概念 - 由于正在发生的事情,在这个级别进行评论几乎必然是单调乏味的.换句话说,就像试图教别人在浅水池里游泳一样; 他们理解这些动作并不是正确的背景. (6认同)
  • Code Complete有很好的评论提示和备份数据. (5认同)
  • 对于多行注释我推荐/*和*/:) (5认同)

Car*_*ter 117

单点返回.

我曾经偏好每个方法的单个返回点,因为我可以确保不会忽略例程所需的任何清理.

从那以后,我转向了更小的例程 - 因此减少了清理的可能性,并且实际上减少了清理的需要 - 并且发现早期的返回减少了代码的明显复杂性(嵌套级别).单个返回点的工件 - 保持"结果"变量,保留标志变量,未完成情况的条件子句 - 使代码看起来比实际复杂得多,使其更难以阅读和维护.早期出口和较小的方法是可行的方法.

  • 同意.*用Guard子句替换嵌套条件*ftw! (4认同)
  • 我同意,当与自动清理自己的数据类型结合使用时,例如autoptr,scoped_ptr,CComPtr等. (3认同)
  • 代码清理是try {} finally {}的用途 (3认同)

Woj*_*ski 111

  • 尝试在第一次尝试时完美地编写代码.
  • 尝试在编码之前创建完美的OO模型.
  • 为灵活性和未来改进设计一切.

用一句话来说,过度工程.

  • 真正的金钱是第一次让它变得微妙错误并让它暴露在野外.然后,当人们习惯了gimped版本时,突然出现傲慢的表演并修复bug /低效率以获得额外的荣耀!;) (18认同)
  • @jeffamaphone - 不,只有Jon Skeet第一次就做对了. (7认同)
  • 等等,我总是在第一次尝试时做对.:) (6认同)

Ken*_*ann 78

匈牙利表示法(表格和系统).我以前用过所有的前缀.strSomeString或txtFoo.现在我使用someString和textBoxFoo.对于新来的人来说,它更易读,更容易阅读.作为一个额外的奖励,保持它一致是微不足道的 - camelCase控件并附加一个有用/描述性的名称.表格匈牙利语的缺点是并不总是保持一致,而匈牙利语系统并没有真正为您带来多少收获.将所有变量组合在一起并不是那么有用 - 特别是对于现代IDE.

  • 我做类似的事情除外:fooTextBox和string's只是显而易见:numberOfEntries => int,isGreat => bool等. (4认同)
  • 顺便说一句,你提到的不是真正的匈牙利人. (4认同)
  • @ wuub:我认为通过正确的命名,你不需要为任何东西添加前缀. (3认同)

Bru*_*eod 67

"完美"的架构

我想出一对夫妇几年前的架构.我尽可能地在技术上推动自己,因此有100%松散耦合的层,广泛使用委托和轻量级对象.这是技术天堂.

这是废话.该体系结构的技术纯度正在减慢我的开发团队的目标,完美结果,我几乎完全失败.

我们现在拥有更简单,技术更完美的架构,我们的交付率飙升.


Ale*_*lex 57

使用caffine.它曾经让我保持清醒,并且处于一种光荣的编程氛围中,代码从我的手指中流出,带着狂热的流动性.现在它什么也没做,如果我没有,我会头痛.

  • 你需要喝更多的咖啡.如果这不起作用,请吸烟. (55认同)
  • "看起来我选择了错误的一周戒掉安非他明." (15认同)
  • 布拉德:当你拥有Python时,你不需要那些:http://www.xkcd.com/353/ (7认同)
  • 我打破了这个习惯,然后再次把它捡起来好几次(现在是我的第三个周期).没有什么比在寒冷的早晨用一杯温暖的咖啡编码了! (2认同)

bbr*_*own 50

评论代码.我曾经认为代码是珍贵的,你不能只删除你精心制作的那些美丽的宝石.我现在删除了我遇到的任何已注释掉的代码,除非附加了TODO或NOTE,因为将它留在其中太危险了.就是说,我遇到了带有大量注释部分的旧类,它真的让我困惑为什么他们在那里:他们最近评论过吗?这是一个开发环境变化吗?为什么要做这个无关的块呢?

认真考虑不要注释掉代码而只是删除代码.如果您需要它,它仍然在源代码管理中.YAGNI虽然.

  • 我在重构期间注释掉旧代码,但直到我验证替换代码是否有效.一旦新版本完全正常运行,我将删除旧的注释行. (6认同)
  • 我说检查一次注释代码,然后删除它.有很多次,当你测试各种不同的代码时,你不想检查损坏的代码...... (4认同)

Sco*_*son 46

#region指令的过度使用/滥用.这只是一件小事,但在C#中,我以前会在整个地方使用#region指令来组织我的课程.例如,我将所有类属性组合在一个区域中.

现在我回顾一下旧代码,大多只是被他们烦恼了.我不认为它在大多数情况下确实让事情变得更清晰,有时它们只会让你失望.所以我现在已经改变了主意,觉得布局合理的课程大多是清洁的,没有地区指令.

  • 我讨厌地区的.我团队中的人们轻率地使用它们.我称之为"糟糕的代码隐藏者". (31认同)
  • 它们绝对是代码味道. (9认同)
  • 我认为如果谨慎使用,地区可以很好. (9认同)
  • @Solution Yogi:我不认为地区是你真正的问题:-) (6认同)
  • 我讨厌地区.我目前正在维护代码,其中函数几乎是500行并且为了管理它,智能开发人员已经在10到15个区域中放置了大量代码. (3认同)
  • 我同意区域主要适得其反的情绪,我在VS2008中完全禁用它们:工具 - >选项 - >文本编辑器 - > C# - >高级 - >'文件打开时输入大纲模式' (3认同)
  • 它们是最显着的浪费时间. (2认同)
  • 我讨厌术语"代码味道"......区域对于某些事情很有用,比如分区方式接口实现或者不需要经常修改的代码(如果有的话)并且只是妨碍了,但是,是的,它们是经常被滥用 (2认同)
  • 我不同意.如果它们被谨慎和一致地使用,区域可以节省时间.您必须首先以结构化的方式布置代码才能使其工作(大多数程序员一开始都懒得做).我通常有5个区域,构造函数,属性,事件,方法,成员.它节省了我大量的时间,不必滚动我不需要看到的大量废话,并帮助我在心理上剖析一个类,以便我可以更好地可视化各个部分及其相互作用. (2认同)

Pau*_*ier 39

瀑布开发一般,具体而言,是编写完整和全面的功能和设计规范的实践,这些规范在某种程度上是预期的规范,然后期望这些规范的实现是正确和可接受的.我已经看到它被Scrum取代了,并且很好地解决了它,我说.简单的事实是,客户需求和欲望的变化使得任何固定的规范都无济于事; 真正正确解决问题的唯一方法是使用迭代方法.当然,并不是说Scrum是一颗银弹; 我已经看到它滥用和滥用了很多次.但它击败了瀑布.

  • 告诉我的客户......我正在写一些无用的"我是一个带水晶球的程序员所以我确切知道我的低级设计在6个月后会是什么样子"规范文件:) (3认同)

gus*_*afc 36

永远不会崩溃.

这似乎是个好主意,不是吗?用户不喜欢崩溃的程序,所以让我们编写不会崩溃的程序,用户应该喜欢这个程序吧?这就是我开始的方式.

如今,我更倾向于认为如果它不起作用,它就不应该假装它正在发挥作用.尽快失败,并提供良好的错误消息.如果你不这样做,你的程序将在稍后的几个指令中更加崩溃,但是有一些非描述性的空指针错误,你需要一个小时来调试.

我最喜欢的"不要崩溃"模式是这样的:

public User readUserFromDb(int id){
    User u = null;
    try {
        ResultSet rs = connection.execute("SELECT * FROM user WHERE id = " + id);
        if (rs.moveNext()){
            u = new User();
            u.setFirstName(rs.get("fname"));
            u.setSurname(rs.get("sname"));
            // etc
        }
    } catch (Exception e) {
        log.info(e);
    }
    if (u == null){
        u = new User();
        u.setFirstName("error communicating with database");
        u.setSurname("error communicating with database");
        // etc
    }
    u.setId(id);
    return u;
}
Run Code Online (Sandbox Code Playgroud)

现在,您不必要求用户复制/粘贴错误消息并将其发送给您,而是必须深入了解尝试查找日志条目的日志.(因为他们输入了无效的用户ID,所以没有日志条目.)


mol*_*olf 33

我认为只要我认出它就应用设计模式是有意义的.

我几乎不知道我实际上是从外国编程语言复制样式,而我正在使用的语言允许更优雅或更简单的解决方案.

使用多种(非常)不同的语言让我大开眼界,让我意识到我不必将其他人的解决方案误用于不属于我的问题.当我看到像Ruby这样的语言应用工厂模式时,我不寒而栗.

  • 请原谅我对红宝石的无知,但为什么我们不应该使用工厂模式呢? (2认同)

yal*_*tar 27

强迫测试.我曾经是测试优先开发的狂热支持者.对于某些项目来说,这很有道理,但我已经意识到,这不仅是不可行的,而且对许多项目而言是有害的,因为他们盲目地坚持为每一项功能编写单元测试的学说.

真的,盲目地坚持任何事情都可能是有害的.

  • 对于藤壶来说效果非常好. (22认同)

Dan*_*Lew 25

这是一件小事,但是:关心括号的位置(在同一行或下一行?),建议代码的最大行长度,变量的命名约定以及样式的其他元素.我发现每个人似乎都比我更关心这一点,所以我只想跟随我现在工作的人的流动.

编辑:当然,这是一个例外,当我是最关心的人(或者是一个能够为一个团体设置风格的人).在那种情况下,我做我想做的!

(请注意,这与没有一致的样式不同.我认为代码库中的一致样式对于可读性非常重要.)

  • 最好的代码样式是该商店的标准. (12认同)
  • 有人给了它一个downvote,但我认为它是一个实用的观点.什么是最好的代码样式?不重要.在同一个文件中上下查找并复制. (5认同)
  • @cory:你的版本控制软件能否显示你刚刚重新格式化的文件版本之间的差异? (5认同)

Nip*_*rus 24

也许我改变主意的最重要的"编程实践"是我的代码比其他人更好的想法.这对于程序员(尤其是新手)来说很常见.


Jam*_*ler 20

实用程序库.我曾经带着各种辅助方法和类进行组装,其理论是我可以在其他地方使用它们.

实际上,我刚刚创建了一个庞大的命名空间,其中包含许多组织不当的功能.

现在,我只是将它们留在我创建它们的项目中.很可能我不需要它,如果我这样做,我总是可以将它们重构为以后可重用的东西.有时我会用// TODO标记它们,以便可能提取到一个公共程序集中.

  • 这是一个很好的引用(我目前找不到原文),这是"在你需要解决同样的问题3次之前,甚至不考虑创建一个通用的例程". (12认同)
  • "三次罢工,你重构" - *由Martin Fowler重构*.**三法则**,第58页. (9认同)

Pau*_*han 20

设计超过我编码.过了一会儿,它变成了分析瘫痪.

  • 我偶尔会引用这句话:"如果你发现自己的想法太多,那就停下来做.如果你发现自己做得太多,那就停下来思考吧." (44认同)

Eri*_*der 15

使用DataSet执行业务逻辑.这会将代码与数据库紧密绑定,而DataSet通常也是从SQL创建的,这使得事情变得更加脆弱.如果SQL或数据库发生变化,它往往会渗透到DataSet触及的所有内容.

在对象构造函数中执行任何业务逻辑.继承和创建重载构造函数的能力往往使维护变得困难.


Rhy*_*nes 15

缩写变量/方法/表/ ...名称

我曾经一直这样做,即使在没有强制限制名称长度的语言中工作(好吧它们可能是255或者其他东西).其中一个副作用是在整个代码中散布了许多解释(非标准)缩写的评论.当然,如果名字因任何原因而改变了......

现在我更喜欢用好的描述性名称来称呼它们的真实含义.仅包括标准缩写.无需包含无用的注释,代码更具可读性和易懂性.


blu*_*blu 14

使用自定义辅助方法层包装现有的数据访问组件(如企业库).

  • 它不会让任何人的生活更轻松
  • 它的代码可能会有更多错误
  • 很多人都知道如何使用EntLib数据访问组件.除了本地团队之外,没有人知道如何使用内部数据访问解决方案


Gre*_*ham 14

我在1984年阅读关于Smalltalk的时候第一次听说过面向对象的编程,但在1992年我使用cfront C++编译器之前我没有访问oo语言.我终于在1995年使用了Smalltalk.我曾热切期待oo技术,并购买了它将节省软件开发的想法.

现在,我只看到oo作为一种具有一些优势的技术,但它只是工具箱中的一个工具.我在Python中完成大部分工作,而且我经常编写不是类成员的独立函数,而且我经常在元组或列表中收集数据组,过去我会创建一个类.我仍然在数据结构复杂时创建类,或者我需要与数据相关的行为,但我倾向于抵制它.

当我得到时间时,我真的很想在Clojure做一些工作,虽然如果我理解正确,它可以使用Java对象.我还没准备好说oo已经死了,但我个人并不是以前的粉丝.


Jul*_*anR 13

在C#中,_notation用于私有成员.我现在认为这很难看.

然后我改为this.notation私人会员,但发现我使用它不一致,所以我放弃了.

  • 我仍在使用_notation并认为它很棒. (29认同)
  • 我不同意.它使管理名称变得更加容易.对于属性或公共/内部成员使用PascalCase,对通过属性公开的成员使用_UnderscorePascalCase,对于方法/构造函数和私有成员使用camelCase作为参数名称.只有当您需要在类之外传递当前类的引用或者您需要访问类中的自动生成的成员(例如名称,控件等等)时,才需要使用'this'关键字. (4认同)
  • 我讨厌_notation; 我为公共成员使用ThisNotation,为私人成员使用thisNotation. (3认同)

ral*_*nja 11

在实施之前,我停止了大学推荐的设计方法.在一个混乱而复杂的系统中工作迫使我改变态度.

当然我还在做代码研究,特别是当我要触摸之前从未接触过的代码时,但通常我会尽量专注于尽可能小的实现来先获得一些东西.这是主要目标.然后逐渐完善逻辑,让设计自己出现.编程是一个迭代过程,并且通过敏捷方法和大量重构非常有效.

代码不会查看您最初认为的样子.每次都发生:)


Fra*_*man 10

我曾经在合同设计方面做得很好.这意味着在我的所有功能开始时进行大量的错误检查.从关注点分离的角度来看,合同仍然很重要,但是我尝试使用单元测试来验证它的作用,而不是试图强制执行我的代码不应该做的事情.


rba*_*all 10

我会在很多方法/类中使用static,因为它更简洁.当我开始编写测试时,练习变化非常快.


Gre*_*zky 10

已检查的例外情况

在纸上的一个惊人的想法 - 明确定义合同,没有错误的余地或忘记检查一些异常情况.我第一次听到它时卖掉了.

当然,它在实践中变得如此混乱.到目前为止,像Spring JDBC一样拥有库,它将遗留的遗留检查异常作为其主要特征之一.


小智 9

任何值得的东西只能用一种特定的语言编码.在我的情况下,我相信C是有史以来最好的语言,我从来没有任何理由用任何其他语言编码任何东西......永远.

从那以后,我开始欣赏许多不同的语言以及它们提供的好处/功能.如果我想编写一些小的东西 - 很快 - 我会使用Python.如果我想处理大型项目,我会用C++或C#编写代码.如果我想发展脑肿瘤,我会在Perl中编码.


Yin*_*ing 8

当我需要进行一些重构时,我认为直接开始并实施新设计更快更干净,修复连接直到它们工作.然后我意识到最好做一系列小的重构,以缓慢但可靠地向新设计迈进.


小智 8

也许在我的编码实践中以及在其他实践中发生的最大变化是接受从互联网下载的外部类和库作为应用程序中行为和功能的基础.在我上大学的时候,我们被鼓励想出如何通过我们自己的代码让事情变得更好,并依靠语言来解决我们的问题.随着用户界面和服务/数据消耗的各个方面的进步,这不再是一个现实的概念.

有些东西在一种语言中永远不会改变,并且有一个库将这个代码包装在一个更简单的事务中,而且我需要编写的代码行更少,这是一种祝福.连接到数据库将始终是相同的.选择DOM中的元素不会改变.通过服务器端脚本发送电子邮件永远不会改变.不得不写这个时间又浪费了我可以用来改进应用程序中的核心逻辑的时间.


Nip*_*rus 7

初始化所有班级成员.

我曾经用某些东西显式初始化每个类成员,通常是NULL.我已经意识到这一点:

  • 通常意味着每个变量在被读取之前被初始化两次
  • 是愚蠢的,因为在大多数语言中自动将变量初始化为NULL.
  • 实际上在大多数语言中都会略微降低性能
  • 可以在较大的项目上膨胀代码

  • 有时,NOT初始化所有班级成员的后果可能真的会让你陷入a $$. (4认同)

aja*_*987 6

和你一样,我也采用了IoC模式来减少应用程序各个组件之间的耦合.只要我能够使每个组件尽可能独立,它使维护和部件交换变得更加简单.我还使用了更多的对象关系框架,如NHibernate,以简化数据库管理工作.

简而言之,我正在使用"迷你"框架来帮助更快速有效地构建软件.这些迷你框架可以节省大量时间,如果做得好,可以使应用程序变得非常简单,以便在路上维护.即插即赢!