Questions tagged «programming-practices»

编程实践是软件开发中常用或不常用的实践。这些可以包括敏捷开发,看板,编码快捷方式等。

22
为什么有些程序员认为理论与实践之间存在差异?[关闭]
将软件工程与土木工程进行比较时,我惊讶地发现了另一种思维方式:任何土木工程师都知道,如果您想在花园中建造一个小木屋,则只需获取材料并进行建造,而如果您要建造一栋10层高的房子(或类似这样的房子),您需要做一些数学运算以确保它不会崩溃。 相反,在与一些程序员交谈或阅读博客或论坛时,我经常发现一种广泛的观点,可以或多或少地提出如下观点:理论和形式方法适用于数学家/科学家,而编程则更多地是要把事情做好。 这里通常暗示的是编程是非常实用的东西,即使形式方法,数学,算法理论,简洁/连贯的编程语言等可能是有趣的主题,但如果所有人都想得到东西,通常就不需要它们了。完成。 根据我的经验,我想说的是,虽然您不需要太多理论来编写100行脚本(小屋),但是要开发复杂的应用程序(10层建筑),则需要结构化的设计,定义的方法,良好的编程语言,可在其中查找算法的良好教科书等。 因此,IMO(适量的)理论是完成任务的工具之一。 我的问题是,为什么有些程序员认为理论(形式方法)与实践(完成任务)之间存在差异? 与土木工程(房屋)相比,软件工程(房屋软件)是否被许多人认为 容易? 还是这两个学科真的不同(除了关键任务软件,软件故障比构建故障更容易接受)? 我尝试总结一下,到目前为止,我已经从答案中了解了什么。 与软件工程相反,在土木工程中,对于特定任务需要多少理论量(建模,设计)更加清楚。 部分原因是因为土木工程与人类一样古老,而软件工程仅存在了几十年。 另一个原因是软件是一种更具可变性的人工产品,具有更灵活的要求(可能会崩溃),不同的营销策略(可以牺牲良好的设计以便快速将其投放市场)等。 结果,要确定在软件工程中合适的设计/理论量是非常困难的(太少->凌乱的代码,太多->我永远无法完成),因为没有通用规则,而只有(很多)经验可以提供帮助。 因此,如果我正确地解释了您的答案,那么 对于真正需要多少理论的不确定性会导致一些程序员对理论的爱恨交加。

16
通常,在大多数编程工作中,全新软件的创建是否都是主要的一部分?[关闭]
我从事软件开发工作已有10多年了,但我却很少能创建任何“新”东西,这使我感到惊奇。我意识到“新”是一个模糊的术语,但是我将其定义为从明显的新大型项目到现有项目中的新大型功能的任何内容(例如,需要对其设计进行一些思考,并且可能需要2周或更长时间才能完成)。如果需要书面说明,粗略的指导也许是新的东西。我认为大多数程序员都知道我在说什么-您正在开发中,正在快速编写大量代码。 无论如何,回想我所做的事情,我估计我只有不到10%的时间花在“新”工作上。诸如“使现有系统适应在新环境中工作”之类的事情当然需要进行大量规划,但是实际的编码和“新事物”归结为在整个代码中的许多地方进行了微小的更改。同样,对于小型功能请求-如果我知道该怎么做,通常可以在一个小时内完成,如果我不知道,那么很多阅读代码并弄清楚该做什么(这使我感到沮丧,因为我学习了做的更好,而不是阅读)。 总的来说,我觉得我大部分时间都没有创造任何东西。我以为大多数地方都是这种情况-新产品会很快推出,到那时每个人都会很兴奋,并以快速的速度发布代码,但是一旦上线,它就会进入维护模式,随后的更改很少被认为是“新的和创造性的”。 我错了吗?我是准确地描述了大多数编程工作,还是大多数程序员都觉得自己经常在创造新事物?

