“最佳做法”在我们行业中无处不在。 Google在“编码最佳做法”上的搜索结果将近150万个结果。这个主意似乎给许多人带来了安慰。只需按照说明进行操作,一切都会好起来的。

当我阅读最佳实践时-例如,我最近刚刚阅读了“清洁代码”中的一些内容-我感到紧张。这是否意味着我应该始终使用这种做法?有附带条件吗?在某些情况下可能不是好的做法吗?在进一步了解该问题之前,我怎么能确定?

Clean Code中提到的几种做法并不适合我,但老实说,我不确定这是否是因为它们可能很糟糕,或者这仅仅是我个人的偏见。我确实知道,科技行业的许多杰出人士似乎都认为没有最佳实践,所以至少我那令人烦恼的疑问使我成为了一个好公司。

我读过的最佳实践数量关于的代码太多了,无法在此处列出或询问个别问题,因此,我想将其表述为一个一般性问题:

通常被称为“最佳实践”的编码实践可以分为以下几个部分:在某些情况下最佳甚至有害?这些情况是什么?为什么使这种做法不佳?

我希望听听具体的例子和经验。

评论

您不同意哪些做法?只是好奇。

任何人都可以写一本书,而我不必同意它-就这么简单。

我喜欢史蒂夫·麦康奈尔(Steve McConnell)撰写的《代码完成》(Code Complete)一本书,一件事是他用确凿的证据和研究来支持他的所有技巧。只是说'

@Walter:已经开放了几个月,这绝对是建设性的,为什么要关闭它?

好像在这里提到我的名字一样,我想加入一下:我相信这里的答案很有价值,但是在不使任何答案无效的情况下,可以将该问题改写为绝对不太像民意测验的东西。示例标题:“哪些流行的“最佳做法”有时可能有害,以及何时/为什么?”

#1 楼

我想您会以这种说法打动您的头绪


我不愿看重事物的面值而不是批判地考虑它们


我几乎忽略了所有最佳实践,但都没有解释为什么它存在

雷蒙德·陈(Raymond Chen)在说“


好的建议带有一个基本原理,因此
您可以分辨出什么时候变坏了
建议。如果您不理解为什么
应该做些什么,那么您已经
陷入了对货物崇拜的陷阱中
编程,即使在以下情况下,您也会继续这样做
不再是必需的,或者甚至变得有害。


评论


精彩的报价。

– David Thornley
2010-10-26 20:10

Raymond Chen引用的下一段可能描述的是匈牙利符号!我看到的大多数公司都没有充分的理由来解释它。

– Craig
2010-10-27 2:03

但是,我希望人们不要以此为借口不去查找最佳实践背后的原因。 ;)不幸的是,我见过开发人员有这种态度。

–车
2010-10-27 8:23

理由是好的。研究更好。

–琼·普迪(Jon Purdy)
2010-10-27 14:26

绝对正确,我之前也说过。也许任何“标准”文档中的第一个标准都应显示为:“为了共享知识并在以后提供废除标准所需的信息,所有标准都应包括其存在的原因。”

–斯科特·惠特洛克
10-10-29在0:47

#2 楼

最好把它扔进去:


Premature optimization is the root of all evil.



不,不是。

完整的报价:


“我们应该忽略小的效率,例如约97%的时间:过早的优化是万恶之源。但是,我们不应该
放弃那3%的关键机会。”


这意味着您可以在整个设计中利用特定的,战略性的性能提升处理。这意味着您将使用与性能目标一致的数据结构和算法。这意味着您了解会影响性能的设计注意事项。但这也意味着您这样做时不会轻率地进行优化,而只会以可维护性为代价而获得微不足道的收益。当您在它们上施加一点负载,然后结束重写它们时,它就结束了。缩写词的危险在于,开发人员经常以它为借口,根本不考虑性能,直到最后对它做任何事情都为时已晚。最好从一开始就构建良好的性能,前提是您不关注细节问题。

假设您正在嵌入式系统上构建实时应用程序。您选择Python作为编程语言,因为“过早的优化是万恶之源”。现在,我对Python没有任何了解,但这是一种解释语言。如果处理能力有限,并且需要实时或近乎实时地完成一定数量的工作,并且您选择的语言需要比您的工作需要更多处理能力的语言,那么您就很费力。现在必须从一种精通的语言开始。

评论


+1为强否,不是。

–斯蒂芬
10-10-26在21:26

但是,如果您已经意识到某个特定的优化在3%的临界范围内,您是否还为时过早?

–约翰
10-10-26在21:33

@罗伯特:那么与“过早的优化是万恶之源”这一说法有何不同?

–约翰
2010-10-26 22:20

优化高级设计和技术决策(如语言选择)永远不会为时过早。但是,通常只有在您大部分完成设计后,效率低下才会变得明显,这就是为什么弗雷德·布鲁克斯(Fred Brooks)表示大多数团队无论是否打算都写一个废弃版本。原型的另一个论点。

– Dominique McDonnell
2010-10-27 12:06

@ Robert,Knuth的报价过早优化了...

–user1249
2011年1月21日0:00,

#3 楼

每个函数/方法返回一次。

评论


我打算把这个。我爱我一些早期的回报声明。

–卡森·迈尔斯(Carson Myers)
2010年12月1日,下午3:37

绝对!人们设计了一些非常有趣的程序流程来避免提早返回语句。深度嵌套的控制结构或连续检查。当if返回确实可以简化此问题时,这确实会使方法膨胀。

–snmcdonald
2010-12-19 22:26

如果在一个函数中需要多个返回(除了警卫之外),则您的函数可能太长了。

– EricSchaefer
2010-12-28 20:16

除非要在多个位置出现,否则没有return关键字是没有意义的。早点回来,经常回来。它只会进一步简化您的代码。如果人们能够理解中断/继续语句的工作方式,为什么还要为收益而挣扎?

–伊文·普莱斯
2011年1月12日下午16:14

我认为这是一个过时的最佳实践。我认为这不是现代的最佳做法。

– Skilldrick
2011年1月17日在11:26

#4 楼

不要重新发明轮子是一种被广泛滥用的教条。它的想法是,如果存在合适的解决方案,请使用它,而不要创建自己的解决方案。除了节省精力之外,现有解决方案可能比最初设想的要更好地实施(无错误,高效,经过测试)。到目前为止,一切都很好。

问题是几乎没有100%合适的解决方案。可能存在80%合适的解决方案,使用它可能很好。但是60%合适吗? 40%?您在哪里划界线?如果不划清界限,最终可能会在项目中合并一个incorporating肿的库,因为您正在使用其10%的功能-只是因为您要避免“重新发明轮子”。

