软件工程

针对在系统开发生命周期中工作的专业人士,学者和学生的问答

4
从概念上讲,人们如何制定游戏的规则/约束(不是图形/物理)引擎
我想制作一个类似于自己选择冒险书籍的简单游戏。向玩家显示一个叙述文字,并从一系列可能性中选择其动作。反过来,这导致了新的叙述性文本无穷大。唯一要注意的是,根据先前的某些决定,可能性列表可能会有所不同。 乍一看,这听起来像是if-else语句的负载,因此暗示规则引擎将就位。但是,对我来说,这听起来也像是一台有限状态机。 我打算用Java或Groovy编写。目前,我对概念性问题更感兴趣,即应该如何在广义上进行操作(无论如何,人们如何实施国际象棋或纸牌游戏?),但也欢迎在特定库中提供一些建议。 显然,标题中的“游戏引擎”不是指碰撞检测或其他物理/图形力学,而是决定玩家给出的情况及其当前状态的选择的逻辑。

6
面向对象设计中的松耦合
我正在尝试学习GRASP,我发现了有关低耦合的解释(在第3页上),当我发现这一点时,我感到非常惊讶: 考虑addTrack一个Album类的方法,两种可能的方法是: addTrack( Track t ) 和 addTrack( int no, String title, double duration ) 哪种方法可以减少耦合?第二个则需要,因为使用Album类的类不必知道Track类。通常,方法的参数应使用基本类型(int,char ...)和java。*包中的类。 我倾向于不同意这一点。我相信addTrack(Track t)胜于addTrack(int no, String title, double duration)各种原因: 最好总是使用尽可能少的参数的方法(根据Bob叔叔的“清洁代码”,最好是无或一个,在某些情况下为2,在特殊情况下为3;超过3的需求需要重构-这些当然是建议,而不是冬青规则) 。 如果addTrack是接口的一种方法,并且要求a Track应该具有更多的信息(例如年份或类型),则需要更改接口,以便该方法应支持另一个参数。 封装破裂;如果addTrack在接口中,则它不应该知道的内部Track。 实际上,它在第二种方式中与许多参数耦合在一起。假设no参数需要被改变,从int到long,因为有超过MAX_INT轨道(或无论何种原因); 则Track必须同时更改和方法,而如果addTrack(Track track)仅更改方法,则需要Track更改。 这四个参数实际上是相互关联的,其中一些是其他因素的结果。 哪种方法更好?

1
是否有理由等到第三规则中的第三次?
我刚刚在维基百科上看到了文章“ 三法则 ” 第三规则是代码重构的经验法则,用于确定何时应将新代码替换为新过程。它指出该代码只能复制一次,但是当同一代码使用3次时,应将其提取到新过程中。该规则由Martin Fowler在“重构”中引入,并归因于Don Roberts。 我知道这只是一个经验法则,但是为什么建议仅在第二次重复之后才进行重构?编写第一个副本时,重构有什么不利之处吗?