10
是否存在过多的私有功能/方法?
我了解文件齐全的代码的重要性。但是我也了解自我记录代码的重要性。直观地读取特定功能越容易,我们在软件维护期间就可以进行得越快。 话虽如此,我喜欢将大型功能分离为其他较小的功能。但是我这样做的程度是,一个班级最多可以有五个班级,以服务于一种公共方法。现在将五个私有方法乘以五个公共方法,您会得到大约二十五个隐藏方法,这些隐藏方法可能只会被那些公共方法调用一次。 当然,现在可以更轻松地阅读这些公共方法,但是我不禁认为,拥有太多函数是不明智的做法。 [编辑] 人们一直在问我为什么认为过多的功能是不好的做法。 简单的答案:这是一种直觉。 我的信念一点都没有任何小时的软件工程经验作为后盾。只是不确定性给了我一个“作家的障碍”,但对于程序员而言。 过去,我只编写个人项目。就在最近,我开始进行基于团队的项目。现在,我想确保其他人可以阅读和理解我的代码。 我不确定会提高可读性。一方面,我正在考虑将一个较大的功能分成名称可理解的其他较小的功能。但是我还有另一面说这是多余的。 因此,我要对此进行启发以选择正确的路径。 [编辑] 下面,我包括我怎么两个版本可以解决我的问题。第一个解决方案是不分离大块代码。第二个做不同的东西。 第一版: public static int Main() { // Displays the menu. Console.WriteLine("Pick your option"); Console.Writeline("[1] Input and display a polynomial"); Console.WriteLine("[2] Add two polynomials"); Console.WriteLine("[3] Subtract two polynomials"); Console.WriteLine("[4] Differentiate two polynomials"); Console.WriteLine("[0] Quit"); } 第二版: public static int …


16
if / return的最佳做法
我想知道当我有if陈述时被认为是更好的返回方法。 范例1: public bool MyFunction() { // Get some string for this example string myString = GetString(); if (myString == null) { return false; } else { myString = "Name " + myString; // Do something more here... return true; } } 范例2: public bool MyFunction() { // Get some …

11
什么时候提交代码?
当在项目上工作时,可以在几天或一点点的时间内,以相当快的速度开发代码,并持续数周/月/年。随着代码提交已被视为衡量项目开发的标准,这并不意味着编写的代码要比提交次数少的项目多。 所以问题是什么时候真正对存储库进行提交,以便提交是合理的? 作为附加组件:根据提交的数量来衡量项目的开发是否正确?

10
程序为什么要使用闭包?
在阅读了许多解释闭包的文章之后,我仍然缺少一个关键概念:为什么要写闭包? 程序员将执行什么样的特定任务,最好通过闭包来完成? Swift中闭包的示例是访问NSUrl并使用反向地址解析器。这是一个这样的例子。不幸的是,这些课程只是关闭。他们没有解释为什么将代码解决方案写为闭包。 一个现实世界中编程问题的示例可能会触发我的大脑说:“啊哈,我应该为此写一个闭包”,这比理论上的讨论要有用得多。该站点上不乏理论讨论。


17
专业版本控制的替代方法
我们正在与一些需要为我们的项目之一做出贡献的非程序员(作家)合作。 现在,他们只是不喜欢使用Git(或与此相关的任何东西)进行版本控制其工作的想法。我认为这是因为他们只是觉得不值得把头放在版本控制的扭曲概念上。(当我第一次向他们介绍分支和合并时-他们看起来像是冒犯了他们。) 现在,我们无法对他们进行教育或说服他们使用它。我们只是在尝试寻找替代方案,以便我们对他们的所有工作进行版本化(这是我们所需要的),并且他们可以轻松地进行工作流并专注于自己的工作。 我想出了一些主意... 告诉他们每次进行不重要的更改时都将工作另存为单独的文件,然后在我们这边使用diff来跟踪更改。 用Python编写一个以某种方式实现CSSEdit中“里程碑”的程序。 关于该项目: 它是一种自然语言处理系统(用C + Python编写)。我们已经聘请了一些作家来用不同的语言为系统准备输入。随着软件的发展,我们需要那些作者来更改他们的输入(文章)。有时变化很小(一两个字),而其他时候变化很大。 我们需要对这些更改进行版本控制的原因是,输入中的每个小/大更改都有可能显着更改系统的输出。

6
做一个小的改变,进行测试,然后“漂洗并重复”,这是一个坏习惯吗?
我是一位具有多年经验的程序员。我意识到我有一定的习惯。我不确定这是否真的是个坏习惯。 我会列出要为解决方案执行的任务的清单,例如一些小的小任务, 更改此用户控件的资源 更改另一个尺寸 在另一个用户控件上添加一些HTML和编码 所有这些任务都很小。我的意思是,它们可以在10分钟内完成,但是我习惯于进行一些小的更改,然后在Web浏览器中一次又一次地测试它们。这是一个好习惯吗? 还是我应该一次执行所有这些,然后一起测试? 如果这确实是个坏习惯,那么我该如何改正它,因为这就像浪费时间反复测试小变化?

8
测试人员竞相看看谁打开了更多的漏洞,这很好吗?
我是软件开发人员。有一组测试人员,他们遵循并运行由分析师编写的测试用例,但也执行探索性测试。似乎测试人员一直在竞争,看看谁可以打开更多错误,而且我注意到错误报告的质量下降了。除了测试功能和报告与软件操作有关的错误外,测试人员还提交了有关屏幕增强,可用性或愚蠢错误的错误。 这对项目有好处吗?如果不是,我(作为软件开发人员)如何尝试改变测试人员团队的想法和态度? 另一个问题是,由于截止日期是估计的并且无法更改,因此随着截止日期的临近,测试人员将争先恐后地完成他们的测试用例,这将导致测试质量下降。这将导致合法的错误出现在客户端收到的最终产品中。 OBS:此竞赛不是公司的惯例!这是仅由他们组织的测试人员之间的竞赛,没有任何奖项。

8
MVC体系结构—我需要多少个控制器?
我已经编码了一段时间,但主要是脚本和简单的应用程序。我已经升任新职位,其职责是开发Web应用程序并使用适当的MVC架构,因此我拼命尝试快速了解所有内容。 我希望这个问题与“ MVC体系结构的最佳实践 ”不太相似,但是当我浏览一些不同的教程时,我注意到其中有些具有针对不同事物的多个控制器。 一个Web应用程序需要多少个控制器? 我意识到如果没有示例,这将很难回答,因此我将提供一个示例: 应用: 用户登录。 用户可以做以下三件事之一: a) 上传一个文件(与元数据一起存储在mongodb数据库中)。 b) 搜索文件。 c) 注销。 我的问题很笼统,但我举了一个例子来帮助任何想回答的人。