如果您确实重新发明了轮子,那么您将得到您想要的一切。您还将学习如何制作轮子。边做边学不应被低估。最后,定制轮可能比现成的通用轮更好。

评论


我曾经发生过这种情况。我建立了自己的ajax网格组件,因为当时没有人可以做我想要的,但是后来用Ext JS网格替换了它。我从一开始就做出了替换显示层的假设,这很有帮助。

– Joeri Sebrechts
2010-10-28 19:15

同意如果没有人重新发明轮子,那么我们所有人都将使用木制轮胎驾驶汽车。

–威利博士的学徒
2010-10-29 20:41

当我将Boost添加到C ++项目时,我总是感觉像是10%的示例。我总是直接需要少于10%的东西,但是当然我需要导入其他模块的功能,这些模块导入其他模块...

–罗马·斯塔科夫
10 Nov 19 '13:02

+1:就在本周,我重新发明了轮子(例如,用适合我们需求且模块化的东西替换使用过时但又流行的jquery插件),并带来了巨大的性能提升。另外,有些人的工作实际上是重塑车轮:以米其林为例,他们从事研发以改进轮胎。

–狂话
2011年1月12日18:39

@博士聪明地,这些轮子没有被重新发明,而是被重构了!

–user1249
2011年1月21日,0:01

#5 楼

“一切都进行单元测试。”

我经常听到所有代码都应该进行单元测试,这一点我不同意。对某个方法进行测试时,必须对该方法的输出或结构进行两次更改(一次在代码中,一次在测试中)。

因此,单元测试应该在我看来,与代码的结构稳定性成正比。如果我是从下往上编写分层系统,那么我的数据访问层将测试wazoo。我的业务逻辑层将经过很好的测试,我的表示层将进行一些测试,而我的视图将进行很少甚至没有测试。

评论


我怀疑“一切都进行单元测试”已经成为陈词滥调,就像“过早的优化”报价一样。我通常同意您的比例,并且看到了许多开发人员正在努力模拟应用程序层对象的示例,而这些工作可能更适合进行验收测试。

–罗伯特·哈维(Robert Harvey)
2010-10-26 18:23

如果方法结构的更改导致测试更改,则可能是测试做错了。单元测试不应验证实现,而只能验证结果。

–亚当·李尔♦
2010-10-26 18:27

@Anna Lear:我认为他是在谈论进行设计/结构更改(重构)。由于设计还不够成熟,因此当您找到更好的设计方法时,您可能不得不修改很多测试方法。我同意,如果您的测试人员技术水平更高,则可能会更容易注意到测试在哪里是个坏主意(由于这个原因和其他原因),但是如果设计不是很成熟,您仍然很可能会在其中进行一些测试。道路。

– n1ckp
10-10-27在0:44

我认为这也是为什么“先做测试”的想法行不通的原因。首先要进行测试,您必须具有设计权。但是拥有正确的设计要求您尝试一些事情,看看它们如何工作,以便您可以对其进行改进。因此,您在设计之前就无法真正进行测试,而正确进行设计需要您进行编码并查看其工作方式。除非您有一些真正的超级建筑师,否则我不会真正看到这个想法如何工作。

– n1ckp
2010-10-27 1:02

@ n1ck TDD实际上不是设计练习,而是设计练习。这个想法是,您通过测试来改进设计(因为这样可以快速地为您的东西公开一个合理的API),而不是使测试适合现有设计(这可能是不好的/不足的)。因此,您不必先拥有设计权就可以进行测试。

–亚当·李尔♦
2010-10-27 4:45

#6 楼

始终对接口进行编程。

有时只有一种实现。如果我们将提取接口的过程推迟到看到需要接口的时间,我们通常会发现它是不必要的。

评论


同意,当您需要接口(即可以使用的稳定API)时,可以对接口进行编程。

–罗伯特·哈维(Robert Harvey)
10-10-26在20:06

在我的阅读中,该规则与语言构造的接口无关。这意味着您在调用类的方法时不应对类的内部工作作任何假设,而应仅依赖于API合同。

– ZsoltTörök
10-10-26在20:52

好的,这是一个有趣的问题-我主要是.NET开发人员,所以对我来说,我的界面看起来像IBusinessManager或IServiceContract。对我来说,这非常容易导航(而且我通常将我的界面保留在另一个名称空间(甚至另一个项目)中)。当我使用Java时,实际上发现了这一点令人困惑(通常我看到的接口实现都带有.impl后缀-接口没有描述)。那么这可能是代码标准问题吗?当然,Java中的接口会使代码看起来很混乱-乍一看,它们看上去与普通类完全相同。

–沃森
2010-10-28 14:19

@沃森:一个代价是,每当我在Eclipse中的一个方法调用上击中F3(“跳转到声明”)时,我都会跳到该接口,而不是一个实现。然后,我必须控制-T,向下箭头,返回到实现。它还会阻止一些自动重构-例如,您不能在接口定义中内联方法。

–汤姆·安德森(Tom Anderson)
2010-10-28 17:35

@汤姆:好吧,先生,我很乐意让您参与这场战争,Eclipse与Intellij。但是,我有出色的道德准则,这使我无法与明显有障碍的人进行身体对抗。繁荣。我并不是说Eclipse不好,而是说如果轴心国使用它来建造或设计他们的战争机器,第二次世界大战现在将被称为“两日混战”。严重的是,我发现它缺乏一些现成的IDE(Intellij / VS + ReSharper)中的润色。我发现自己不止一次与之抗争-太多了。

–沃森
2010-10-29 14:15

#7 楼

不要使用任何开源的软件(或非Microsoft开发人员使用的.NET开发人员)

如果Microsoft不进行开发,则不要在这里使用。想要使用ORM-EF,想要使用IOC-Unity,想要记录-企业记录应用程序块。存在许多更好的库-但是我总是被困在开发世界的美元菜单中。每当我听到“ Microsoft最佳做法”时,我都会发誓我认为《麦当劳的营养指南》。当然,如果跟随他们,您可能会生存,但您也会营养不良和超重。


请注意,这可能不是您的最佳做法,但这是我工作过的几乎所有地方都遵循的常见做法。


评论