6
与“主要”功能待办事项并行的“一口大小”任务的待办事项?
在高度孤立的“孤狼”开发部门结构中工作了两年多之后,我们采用了敏捷SCRUM。大。我喜欢敏捷;作为一名开发人员,它可以让您专注,忙碌和高效,而无数个利益相关者将项目逐个推销,而他们的期望已于昨天完成。 但是,与我们当前的“模型”相比,转向SCRUM有一个方面,我认为Development以外的人不会丝毫喜欢。这就是他们目前的能力,可以让我们在“等待时”进行一些小的更改。我们开发的很大一部分仅用于内部消费,而且我们几乎都位于同一栋大楼中。因此,多年来,部门负责人或其他部门的经理来找特定应用程序的“代码库所有者”并索要一些小东西(有时不是那么小,但是我们很乐意不承担这三点,周项目基于这些“偷渡者”)。甚至我们的老板有时也会以此方式转达给他的事情。很多时候,如果我们当时正在使用有问题的代码库,我们可以简单地弹出源文件, 使用基本的敏捷SCRUM方法,这些调整将被记录为缺陷(我们不满足先前使用的故事中指定的要求)或新的小故事(我们满足所有陈述的要求,但这些要求不完整,模糊或不正确) ,或者在用户看到新功能后在交付后进行了更改)。无论哪种方式,绝大多数将是一个三分球最多如果不是零和相对较低的优先级(该系统是在其当前状态下使用,但它是如此酷多了,如果......),这使得它们不太可能自上而下地处理积压工作时进入冲刺。 在开发人员会议上提出的这种可能性是其他部门积极反对我们的敏捷过程的根源,他们认为这比我们当前根据要求进行细微调整的能力“敏捷”程度要小。IMO是一个有效的关注点。采购订单背后的利益相关者并不总是就最重要的事情达成共识,因为他们的观点并不完全相同,但是通常只有管理者才能做出最终决定,因此他们的偏见是显示在产品积压中。 然后提出了一个解决方案,该解决方案暂时称为“糖果罐”(另一个抛出的术语是“肉汁船”)。各个部门的“小家伙”要求进行的细微调整(不是现有故事中的缺陷),通过团队内部的共识或鼓掌估计,这些细微调整需要不到开发人员一天的一半,而最终用户认为,对用户体验的即时,重要,积极的影响将与主要待办事项并行列出。它们将被识别为“故事”,但将与“大”故事的主要待办事项隔离开来,但要优先考虑。如果在sprint正常进行期间的任何时间,我们碰巧在系统区域中可以进行这些调整之一的工作,使微调变得微不足道,我们可以将微调带入sprint并在更大的故事中对其进行编码。这样做不得危害更大故事的完成或任何其他承诺的工作。PO也可以访问此列表,如果他们正在处理即将到来的用户故事,涉及涉及该调整的基本功能,则可以将其作为故事的要求折叠起来,然后我们将满足该要求。其他。人们认为,这将使调整的生效时间提早。 这在ScrumMaster培训“ uh-uh”中触发了我们当中的反应。有一个积压。两次积压引入了以下问题:哪个#1项实际上是最重要的,哪个列表的项决定了真实的速度,以及一个故事实际所属的两个积压中的哪个(大小/复杂性的任何划分都会使某些情况相对下降任意一侧或另一侧)。我们说:“让这个过程起作用”;如果更改对最终用户确实很重要,那么他们将发出足够的声音让部门负责人做出时间/金钱的决定,并且将被积压在开发团队的意识中。 我以为我要提一个问题:您认为,平行列出的“一口大小”的故事是否对使小而有用的,但最终是低优先级的更改更快地做出有价值的决定,或者总体而言是一个更好的决定?将它们折叠成主要待办事项,并让基本过程控制它们是否包含在冲刺中?

10
为什么我们需要“回调函数”?
我正在读书programming in Lua。它说 在许多情况下,封闭提供了一种有价值的工具。如我们所见,它们可用作排序等高阶函数的参数。闭包对于构建其他功能的功能也很有价值,例如我们的newCounter示例;这种机制允许Lua程序结合功能世界中的复杂编程技术。闭包对于回调函数也很有用。当您在传统的GUI工具箱中创建按钮时,就会出现一个典型的示例。每个按钮都有一个回调函数,当用户按下该按钮时会被调用。您希望不同的按钮在按下时会做一些略有不同的事情。例如,一个数字计算器需要十个类似的按钮,每个数字一个。您可以使用以下功能创建每个: function digitButton (digit) return Button{label = tostring(digit), action = function () add_to_display(digit) end} end 看来,如果调用digitButton,它将返回action(将创建一个闭包),因此,我可以访问digit传递给digitButton。 我的问题是: Why we need call back functions? what situations can I apply this to? 作者说: 在此示例中,我们假定Button是创建新按钮的工具包函数。label是按钮标签;而action是按下按钮时要调用的回调闭包。在digitButton完成其任务之后以及在局部变量digit超出作用域之后,可以很长一段时间调用该回调,但是仍然可以访问此变量。 根据作者,我认为类似的例子是这样的: function Button(t) -- maybe you should set the button here return t.action -- so …