17
如何处理评论中的重言式?[关闭]
有时,我遇到的情况是我正在编写的部分代码是(或似乎是)不言而喻的,其名称基本上会作为注释重复: class Example { /// <summary> /// The location of the update. /// </summary> public Uri UpdateLocation { get; set; }; } (C#示例,但请将该问题与语言无关)。 这样的评论是没有用的。我究竟做错了什么?是错误的名称选择吗?我怎样才能更好地评论这样的部分?我应该跳过诸如此类的评论吗?

9
类的方法应该调用自己的getter和setter吗?
在我工作的地方,我看到很多班级都做了这样的事情: public class ClassThatCallsItsOwnGettersAndSetters { private String field; public String getField() { return field; } public void setField(String field) { this.field = field; } public void methodWithLogic() { setField("value"); //do stuff String localField = getField(); //do stuff with "localField" } } 如果我是从头开始写的,那我应该写成methodWithLogic()这样的: public class ClassThatUsesItsOwnFields { private String field; public …

11
如何避免级联重构?
我有一个项目。在此项目中,我希望对其进行重构以添加功能,并且对项目进行重构以添加功能。 问题是,当我完成后,原来我需要做一个小的接口更改以适应它。所以我做了改变。然后,就新类而言,无法使用其当前接口来实现消费类,因此它也需要一个新接口。现在已经三个月了,我不得不解决了几乎不相关的无数问题,而且我正在寻找解决从现在开始经过一年规划的问题,或者只是因为困难而列为无法解决的问题,然后再进行编译再次。 将来如何避免这种级联重构?这仅仅是我以前的课程互相依赖的一种征兆吗? 简要编辑:在这种情况下,重构就是功能,因为重构增加了特定代码的可扩展性并减少了一些耦合。这意味着外部开发人员可以做更多的事情,而这正是我想要提供的功能。因此,原始重构本身不应该是功能上的更改。 我五天前承诺的更大修改: 在开始重构之前,我有一个带有接口的系统,但是在实现中,我只是简单地dynamic_cast通过了所有可能的实现。显然,这意味着您不能一方面从接口继承,其次,对于没有实现访问权即可实现此接口的任何人,这都是不可能的。因此,我决定要解决此问题并开放供公众使用的界面,以便任何人都可以实施,而实施该界面是整个合同所必需的-显然是一项改进。 当我发现并用火杀死所有地方时,我发现一个地方被证明是一个特殊的问题。它取决于所有各种派生类的实现细节以及已经实现但在其他地方更好的重复功能。它可以代替公共接口来实现,而可以重新使用该功能的现有实现。我发现它需要特定的上下文才能正常运行。粗略地说,调用先前的实现看起来像 for(auto&& a : as) { f(a); } 但是,要获得此上下文,我需要将其更改为更类似的内容 std::vector<Context> contexts; for(auto&& a : as) contexts.push_back(g(a)); do_thing_now_we_have_contexts(); for(auto&& con : contexts) f(con); 这意味着对于以前曾经是其中一部分的所有操作f,其中一些操作需要成为g无需上下文的新功能的一部分,而其中某些操作则需要由现在延迟的一部分组成f。但是,并非所有方法都f调用需要或需要此上下文-其中一些需要通过单独的方式获得的独特上下文。因此,对于f最终调用的所有内容(大致来说,几乎所有内容),我必须确定他们需要的上下文(如果有的话),应该从哪里获取以及如何将它们从旧f分为新f与新g。 这就是我最终所处位置的方式。我一直坚持下去的唯一原因是因为无论如何我都需要这种重构。

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.