听起来太可怕了……=(不过,我可能在另一方面过分了,我尽可能避免使用M $。

– Lizzan
2010-10-28 13:23

那不应该是那样的。应该选择图书馆的价值,而不仅仅是考虑谁创造了它。例如,我喜欢EF,但是我对Enterprise Library的经验很差,并且找到了更好的验证和日志记录工具,例如FluentValidation,log4net和Elmah。

–马特奥·莫斯卡(Matteo Mosca)
2010-10-28 13:28

您不会因购买IBM ^ wMicrosoft而被解雇

–克里斯托弗·马汉(Christopher Mahan)
2010-10-29 4:30

也有镜像版本,即从不使用任何Microsoft或从不使用任何您需要付费的东西。

–理查德·加兹登(Richard Gadsden)
2011-1-17的12:53

我很幸运地在一个组织中工作,而这并不是一个普遍存在的教条,但是在我们采用商业解决方案的地方,肯定会有很多痛苦。当商业解决方案的某些部分无法正常工作时,就会出现问题。当它是开放源代码时,您可以查看源代码(最终文档)并找出问题所在。使用封闭源时,您必须为获得对技术支持知识的特权而付出的特权,而技术支持知识对您所做产品的了解甚至更少。那就是唯一可用的“修复”。

–SingleNegationElimination
2011年1月29日下午6:15

#8 楼

面向对象

有一个假设,就是因为代码是“面向对象的”,所以它具有神奇的优势。因此人们继续将功能压缩到类和方法中,只是要面向对象。

评论


我无法想象在不利用对象定向提供的组织优势的情况下构建任何规模的软件系统。

–罗伯特·哈维(Robert Harvey)
2010-10-28 20:55

罗伯特Unix不是面向对象的,并且可以肯定是合格的软件系统。它似乎也很受欢迎(例如Mac OSX,iPhone,Android手机等)

–克里斯托弗·马汉(Christopher Mahan)
2010-10-29 4:29

我的意思是我认为我们应该使用最合适的方法。我已经看到人们使用繁琐且没有多大意义的方法和类,只是因为“它是面向对象的”。那是货物崇拜。

– LennyProgrammers
2010-10-29 7:49

没有银弹。在没有面向对象的情况下,函数式编程(Haskell)非常成功。归根结底,您拥有多种工具,为手头的任务选择最佳的分类是您的工作。

– Matthieu M.
2010-11-22 20:46

有趣的是,除了使用类,多态性之类的东西外,大多数面向对象的代码实际上都是过程代码。

–奥利弗·韦勒
2010年11月30日,0:05

#9 楼

所有代码都应加注释。

不,不应该。有时您会有明显的代码,例如,在执行特殊操作之前,不应注释设置器。另外,为什么我要这样评论:

/** hey you, if didn't get, it's logger. */
private static Logger logger = LoggerFactory.getLogger(MyClass.class);


评论


所有代码都应该可以理解。注释是其中的主要工具,但远非唯一。

–旅行
2011年1月17日22:27

绝对地,代码应该是可以理解的。但是没有唯一的理由写一个注释,该注释不会为方法名称添加任何内容。如果写/ **设置等级。 * / void setRank(int rank){this.rank = rank;我认为评论是愚蠢的。为什么要写?

–弗拉基米尔·伊万诺夫(Vladimir Ivanov)
2011年1月17日在22:34

生成的文档。这就是/ ** * /格式的含义,而不是/ * * /格式的注释。或.NET,它将是///

–贝琳·洛里奇(Berin Loritsch)
2011年1月18日下午16:19

使用} // end,} // end,} // end while是我见过的浪费评论的最佳示例。我已经看过很多次了,开头括号不超过2行。恕我直言,如果您需要这些注释,则您的代码需要重构...,或者您需要付20美元并购买一个IDE / Text编辑器,以突出显示匹配的花括号。

–scunliffe
2011年1月21日,11:54

代码说“如何”。评论需要说“为什么”。

–user1249
11年1月27日在18:03

#10 楼

方法论,尤其是混乱。当我听到大人使用“ Scrum Master”一词时,我不能保持直面。我非常厌倦听到开发人员抗议方法论X的某些方面对他们的公司不起作用,仅由Guru So-and-Su告诉他们,它行不通的原因是实际上他们不是真正的从业者方法论X的作者。“加倍努力,我的Padawan学习者必须加倍努力!”

敏捷方法论中有很多智慧-很多-但它们经常被充斥我无法抵抗我的呕吐反应。从Wikipedia的Scrum页面中获取以下内容:

Scrum中定义了许多角色。根据它们在开发过程中的参与性质,所有角色都分为猪和鸡两个不同的组。

真的吗?猪和鸡,你说呢?迷人!迫不及待想把这个介绍给我的老板...

评论


有趣。我在一定程度上同意。在最后一部分中:称呼您想要的东西,它们就是助记符,仅此而已。

–史蒂文·埃弗斯(Steven Evers)
2010-11-29 21:38

+1 ...您是对的,很难认真对待。 <大声的声音> *我是SCRUMMASTER *

–GrandmasterB
2010-11-29 21:50



和寓言。它让我想起教堂的讲道,或自助大师(和喜剧演员)闻名的轶事:“带我的朋友史蒂夫。史蒂夫一直在与妻子谢丽尔吵架。那两个人会花几个小时,直到他们的婚姻处于真正的危险之中。然后,有一天……”这些说教的纱线不会在其他领域打扰我,但我讨厌看到它们在工程科学中激增。

–evadeflow
2010-11-29 22:02



Scrum忍者呢?

–贝琳·洛里奇(Berin Loritsch)
2011年1月12日在18:20

我不同意“猪和鸡”的比较……它直接面对敏捷宣言。即“基于合同谈判的客户协作”。在项目成功方面,客户与项目团队一样被授予(如果不是更多的话)。称某些角色为“猪”而其他角色为“鸡”则树立了“我们与他们”的思想,即恕我直言是成功项目的最大障碍。

–迈克尔·布朗(Michael Brown)
2011年1月21日在23:58

#11 楼

对象关系映射... http://en.wikipedia.org/wiki/Object-relational_mapping

我不想从我的数据中抽象出来,也不想失去它精确的控制和优化。我在这些系统上的经验非常差。这些抽象层生成的查询甚至比我从离岸外包中看到的还要糟糕。

评论


过早的优化是万恶之源。与无法维护的代码相比,慢速代码在现实生活中仅是极少出现的问题。使用ORM,然后仅在需要时切入抽象。

– Fishtoaster
2010-10-26 18:12

ORM是80-20工具。他们的目的是要处理80%的CRUD,以至于过一会儿再写所有无尽的管道代码就变得很累。剩下的20%可以通过使用存储过程和编写普通SQL查询等“常规”方式来完成。

–罗伯特·哈维(Robert Harvey)
2010-10-26 18:13



@Fishtoaster:您的意思不是说:“我们应该忘记效率低下的问题,大约有97%的时间是这样:过早的优化是万恶之源。但是,我们不应该在这3%的临界水平上放弃机会。”

–罗伯特·哈维(Robert Harvey)
2010-10-26 18:15



@Robert Harcey:我没有使用直接引号是有原因的。我认为大多数程序员都过于关注效率问题,这是他们中很少真正需要解决的问题。诚然,在某些领域中,它比其他领域更重要,但是可维护性和可扩展性到处都是问题。另一个修改过的语录:“使其生效,使其可维护,使其易于阅读,使其具有可扩展性,使其可测试,然后,如果有时间,事实证明您需要它,则使其快速。”

– Fishtoaster
2010-10-26 18:23



@克雷格:你怎么不承认你的陈述中的讽刺?需要一年的时间来学习如何从ORM中获得良好的性能,这是反对ORM的一个极好的理由,因为需要“控制” SQL生成并注入存储过程。如果您有足够的知识,则可以完全绕过ORM。

–尼古拉斯·奈特
2010-11-22在11:48

#12 楼

将函数名称写成英语句子:

Draw_Foo()
Write_Foo()
Create_Foo()


等。这看起来不错,但是在学习API时会很痛苦。

Foo_Draw()
Foo_Write()
Foo_Create()


等。

评论


大概和在TM的功能列表中键入Foo一样容易。

–乔什·K(Josh K)
2010-10-26 17:50

听起来您实际上希望它是Foo.Draw(),Foo.Write()和Foo.Create(),以便可以执行Foo.methods.sort或Foo.methods.grep([我追求的目标] )。分类

– Inaimathi
2010-10-26 17:59

以“ Get”开头是另一个示例。

– JeffO
2010-10-26 18:25

我来自Objective-C世界,在做Java时(我的另一生)非常想念冗长的方法名和中缀表示法。自从代码完成开始工作以来,我也没有发现额外的键入问题。

–user4051
2010-10-26 18:28

@Scott Whitlock:对于某些.NET开发人员来说,iirc,VS 2008并没有做到这一点。不过2010年确实如此,这真是太棒了。

–史蒂文·埃弗斯(Steven Evers)
10 Nov 18 '21:44



#13 楼

MVC-我经常发现,将许多Web设计问题纳入MVC方法中,更多的是使框架(导轨等)满意,而不是简单或结构。 MVC是“建筑宇航员”的最爱,他们似乎过于重视简单的支架。嗯

基于类的OO-我认为鼓励复杂的可变状态结构。多年来,我发现基于类的面向对象的唯一引人注目的案例是构成任何面向对象的书的第一章的老套“形状->矩形->正方形”示例

评论


我已经在ASP.NET和ASP.NET MVC中完成了Web开发,尽管MVC似乎很简陋,但由于许多原因,我还是更喜欢ASP.NET,这有很多原因:简单性,可维护性和对标记的极好的控制。一切都有它的位置,尽管看起来有些重复,但维护起来却是一种快乐。它是完全可定制的,因此,如果您不喜欢开箱即用的行为,则可以对其进行更改。

–罗伯特·哈维(Robert Harvey)
2010-10-29 6:06



就OO而言,有好的方法也有坏的方法。继承被高估了,并且在现实世界中使用的程度比大多数人认为的要少。即使在面向对象的世界中,目前也存在着一种趋向于更加实用,一成不变的开发风格的趋势。

–罗伯特·哈维(Robert Harvey)
2010-10-29 6:08



+1代表提及MVC。尽管MVC的概念(将数据层逻辑,表示逻辑和背景逻辑分开)是一个好主意,但是将它们物理地分成一个复杂的文件夹层次结构,其中包含代码片段的文件杂乱无章,这是愚蠢的。我将整个现象归咎于PHP缺乏名称空间支持,而新手开发人员将数十年的技术赞誉为“最新的东西”。很简单,为数据库访问器,GUI和后台逻辑创建名称空间(以及需要时的子名称空间)。

–伊文·普莱斯
2010年11月19日在18:50



对于OO,直到您的项目发展到管理复杂性变得重要的规模时,您才真正看到它的好处。尽可能遵循单一责任原则,并且如果可以公开访问您的代码(例如,.dll),请在任何可能的地方隐藏类/方法/属性的内部实现,以使代码更安全并简化API。

–伊文·普莱斯
2010年11月19日在18:55

我个人认为shape-> rectangle-> square示例是反对oop的最优雅的论据之一。例如,对于Square(10).Draw()来说,Rectangle(10,10).Draw()就足够了。所以我想这意味着Square是矩形的子类。但是mySquare.setWidthHeight(5,10)是胡说八道(即,它不符合Liskov替换原理),正方形不能具有不同的高度和宽度,尽管矩形可以,因此这意味着矩形是正方形的子类。在其他情况下,这称为“圆,椭圆问题”

–SingleNegationElimination
2011年1月19日在2:32



#14 楼

YAGNI

(您将不需要它)

这种方法使我不得不花费数小时的时间,而当我不得不在现有代码库上实现功能时,需要仔细计划

我的想法经常由于YAGNI而被拒绝,并且在大多数情况下,有人不得不稍后为该决定付费。

(当然一个可能会争辩说,精心设计的代码库也将允许以后添加功能,但实际情况有所不同)

评论


我同意YAGNI,但我明白您的意思。 YAGNI的重点是与想要从头到尾计划所有细节的人员打交道。尽管十分之九,但它却被用作借用工程师代码或完全跳过计划的借口。

–杰森·贝克(Jason Baker)
2010-11-29 19:55

P.Floyd,@ Jason Baker:+1完全正确。俗话在这里适用:“在实验室工作数月可节省图书馆时间”

–史蒂文·埃弗斯(Steven Evers)
2010-11-29 21:40

规范通常会(而且大多数情况下应该)保留大多数实现,并且某些接口是开放的。规范中没有直接列出的所有内容,而是实现规范所需的所有内容,无论是实现决策,用户可见的界面还是其他任何内容,也都是规范的间接要求。如果某个功能不在规范中,并且未在规范中隐含,那么您就不需要它。这怎么会令人困惑?

–SingleNegationElimination
11年1月28日在14:01

@TokenMacGuy的关键方面是规范部分所隐含的内容。那是意见分歧很大的地方。

–塞恩·帕特里克·弗洛伊德(Sean Patrick Floyd)
11年1月28日在14:04

#15 楼

对于SQL


不要使用触发器
始终将表隐藏在视图后面

顺序:


它们是具有此功能的功能。您有一个表的多个更新路径,或需要100%审核?
为什么?如果要重构以维护合同,我会这样做,但是当我读到人们更改视图以匹配任何表更改时,我会这样做

编辑:

数字3:避免*有EXISTS。尝试1/0。有用。列列表未按照SQL标准进行评估。第191页

评论


#2是最佳做法?

– Hogan
2010-10-27 3:35

@Hogan:是的,它在许多地方都有记录vyaskn.tripod.com/sql_server_security_best_practices.htm和flylib.com/books/en/3.404.1.34/1在这里很少:simple-talk.com/community/blogs/tony_davis/存档/ 2009/08/06 /…

– gbn
2010-10-27 3:57



@Hogan:仅镜像基本表的视图不会增加直接使用基本表的安全性。如果您连接到securityuser表,或者掩盖了某些列,那么就足够了。但是从表或视图中选择每一列:没有区别。就我个人而言,我还是使用存储过程。

– gbn
10-10-27在11:20

@Hogan:我对SQL Server有所了解:-) stackoverflow.com/users/27535/gbn我的意思是,如果视图是SELECT * FROM TABLE,则表上的GRANT SELECT与GRANT SELECT ON VIEW没有区别