1
如何对REST Web服务进行单元测试?
我是单元测试的新手,我有一个REST Web方法,它仅调用DB并填充DTO。伪代码是 public object GetCustomer(int id) { CustomerDTO objCust = //get from DB return objCust; } 我的疑问是如何编写针对这些方法的测试以及要包括的测试类型(集成/单元)。对于单元测试,是否需要命中数据库。如果是这样,并且我传递了一个客户ID并执行了一些断言,则数据可能会更改,最终导致失败。 我想我在这里缺少了解这些概念的内容。

6
HTTP会话或数据库方法
我对应该采取的方法感到有些困惑,正在研究购物车的设计,我需要将购物车存储在会话中或数据库中,但不确定哪种方法是最佳方法。 用户未登录并将产品添加到购物车(匿名用户) 用户已登录并将产品添加到购物车。 第一种情况对我来说更令人困惑,因为在许多情况下,用户只是访问网上商店并在没有登录的情况下添加产品,很可能他可能不会进行结帐流程。 但是我们仍然需要为此用户创建一个购物车,为了创建和保存购物车,我有两个选择。 当用户添加产品时,请在数据库中创建一个购物车并将该购物车与该用户相关联,当他登录时将其移动到登录用户。 当用户登录数据库中的创建购物车并将该登录购物车的用户与用户相关联时,创建购物车,向其中添加产品并将其保存到会话中。 我知道无论是数据库驱动的Cart系统还是基于Session的方面都可能有积极的方面也有消极的方面,但是我不确定哪一个是考虑以下几点的最佳方法 可扩展性 灵活性 可扩展性 应用程序应注意速度 寻找有关此方面的信息以决定路径。

7
生成随机数学表达式
我脑子里到处都是这个想法,以生成和评估随机数学表达式。因此,我决定先尝试一下,然后详细说明一下算法,然后再对其进行编码以对其进行测试。 例: 以下是一些我想随机生成的示例表达式: 4 + 2 [easy] 3 * 6 - 7 + 2 [medium] 6 * 2 + (5 - 3) * 3 - 8 [hard] (3 + 4) + 7 * 2 - 1 - 9 [hard] 5 - 2 + 4 * (8 - (5 + 1)) …
16 algorithms 

6
(过度)使用反射是个坏习惯吗?
如果大大减少了样板代码的数量,使用反射是否是一种好习惯? 基本上,在性能和一方面的可读性与另一方面的抽象/自动化/简化样板代码之间要进行权衡。 编辑:这是推荐使用反射的示例。 举一个例子,假设有一个抽象类Base,其具有10个字段和具有3个亚类SubclassA,SubclassB并且SubclassC每个具有10个不同的字段; 它们都是简单的豆子。问题是您有两个Base类型引用,并且想要查看它们的对应对象是否属于相同(子)类型并且相等。 作为解决方案,有一个原始解决方案,在该解决方案中,您首先要检查类型是否相等,然后检查所有字段,或者可以使用反射并动态查看它们是否属于同一类型,并遍历以“ get”开头的所有方法(约定超出配置),请同时在两个对象上调用它们,并在结果上调用equals。 boolean compare(Base base1, Base, base2) { if (base1 instanceof SubclassA && base2 instanceof SubclassA) { SubclassA subclassA1 = (SubclassA) base1; SubclassA subclassA2 = (SubclassA) base2; compare(subclassA1, subclassA2); } else if (base1 instanceof SubclassB && base2 instanceof SubclassB) { //the same } //boilerplate } …

2
何时在RESTful API中使用嵌套资源
我有两个资源:用户和链接。 用户可以具有几个与之关联的链接。我已经设计了RESTful API,以便您可以通过以下URI访问与用户关联的链接: /users/:id/links 但是,我总是需要一个仅用于链接的URI –有时我可能想要所有链接,无论用户是谁。 为此,我有: /links 听起来还好吗?有两个链接的URI吗? 我想知道是否应该使用URI来访问用户的链接,例如: /links/user/:id 要么 /links/?user=:id 这样,我只有一个链接资源。
16 api  rest  api-design 

4
工作流程:在Git中使用无锁定的二进制文档格式(从Subversion移出)
我们是一家软件咨询公司,为不同客户提供大量项目。传统上我们使用Subversion,但目前正在考虑迁移到Git。 我们生成的文档中有很大一部分与客户共享(需求,全局设计,测试规范等),我们使用MS Office生成这些文档。在Subversion中,我们可以使用其“锁定”功能来确保没有人同时编辑同一文档。在Git中,您无法执行此操作,因为git具有分布式特性,因此它没有锁。 锁实际上只是一种通信机制,但它是一种非常有效的机制。 当前,我们的代码和面向客户的文档通常位于不同svn存储库的不同子文件夹中。转到git时,您会建议我们做什么?我看到了一组选项: 我们将svn存储库移至git 1-on-1。我们不使用Office文件上的锁,而是执行git人们建议的操作,并以某种方式尝试更改工作流以对其进行修复。这可以在任何文档编辑的分支中进行,然后将其合并到审阅中。这种方法突破了例如包含项目管理信息的Excel工作表;他们很容易被团队成员编辑(我们鼓励这样做),但不受任何正式审查程序的约束 我们将git用于代码,将svn用于文档和项目管理。这样做的缺点是,某些更多具有设计意义的文档不会“靠近”其指定的代码,从而增加了人们忘记更新它们的机会。此外,每个人都必须使用和理解两组工具。就是说,对于非面向客户的设计文档来说,这可能是转向基于文本的文档工具(胶乳,降价,HTML等)的绝佳机会。 与1类似,但我们修改了一个git lock命令,该命令执行svn lock对我们所做的事情(适当地切换了只读标志并通过某种方式与服务器同步)。 我不赞成在DVCS中锁不起作用的说法,因为系统甚至在您完全脱机时也可以工作。SVN锁也可以被覆盖。他们是一种沟通机制。没有某种类型的网络连接,您将无法使计算机进行大量通信。 我们不能成为唯一一个对svn lock我们的工作流程适应性非常满意的商店,对吗? 有什么想法或提示吗? 我找到了/programming/119444/locking-binary-files-using-git-version-control-system,但是讨论的内容是技术性的;我正在寻找解决或避免两个团队成员同时编辑同一二进制文件的实际问题的方法。
16 git  svn  dvcs  excel  word 

4
适应(Python)语言更改的策略
编写仍将运行数年的代码 编程语言会改变。图书馆变化。5、10甚至20年以前的某些代码可能仍会运行并产生预期的结果,而2年之后的某些代码可能会因语法错误而失败。这是部分不可避免的,因为语言会不断发展(至少大多数会这样做)。开发人员有责任维护其代码。但是有时候,稳定性是生产代码中的一个重要要求,并且代码应该只运行10年,而无需每年有人通过代码来适应语言变化。或者,我可能有一些小脚本,例如用于科学数据分析的脚本,在多年不接触它们之后我需要重新访问。例如,在气象部门,即使对于非速度必不可少的部分,也有许多可操作的Fortran代码,而代码稳定性是原因之一。一世' 我们听说过对不稳定的恐惧是他们反对迁移到Python的目的之一(当然,除了语言惯性之外,这还可能是新代码不依赖于旧代码)。当然,稳定代码的一种策略是冻结整个操作系统。但这并不总是可行的。 我以Python为例,但问题不仅限于Python。 有关Python兼容性问题的文档 对于Python,有几个文档概述了向后不兼容更改的策略。 PEP-5 根据PEP 5: 从Python过渡版本的发行到向后不兼容版本的发行,必须至少有一年的过渡期。用户将有至少一年的时间来测试他们的程序,并将其从使用已过时的结构迁移到替代结构。 我个人认为一年是很短的。这意味着我可能会编写一些代码,并且从现在起1.5年前它将不再运行。 PEP 291 PEP 291包含不完整的准则指南清单,应避免使用这些准则以保持向后兼容性。但是,它仅与Python 2.x有关。由于Python 2.7是2.x系列的最终版本,而Python 2.7仅是错误修复,因此该PEP现在仅具有历史意义。 PEP 387 向后不兼容的更改也有PEP 387。PEP 387是草案,不是官方政策。2009年6月,在Python-ideas邮件列表中对此进行了讨论。讨论的一部分重点在于开发人员如何编写可抵御语言更改的强大代码。一篇文章列出了一些关于不该做什么的建议: 随之而来的是,您可以推断出在大多数情况下可能是正确的几条规则:不要调用以开头的东西"_",不要猴子打补丁,不要对除您自己以外的类中的对象使用动态类替换,不要依赖于继承层次结构的深度(例如no ".__bases__[0].__bases__[0]"),请确保您的测试在运行时不会产生任何DeprecationWarnings,将属性添加到从其他库继承的类时,请注意潜在的命名空间冲突。我不认为所有这些东西都写在一个地方。 此外,还有一些关于“矿场”(可能会更改的新功能)和“冻结区域”(实际上已保证几乎售出的API不变)的观点。引用安托万·皮特鲁(Antoine Pitrou): 我认为应该对“冻结区域”进行积极的定义(明确的公共API和明确保证的行为),而不是进行消极的定义(明确的“雷区”)。否则,我们将忘记将一些重要的东西放进雷区,并在以后需要以向后不兼容的方式更改这些东西时被咬住。 这个线程似乎没有任何结论,但是它非常接近我要寻找的核心。该线程已使用了将近四年,因此情况可能已更改或改善。什么样的代码可能会生存,而哪种代码更脆弱? 移植指南 除了上面概述的文档之外,每个Python版本还附带一个移植指南:移植到Python 3.2,移植到Python 3.3等。 有用的兼容性 PEP 3151向我介绍了有用的兼容性的概念。用我自己的话来说,可以归结为这样一个想法,即只有精心编写代码,语言开发人员才需要小心维护兼容性。它并没有真正定义有用的兼容性,但是我认为它与我在上面的PEP 387讨论中引用的想法相似。 从程序员的角度 作为一名程序员,我知道Python将来会发生变化,人们(尤其是我自己)将在几年后尝试使用一个,两个或三个次要版本的Python版本运行我的代码。并非所有的东西都兼容,实际上,很容易提出会失败的代码(我曾经遇到过说明的代码if sys.version[:3] != '2.3': print 'Wrong version, exiting')。我正在寻找一组有关如何执行和 不 执行哪些操作的准则,以增加我的代码将来仍可不变运行的机会。 有没有这样的指导方针?如何编写将来仍会运行的Python代码? 我的问题既涉及Python的核心,其标准库,也常用附加库,特别是numpy,scipy,matplotlib。 …
16 python 

2
这些SQL概念适用于初学者,中级或高级开发人员吗?[关闭]
关闭。这个问题是题外话。它当前不接受答案。 想改善这个问题吗? 更新问题,使它成为软件工程堆栈交换的主题。 4年前关闭。 我最近一直在学习SQL,并在MySQL / Postgres和Oracle DB上进行练习。我还在网络上搜索数据库的“路线图”研究,但不幸的是找不到。 我想了解特定数据库概念在何处以及为何从初学者到中级和高级的规模。我大部分时间都在考虑关系数据库。 请说明在初学者->中级->高级过程中如何布置以下所列技能,以使开发人员应该了解这些技能的水平: Where子句 更新语法 加入 修改和创建语句 临时表 游标 指标 外键 约束条件 交易次数 子查询 枢轴 汇总功能 剖析 OLAP和OLTP 扳机 执行计划 执行提示 绩效柜台 正常化

3
表示REST URI中的动作(动词)
我要为客户文件执行打印操作。我还需要执行其他标准操作,例如添加,更新,删除。因此,我有以下内容: 对于创建新客户:URI = / customer / {id},键入= POST,方法名= CreateCustomer() 要更新:URI:/ customer / {id},类型= PUT,方法= UpdateCstomer() 对于删除客户:URI = / customer / {id},键入= DELETE,方法名= DeleteCustomer() 对于视图:URI:/ customer / {id},键入= GET,方法= GetCustomer() 现在,如果需要为该客户打印文档,则需要打印功能。我的URI可能看起来像这样:/ customer / {id},类型= POST,方法= PrintCustomer()。但是我已经将URI和POST类型用于CreateCustomer。我希望URI看起来像这样:/ customer / Print / {id},键入= POST,方法= PrintCustomer()。 但是我的URI中不能包含“ Print”动词。最好的方法是什么?我考虑将/ customer / document / {id}作为URI ...,但是我将遇到相同的问题。我将在“文档”上进行CRUD操作。因此,我再次用尽了用于“打印”的内容。请指教。
16 rest 

3
敏捷是RAD的变体吗?
维基百科说敏捷是一种“ RAD”,我猜是不正确的。据我所知,敏捷开发是因为RAD本身在90年代并没有那么成功(对于变更而言过于僵化)。还是我错了? (注:显然在Wikipedia上,有关敏捷软件开发的文章有所改进,只是将RAD列为敏捷的前身,而不是超集)。 本书来自Radical Project Management(Thomsett) “ ..新的开发风尚,例如RAD,敏捷,面向对象...” CISA认证信息系统审核员: ..意识到两个替代软件的开发。方法:敏捷和快速的应用程序开发 软件的敏捷管理: 敏捷方法主要源自RAD的轻量级方法。 软件评估最佳做法: SW的主要方法。开发。可以概括如下: 1.瀑布.. 4. RAD 5.敏捷 这个问题的重点是: 是RAD的敏捷类型还是独立的开发方法?

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.