– gbn
10-10-27在11:42

@gbn:我同意。那里没有区别。我想我们可能会说同样的话。我想我最初的评论(“#2是最佳实践吗?”)更多地基于我的个人经验,即视图(如触发器)经常被误用而不是正确使用。因此,这种最佳做法只会导致滥用,而不会导致滥用。如果它被认为是一种最佳实践,那么您100%正确,那就不好了。

– Hogan
2010-10-27 22:53

#16 楼

主要是设计模式。它们被过度使用和利用不足。

评论


+1我仍然看不到设计模式是美观还是优雅的解决方案。它们是针对语言缺陷的解决方法,仅此而已。

–奥利弗·韦勒
2010-11-30 0:02

只是将其视为使用语言本身消除语言气味的一种尝试。

–FilipDupanović
2011年1月18日,下午2:10

#17 楼

单一责任原则
(“每个班级应该只有一个责任;换句话说,每个班级应该只有一个,并且只有一个改变的理由”)。
我不同意。我认为一个方法应该只具有一个更改的理由,并且一个类中的所有方法都应该与另一个逻辑上具有逻辑关系,但是该类本身实际上可能会做几件事(相关)。
以我的经验,原理经常过于热心地应用,并且您最终会遇到许多微小的单方法类。我工作过的两家敏捷商店都做到了这一点。 ()等,我们将拥有ListSorter,ListReverser和ListSearcher类!
不再与SRP争论(从理论上讲,它本身并不可怕),我将分享其中一些轶事经验:

在我工作的地方,我写了一个非常简单的最大流求解器,它由五类组成:节点,图,图创建器,图求解器和一类使用图形创建器/求解器解决实际问题。没有一个特别复杂或很长(求解器最长的〜150行)。但是,确定类具有太多的“职责”,因此我的同事着手重构代码。完成后,我的5个班级已扩展到25个班级,它们的总代码行是原来的三倍多。代码的流程不再明显,新的单元测试的目的也不再明显。我现在很难弄清楚自己的代码做了什么。

在同一地方,几乎每个类都只有一个方法(它只有“责任”)。遵循程序中的流程几乎是不可能的,并且大多数单元测试都包括测试该类是否从另一个类调用代码,这两个目的对我来说都是一个谜。从字面上讲,有数百个班级应该只有几十个班级。每个类仅执行一个“操作”,但是即使使用“ AdminUserCreationAttemptorFactory”之类的命名约定,也很难分辨出类之间的关系。

在另一个地方(也具有应有的类) -一种方法的思维方式),我们正在尝试优化一种方法,该方法在特定操作期间会占用95%的时间。经过(相当愚蠢的)优化后,我将注意力转向了为什么它被称为“ bajillion次”。在一个类的一个循环中被调用...在另一个类的一个循环中被调用其方法。在一个循环中也被调用。分布了13个班级(严重)。仅仅通过查看它就无法确定任何一个类实际上正在执行的操作-您必须绘制一个心理图,说明它调用了什么方法以及这些方法调用了什么方法,等等。如果全部归为一种方法,那么问题方法将嵌套在五个显而易见的循环中,那么它的长度只有70行左右。
我将这13个类重构为一个类的请求被拒绝了。

评论


听起来有人在工作中得了“发烧”,或者在这种情况下是“原理发烧”。列表类不违反SRP。它的所有功能都有一个目的,即操纵对象的集合。在班上只有一个功能听起来对我来说太过分了。 SRP背后的原理是,一个代码单元(无论是方法,类还是库)都应具有单一职责,可以简明地表述。

–迈克尔·布朗(Michael Brown)
2011年1月22日,0:37

我开始从那些发现不可能编写纯粹的纯函数代码的人那里看到这种疯狂。太多的教育使世界上的每个问题都可以从一本模式书中解决。关于实用主义的想法还不够。像您一样,我已经看到了一些基于类的OO代码,它们是如此可怕,以至于完全不可能遵循它。而且它巨大而肿。

–quickly_now
2011年2月6日在9:51

在这里第二条评论。许多“原则”被过度应用。很多事情都是好主意,有时恰恰相反是合适的。好的程序员知道什么时候打破规则。因为这些规则不是“规则”,所以它们是“大多数时候的良好做法的陈述,除非它是一个愚蠢的想法”。

–quickly_now
2011-2-6在9:53

“想象一下,.Net API的创建者是否有这种想法:我们将拥有ListSorter,ListReverser和ListSearcher类,而不是List.Sort(),List.Reverse(),List.Find()等。 !”。这正是在C ++中完成的工作,非常好。这些算法与数据结构是分开的,因此,如果我编写自己的容器,则所有与标准库一起使用的算法都将与我的新容器一起使用。它在.Net领域中必须是可怕的,为要排序的每个新容器编写了一个新的排序功能。

– Mankarse
2011-10-26 12:14

#18 楼

既然您已经提到了“干净代码”,尽管它包含一些好主意,但我认为它对将所有方法重构为子方法以及将那些方法重构为子子方法等的痴迷程度实在是太过分了。您应该使用二十行(据说是好命名的)一线而不是十行方法。显然有人认为它很干净,但对我来说,它似乎比原始版本差很多。

还替换了诸如

0 == memberArray.length


>在类中调用该类自己的方法(如

isEmpty()


)是可疑的“改进”恕我直言。另外:不同之处在于第一次检查完全按照它的意思:检查数组长度是否为0。好吧,isEmpty()也可能会检查数组长度。但是它也可以这样实现:

return null != memberArray ? 0 == memberArray.length : true;


即,它包含一个隐式的空检查!对于公共方法来说,这可能是好的行为-如果数组为null,则某些东西肯定为空-但是当我们谈论类内部时,这不是很好。虽然必须封装到外部,但类内部必须准确知道类中发生的事情。您不能从自身封装类。显式要比隐式好。



这并不是说破坏长方法或进行逻辑比较是不好的。当然可以,但是在什么程度上做(甜蜜点在哪里)显然是口味的问题。分解一个长方法会导致更多方法,而这并非免费。如果所有内容都在一个方法中,您可以一目了然地看到源代码,那么您就必须跳过源代码。

我什至会深入探讨说在某些情况下1行方法太短了,不应该成为方法。

评论


我很少将此视为问题。通常,这是因为我通常在一种方法中看到的太多而不是很少。但是,根据某些研究,方法的极低复杂度也比中等程度的低复杂度具有更高的错误率。 enerjy.com/blog/?p=198

– MIA
2010-10-27 15:30

是的,这绝对只是Clean Code中的问题。正如您所说,在现实生活中方法往往太长。但有趣的是看到那条曲线!确实,应该使事情尽可能简单,但不要简单。

–乔纳斯·普拉卡(Joonas Pulakka)
2010-10-27 16:16

我发现您的第二个示例更具可读性,并且如果要公开它,则必须使用该格式(或类似的名称,例如类本身的Length属性)。

–罗伯特·哈维(Robert Harvey)
2010-10-27 22:13



@Robert Harvey:第二个示例是一个很好的公共方法,但是从类本身内部调用它是有问题的,因为在了解如何实现之前您并不确切知道它的作用。例如,它可以检查是否为空。请参阅上面的内容。

–乔纳斯·普拉卡(Joonas Pulakka)
10-10-28在5:58



@乔纳斯:足够公平。

–罗伯特·哈维(Robert Harvey)
10-10-28在21:08

#19 楼

“发表评论要宽容”

评论绝对是一件好事,但太多的评论同样是不好的,甚至还不够不够。为什么?好吧,如果看到太多不必要的注释,人们倾向于将注释调出。我并不是说您可以拥有完全自我记录的代码,但是最好使用需要注释的代码进行解释。

评论


自我记录代码绝对不错。虽然,我喜欢在注释旁边加上简单的计算(以表示返回类型或返回值是什么)。但是,如果您的注释需要比代码本身更多的单词,那么可能是时候重写代码了。

– sova
2010-11-29 20:11

我必须同意sova提出这一建议的方式。干净的代码胜于注释。

–riwalk
2010-11-29 23:47

您仍然需要其中的“为什么”!

–user1249
2011年1月21日,0:04

我宁愿评论解释原因。这意味着当我查看代码意图时,我不得不减少对反向代码意图的思考。

–quickly_now
2011年1月21日,1:17

#20 楼

GoTo被认为有害

如果要实现状态机,则GOTO语句比“结构化编程”方法更有意义(可读性和高效的代码)。当我在一份新工作中编写的第一段代码不仅包含一个goto语句,而且包含多个goto语句时,这确实使某些同事感到担忧。幸运的是,他们足够聪明,以至于意识到这实际上是在特定情况下的最佳解决方案。

任何不允许对规则进行明智且有文件证明的例外的“最佳实践”简直是吓人。

评论


我正在进行九年的编程,没有一个goto语句(如您所述,包括多个状态机)。将您的想法扩展到新的想法。

–riwalk
10-11-22在4:46



@Mathieu M.-同意-将GOTO与结构化控制语句混合是不明智的。 (这是纯C语言,这不是问题。

– MZB
10 Nov 25'0:22

@ Stargazer2-使用简单的FSM,它取决于是否将状态放入变量中并将其用作调用过程的索引(与计算出的GOTO是否相同?)是否比使用程序计数器提供了更清晰/更快的代码作为FSM状态。我并不是在大多数情况下都主张将其作为最佳解决方案,而在某些情况下仅是最佳解决方案。将您的想法扩展到其他方法。

– MZB
10 Nov 25'0:31

@MZB,您是否同意函数调用也只是计算得出的GOTO?同样,for / while / if / else / switch构造也适用。语言设计人员出于某种原因将直接更改抽象到程序计数器。不要使用goto。

–riwalk
2010-11-29 22:37



直接实现状态机可能是一种反模式。在没有字面表示状态和过渡的情况下,有很多方法可以拥有状态机。例如,导入重新

–SingleNegationElimination
2011年1月19日,下午2:37

#21 楼

为使代码可测试而做出的牺牲
我花了很多时间使代码可测试,但是我不假装如果选择的话就不会。但是,我经常听到人们推崇这些是“最佳实践”的想法。这些做法包括(以.Net语言编写,但也适用于其他语言):


为每个类创建一个接口。这使要处理的类(文件)数量增加了一倍,并重复了代码。是的,接口编程是好的,但这是公共/私有说明符的意思。

每个未在启动时实例化的类都需要一个工厂。显然,new MyClass()比编写工厂要简单得多,但是现在不能单独测试创建它的方法。如果不是因为这个事实,我只会使我现在做的工厂类的数量增加1/20。

使每个类公开,这根本就没有在类上使用访问说明符的目的。但是,不能从其他项目访问(因此要测试)非公共类,因此,唯一的选择是将所有测试代码移至同一项目(并随最终产品一起发布)。
< br Dependency Injection。显然,必须给其他所有类使用一个字段和一个构造函数参数,这比仅在需要它们时创建它们要多得多。但是后来我再也不能孤立地测试这个课程了。

单一责任原则使我头疼不已,我将其转移到自己的答案上。

那么我们该怎么做才能解决此问题?我们需要对语言体系结构进行彻底的更改:

我们需要模拟类的能力
我们需要从另一个项目测试内部类的私有方法的能力(这似乎是一个安全漏洞,但是如果被测者被迫命名其测试人员类别,我看不出任何问题。)
依赖注入(或服务位置)以及与我们现有工厂模式等效的东西必须成为该语言的核心部分。

简而言之,我们需要一种从头开始设计的语言,考虑可测试性。

评论


我猜您从未听说过TypeMock吗?它允许模拟类,私有,静态(工厂)等任何东西。

– Allon Guralnek
2011年1月20日23:16

@Allon:我有,但是它并不是免费的,这对于大多数人来说不是一个选择。

– BlueRaja-Danny Pflughoeft
2011年1月20日23:30



如果您必须编写许多工厂类,那么您在做错什么。智能DI库(例如C#的Autofac)可以将Func ,Lazy ,Delegates等用于工厂,而无需自己编写任何样板文件。

– Gix
2011-2-22 15:01

#22 楼

将应用程序划分为多个层;数据层,业务层,UI层

我不喜欢这样做的主要原因是,大多数遵循此方法的地方都使用非常脆弱的框架来完成此工作。即UI层是经过手工编码的,用于处理业务层对象;业务层是经过手工编码的,以处理业务规则和数据库;数据库是SQL,已经非常脆弱,并且由不喜欢更改的“ DBA”组管理。

为什么这样不好?最常见的增强请求可能是“我需要屏幕X上具有Y的字段”。砰!您只是拥有一个影响每个单独层的新功能,并且如果您与不同的程序员将各个层分开,那么对于一个非常简单的更改,它就成为涉及多个人员和小组的大问题。

不知道我参加过像这样的争论有多少次了。 “名称字段的最大长度限制为30,这是UI层,业务层还是数据层问题?”有一百个论点,没有正确的答案。答案是相同的,它影响所有层,您不想使UI变得笨拙,而不必遍历所有层,并在数据库上失败,只是为了让用户发现他的输入太长。如果更改它,它将影响所有图层,等等。

“图层”也容易泄漏;如果任何层在物理上都被流程/机器边界(即Web UI和业务后端逻辑)隔开,则规则将重复以使所有事情都正常运行。即即使这是“业务规则”,某些业务逻辑也会出现在UI中,因为用户需要UI能够响应。

如果所使用的框架或所使用的体系结构能够抵抗微小的变化和泄漏,即基于元数据并在所有层中进行动态调整,则可以减轻痛苦。但是,对于大多数框架而言,这是一个皇家难题,需要对UI进行更改,对业务层进行更改以及对数据库进行更改,每进行一次小更改,都会比该技术产生的工作量更多,所需的帮助也更少。可能会为此受到猛烈抨击,但事实是:)

评论


+1,听起来像是我最后就业的最细微之处!我原则上尊重分层应用程序,但是在没有意义时,太多的人将其视为灵丹妙药。大多数业务软件的业务逻辑量极低,其功能相对简单。这会使分层业务逻辑成为样板代码的噩梦。很多时候,数据查询和业务逻辑之间的界限可能会变得模糊,因为查询就是业务逻辑。

– Maple_shaft♦
2011年6月23日12:42

……此外,大多数商店绝对无法识别UI逻辑或Presentation逻辑。因为他们不了解典型的CRUD应用程序中几乎没有多少业务逻辑,所以当他们的大多数逻辑作为表示逻辑驻留在表示层时,他们会觉得自己必须做错了。它被错误地标识为业务逻辑,然后人们将其推到服务器以进行另一个服务器调用。瘦客户端可以并且应该具有表示逻辑,例如。 (如果在dropDown3中选择了option1,则隐藏textField2)。

– Maple_shaft♦
2011年6月23日12:46

#23 楼

JavaBeans

在Java中使用JavaBeans。看到我的问题为什么我不应该使用不可变的POJO而不是JavaBean?在StackOverflow上。

#24 楼

用户故事/用例/角色



我了解在为您不熟悉的行业编程时需要这些,但是我认为当他们熟悉时全力实施,他们变得太有组织,浪费时间。

#25 楼

80个字符/行的限制是愚蠢的

我知道需要做出一些折衷来匹配GUI端最慢的运行程序的速度(屏幕分辨率限制等),但是为什么该规则适用代码格式化?

请参阅...有一个小发明叫水平滚动条,它是为了管理最右边像素边界之外的虚拟屏幕空间而创建的。为什么成功开发了强大的生产力增强工具(例如语法突出显示和自动完成)的开发人员不使用它呢?

当然,* nix恐龙会虔诚地使用CLI编辑器来跟随疲倦的老用户VT220终端的限制,但是为什么我们其他人都遵循相同的标准?

我说,拧紧80个字符的限制。如果恐龙足够强大,可以整天攻击emacs / vim,为什么它不能创建自动包装线的扩展或为其CLI IDE提供水平滚动功能?

1920x1080像素监视器最终将成为常态,并且全世界的开发人员仍然生活在相同的局限性内,与他们为什么这么做无关,只是他们的长辈在开始编程时就告诉他们这样做。

80个字符数的限制不是最佳实践,而是对极少数程序员的一个小众实践,应该这样对待。

编辑:不喜欢水平滚动条,因为它需要鼠标手势,所以...为什么不为使用现代显示器的我们这些人增加列宽限制(大于80)。

当800x600的计算机显示器成为大多数用户的标准时,Web开发人员增加了他们的网站宽度以容纳大多数用户...为什么开发人员无法做到这一点。

评论


@Or__ ___启用Nice GWB逻辑是邪恶的角度。因此,您讨厌hScroll,您是否有任何合理的理由将col-width限制为80个字符?为什么不160或256?我认为我们都可以假设大多数开发人员已经淘汰了他们的VT220终端,并用puTTY替换了它们,因此他们无论如何都可以通过编程方式扩展宽度。

–伊文·普莱斯
2011年1月18日,下午1:38

我更喜欢我们坚持80个字符的限制。您给我更多的水平空间后,我将尝试与其他文件并排打开其他文件。我讨厌必须滚动四种方式。另外,我经常注意到我被迫使用80个字符的上限编写更具可读性的代码。

–FilipDupanović
2011-1-18的2:17

您将如何打印?

–user1249
2011年1月21日,0:11

抱歉-必须对此表示不同意见。我真的很讨厌长长的线-它需要更多的眼睛移动,它需要鼠标手势滚动,它很难看到行尾的微妙的晃动的东西。在大约99%的情况下,有一些干净的方法可以使内容跨几行(更短)运行,这更清晰,更易于阅读。 80个字符可能是任意的,并且“因为在打孔卡时代就是这样”,但由于上述原因,在大多数情况下,它仍然是一个合理的工作框架。

–quickly_now
2011年1月21日,在1:25

缩进2个空格。并使用带有自动缩进跟踪器的编辑器。多年来,我一直这样做,没什么大不了的。 (具有正确模式的Emacs在这里有帮助。)

–quickly_now
2011年2月6日上午9:47

#26 楼

量度,量度,量度

很好,量度,但是为了隔离性能错误,量度工作以及相继消除。这是我使用的方法。

我一直在努力寻找“智慧”度量的来源。有人用一个足够高的肥皂盒说了它,现在它可以旅行了。

#27 楼

我的老师要求我以小写字母开头所有标识符(不包括常量),例如myVariable

我知道这似乎是一件小事,但是许多编程语言都要求变量以大写字母开头。我重视一致性,因此我的习惯是,所有内容都以大写字母开头。

评论


我有一位需要camelCase的老师,因为他坚持这是人们在现实世界中使用的东西...同时,我在工作时在两个不同的小组中进行编程-两个小组都坚持使用under_scores。重要的是您的小组使用什么。他本可以将自己定义为首席程序员,但在我的书中,一切都会好起来的-我们遵循他的惯例-但他始终将自己的观点视为“现实世界中的工作方式”,就好像没有其他有效的方法一样。道路。

–xnine
2010-11-30 4:42

@xnine我在该网站上没有足够的代表来评价您的评论,因此,我将以同意的评论进行回复。

– Maxpm
2010-11-30 4:44



驼峰式大小写(首字母小写)和帕斯卡大小写(大写的每个单词的首字母)都是很常见的约定。在大多数语言中,camelCase用于私有/内部变量,而PascalCase用于类,方法,属性,名称空间,公共变量。习惯于为可能使用不同命名方案的项目做好准备并不是一个坏习惯。

–伊文·普莱斯
2011年1月12日在16:18

仅供参考。一些语言根据变量的首字母是否大写来推断含义。在这种语言中,如果第一个字母为大写字母,则将变量视为常量,任何对其进行更改的尝试都会引发错误。

–贝琳·洛里奇(Berin Loritsch)
2011年1月12日在18:28

在Go中,公共方法和类中的成员以大写字母开头;带有小写字母的私人字母。

–乔纳森·莱弗勒(Jonathan Leffler)
2011年1月18日14:39

#28 楼

使用Singletons
当您仅应拥有某事物的一个实例时。我不能不同意。切勿使用单例,仅分配一次,并根据需要传递指针/对象/引用。绝对没有理由不这样做。

评论


那是一堆负面因素,使我对您对单身人士的实际立场感到困惑。

–Paul Butcher
2010-11-30在11:17

@Paul Butcher:我讨厌单身人士,永远不应该使用它

–user2528
2010年12月1日,7:58

@rwong:就我个人而言,我认为没有任何理由是合法的。只需将其编写为普通班级即可。确实,除了懒惰之外,没有任何理由使用单身人士来提倡不良习惯或设计。

–user2528
2010年12月1日于22:23

谁说使用Singeltons是最佳做法?

–菲尔·曼德(Phil Mander)
2010-12-10在0:29

单例确实有其位置,尤其是在启动时分配并填充了操作结构的情况下,然后基本上在整个程序运行时才变为只读。在那种情况下,它只是变成了指针另一侧的缓存。

– Tim Post
2010-12-10 8:06

#29 楼

将unsigned int用作迭代器

他们何时会知道使用signed int更加安全,而且不易出错。为什么数组索引只能是正数,为什么每个人都高兴地忽略4-5是4294967295的事实,这是如此重要?

评论


好吧,现在我很好奇-为什么这么说?我有点傻-您可以提供一些代码示例来备份您的语句吗?

– Paul Nathan
2010-12-10 3:22

@Paul Nathan:就越野车而言,这是一个示例:for(unsigned int i = 0; i <10; i ++){int crash_here = my_array [max(i-1,0)];}

– AareP
2010-12-10 5:59

@AareP:可以肯定的是-我假设您引用的事实是,当将无符号整数0减1时,您实际上最终会获得无符号整数可能存储的最大正值吗?

–亚当·佩恩特(Adam Paynter)
2010-12-10 10:11

@Adam Paynter:是的。对于c ++程序员来说,这似乎很正常,但是让我们面对现实吧,“ unsigned int”是正数的一种不好的“实现”。

– AareP
2010-12-10 11:19

在小型嵌入式计算机上不是一个好主意-经常使用无符号int会生成更小,更快的代码。取决于编译器和处理器。

–quickly_now
2011年1月21日,1:19

#30 楼

方法的长度不应超过一个单一的屏幕

我完全同意单一职责原则,但是为什么人们会认为它是指“一个功能/方法在职责范围内只能承担单一职责”最好的逻辑粒度级别?”

这个想法很简单。一种功能/方法应完成一项任务。如果该功能/方法的一部分可以在其他地方使用,请将其切成自己的功能/方法。如果可以在项目的其他地方使用它,请将其移到其自己的类或实用程序类中,并使其在内部可访问。

具有一个包含27个帮助器方法的类,该方法在代码中仅被调用一次笨拙,浪费空间,不必要的复杂性增加以及大量的时间消耗。对于想忙于重构代码但又不会产生太多代码的人来说,这听起来似乎是个好规则。

这是我的规则...

将函数/方法编写为完成某些事情

如果您发现自己要复制/粘贴一些代码,请问自己是否为该代码创建函数/方法会更好。如果一个函数/方法在另一个函数/方法中仅被调用一次,那么将它放在首位真的有一点意义(将来会被更频繁地调用)。在调试期间添加更多的函数/方法跳转是否有价值(即,添加的跳转是否会使调试更容易或更难)?

我完全同意大于200行的函数/方法需要需要仔细检查,但是某些功能只能在许多行中完成一项任务,并且不包含可以在项目的其余部分中抽象/使用的有用部分。

我从API开发人员的角度来看。 ..如果新用户要查看代码的类图,则该图的多少部分将在整个项目的整个范围内有意义,而有多少部分将仅作为项目内部其他部分的助手而存在。 br />
如果要在两个程序员之间进行选择:第一个倾向于编写试图做太多事情的函数/方法。第二个将每个函数/方法的每个部分分解到最细粒度的层次;我会选择第一手放下手。第一个将完成更多的工作(即编写更多的应用程序内容),其代码将更易于调试(由于调试期间函数/方法的跳入/跳出次数减少),并且他将花费更少的时间进行忙碌的工作来完善代码看起来比完善代码的工作方式要好。

限制不必要的抽象,并且不会污染自动完成功能。

评论


这个。我曾经将一个长函数重构为几个,只是意识到几乎所有函数都需要原始代码的几乎所有参数。参数处理非常痛苦,以至于回到旧代码更容易。

–l0b0
2011-1-17 14:59

我认为对此有一个反论点,那就是将大型方法的各个部分重构为单独的调用可以使大型方法更易于阅读。即使该方法仅被调用一次。

–杰里米·海勒(Jeremy Heiler)
2011-1-17的15:33

@Jeremy怎么样?与仅在一行代码段中描述一行代码的顶部放置一行注释相比,抽象出一段代码并将其放在自己的方法中如何使代码更具可读性?假设该代码块在该代码段中仅使用一次。对于大多数程序员来说,在阅读代码时分解代码的工作部分和/或放置一些单行注释以提醒他们如果不能做的话真的难吗?

–伊文·普莱斯
2011-1-18的1:28



@Evan:将代码段有效地放入函数中可以为其命名,希望很好地解释该代码段的作用。现在,无论该代码段被调用到哪里,您都可以看到名称来解释代码的作用,而不必分析和理解算法本身。如果做得好,这可以极大地简化阅读和理解代码的过程。

–sbi
2011年1月19日19:00

+1,如果可以的话,我会付出更多。单个函数中有1000行代码的C代码块没有任何问题(例如,带有大型switch()的解析器),其目的是明确而简单的。淘汰所有小片段并称呼它们只会使事情变得更难以理解。当然,这也有局限性。明智的判断就是一切。

–quickly_now
2011年1月21日,下午1:22