软件工程

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

5
在Java应用程序中引发运行时异常
我是承包商,以技术负责人的身份为我的客户设计企业Java应用程序。该应用程序将由最终用户使用,当我们离开时,将有一个支持团队为该应用程序提供支持。 与我一起工作的其他技术负责人给人的印象是异常处理会使代码变脏。系统应仅从服务层引发检查的异常,而其余代码应从所有其他层引发运行时异常,因此无需处理未检查的异常。 在业务应用程序中抛出未经检查的异常有什么需要? 根据我过去有关运行时异常的经验: 1)未经检查的异常使代码不可预测,因为它们甚至在Javadoc中也不会显示。 2)在业务应用程序中抛出未经检查的异常是没有意义的,因为当您将其抛出并直接出现在用户脸上时,您如何向用户解释?我已经看过足够多的Web应用程序,500 -Internal Error. Contact Administrator它对最终用户或管理该应用程序的支持团队没有任何意义。 3)引发运行时异常会强制引发异常的类的用户遍历源代码以进行调试,并查看引发异常的原因。只有在很好地记录了运行时异常的Javadoc的情况下,才可以避免这种情况,而我发现这种情况永远不会发生。



8
将所有枚举包含在一个文件中并在多个类中使用它是一种不好的做法吗?
我是一个有抱负的游戏开发人员,我偶尔从事独立游戏的工作,有一段时间我一开始似乎做不好,但是我真的想从这里的一些经验丰富的程序员那里得到答案。 假设我有一个名为的文件enumList.h,其中声明了我想在游戏中使用的所有枚举: // enumList.h enum materials_t { WOOD, STONE, ETC }; enum entity_t { PLAYER, MONSTER }; enum map_t { 2D, 3D }; // and so on. // Tile.h #include "enumList.h" #include <vector> class tile { // stuff }; 主要思想是,我在1个文件中声明游戏中的所有枚举,然后在需要使用某个枚举时将其导入,而不是在需要使用的文件中声明该枚举。我这样做是因为它使事情变得干净,我可以在一个地方访问每个枚举,而不必只打开页面来访问一个枚举。 这是不好的做法吗?它会以任何方式影响性能吗?

2
为什么错误代码无效?
我经常在C代码中看到返回的错误代码,例如return -EINVAL而不是return EINVAL。为什么要使用否定?
12 c 

3
在ORM层上创建一个抽象层
我相信,如果您的存储库使用的是ORM,那么它已经足够从数据库中提取出来了。 但是,在我现在工作的地方,有人认为我们应该有一个抽象ORM的层,以防我们以后要更改ORM。 创建一个可以在许多ORM上使用的层真的必要吗? 编辑 只是为了提供更多细节: 我们有与AutoMapper映射的POCO类和实体类。实体类由存储库层使用。然后,存储库层使用附加的抽象层与Entity Framework进行通信。 业务层决不能直接访问实体框架。即使在ORM上没有附加的抽象层,这一层也需要使用使用存储层的服务层。在这两种情况下,业务层都与ORM完全分开。 主要论据是将来能够更改ORM。因为对我来说,它确实是本地化的,所以它已经很好地分离了,我不明白为什么要使用一个附加的抽象层才能具有“质量”代码。
12 database  orm 

7
重构和开放/封闭原则
我最近正在阅读一个有关干净代码开发的网站(我不在此处放置链接,因为它不是英语)。 本网站宣传的原则之一是开放式封闭原则:每个软件组件都应开放以进行扩展,而封闭则可以进行修改。例如,当我们实现并测试了一个类时,我们仅应对其进行修改以修复错误或添加新功能(例如,不影响现有方法的新方法)。现有功能和实现不应更改。 我通常通过定义接口I和相应的实现类来应用此原理A。当类A变得稳定(实现并经过测试)后,我通常不会对其进行过多修改(可能根本没有修改),即 如果新的要求到达需要的代码大的变化(如性能,还是一个全新的接口的实现),我写了一个新的实现B,并使用保持A,只要B还没有成熟。当B成熟时,所需要做的就是更改I实例化方式。 如果新的要求也建议更改接口,那么我将定义一个新的接口I'和一个新的实现A'。所以I,A被冻结并保持实施生产系统,只要I'和A'不够稳定,以取代他们。 因此,鉴于这些观察,令我感到惊讶的是该网页随后建议使用复杂的重构,“……因为不可能直接以其最终形式编写代码。” 在执行“开放/封闭原则”与建议使用复杂重构作为最佳实践之间是否存在矛盾/冲突?还是这里的想法是,在开发一个类的过程中可以使用复杂的重构A,但是当成功测试了该类后,应该冻结它吗?

9
复制并粘贴测试代码:这有多糟糕?
我目前的工作主要是为我们正在处理的各种应用程序编写GUI测试代码。但是,我发现我倾向于在测试中复制和粘贴很多代码。原因是我正在测试的区域趋于足够相似以至于需要重复,但还不够相似以至于无法将代码封装到方法或对象中。我发现,当我尝试更广泛地使用类或方法时,测试变得更加笨重,有时甚至一开始就很难编写。 取而代之的是,我通常从一个部分复制大量测试代码并将其粘贴到另一部分,然后进行我需要的任何细微更改。我不使用更结构化的编码方式,例如使用更多的OO原理或函数。 其他编码人员在编写测试代码时有这种感觉吗?显然,我想遵循DRY和YAGNI原则,但是我发现测试代码(无论如何都用于GUI测试的自动测试代码)会使这些原则难以遵循。还是我只需要更多的编码实践和更好的整体服务系统? 编辑:我正在使用的工具是SilkTest,这是一种称为4Test的专有语言。同样,这些测试主要针对Windows桌面应用程序,但是我也使用此设置对Web应用程序进行了测试。

2
可以在较旧的C ++编译器中链接已编译的C ++ 11库(lib,dll等)吗?
旧的C ++编译器(例如VS2008和gcc3.4)可以与用C ++ 11编写的外部库链接吗? 我的想法是,C ++ 11 .lib文件在此阶段仅是字节代码,并且只要它可以解析和可调用,就不应打扰旧的编译器如何生成它。 我正在开发一个小型库,其API仍应支持C ++ 03用户。因此,展望未来,我想知道是否可以使用诸如此类的有用功能来实现我的库std::unique_ptr,还是我必须坚持使用boost::?
12 c++  c++11 

2
某些NOP代码是否与其他代码不同?
我对此很好奇,可以说我有: 00000000001 90 nop 00000000002 90 nop 00000000003 90 nop 它执行的方式与此完全一样吗? 00000000001 0F1F00 nop dword [ds:rax] 与第一个例子相比,第二个例子会产生什么影响?
12 assembly 

8
如何使开发人员及时进行代码审查
我工作的公司要求所有代码在提交之前都要经过其他开发人员的审查。我们团队的成员经常感到沮丧,因为其他开发人员太忙于编写代码以致无法进行审查,尤其是如果审查时间很长的话。您如何激励其他开发人员及时进行代码审查? (我们使用git-svn,因此我们可以在等待审查的同时继续编码。但是,当我不得不等待很长时间才能提交代码时,我仍然感到沮丧。)

2
CQRS +事件源:(是否正确)命令通常是点对点传递的,而域事件是通过pub / sub传递的?
我基本上是想围绕CQRS的概念和相关概念。 尽管CQRS不一定包含消息传递和事件源,但它似乎是一个很好的组合(从结合了这些概念的许多示例/博客中可以看出) 给定一个用于某种情况的状态更改的用例(例如,更新有关SO的问题),您是否认为以下流程是正确的(如最佳实践中那样)? 系统发出一个汇总的UpdateQuestionCommand,可以将其分成几个较小的命令:以Question Aggregate Root为目标的UpdateQuestion和以User Aggregate Root为目标的UpdateUserAction(对点进行计数)。这些是使用点对点消息传递异步发送的。 聚合根起作用,如果一切顺利,则分别引发事件QuestionUpdated和UserActionUpdated,它们包含外包给事件存储的状态。要保留yadayada,只是为了完整起见,此处并不是重点。 这些事件也被放在发布/订阅队列中进行广播。任何订阅者(其中可能有一个或多个创建阅读视图的投影仪)都可以自由订阅这些事件。 一个普遍的问题:最佳实践是命令之间进行点对点通信(即:接收方已知),而广播事件(即:接收方未知)吗? 假设以上所述,允许通过pub / sub而不是点对点广播命令的优点/缺点是什么? 例如:在使用Saga广播广播Commands时可能会出现问题,因为Saga在某个聚合根之一出现故障的情况下需要扮演的调解角色受到了阻碍,因为saga不知道哪个聚合根开始参与。 另一方面,我看到允许广播命令时的优势(灵活性)。

2
Unicode字符串的高效Trie实现
我一直在寻找有效的String trie实现。通常,我发现这样的代码: Java中的引用实现(每个维基百科) 我不喜欢这些实现主要有两个原因: 它们仅支持256个ASCII字符。我需要介绍西里尔字母。 它们的内存效率极低。 每个节点包含256个引用的数组,在Java的64位计算机上为4096字节。这些节点中的每个节点最多可以具有256个子节点,每个子节点具有4096字节的引用。因此,每个ASCII 2字符串的完整Trie要求超过1MB。三个字符串?256MB仅用于节点中的阵列。等等。 当然,我不打算在Trie中使用全部1600万个三个字符串,因此浪费了很多空间。这些数组中的大多数只是空引用,因为它们的容量远远超过了插入键的实际数量。而且,如果我添加unicode,数组会更大(char具有64k值,而不是Java中的256)。 有没有希望对字符串进行有效的尝试?我考虑了对这些类型的实现的一些改进: 除了使用引用数组之外,我还可以使用原始整数类型的数组,该数组将对大小与实际节点数接近的节点的引用数组进行索引。 我可以将字符串分成4位部分,这将允许以更大的树为代价允许大小为16的节点数组。
12 unicode  trie 

1
在大型对象层次结构中使用访问者模式
语境 我一直在使用对象层次结构(一个表达式树)使用“伪”访问者模式(伪,因为它不使用双调度): public interface MyInterface { void Accept(SomeClass operationClass); } public class MyImpl : MyInterface { public void Accept(SomeClass operationClass) { operationClass.DoSomething(); operationClass.DoSomethingElse(); // ... and so on ... } } 由于MyInterface的实现数量很多(约50个或更多),而且我不需要添加额外的操作,因此该设计非常舒适。 每个实现都是唯一的(它是一个不同的表达式或运算符),而某些实现是组合的(即,将包含其他运算符/叶节点的运算符节点)。 遍历当前是通过在树的根节点上调用Accept操作来执行的,后者依次在其每个子节点上调用Accept,依次类推...依次类推... 但是现在是时候需要添加一个新操作了,例如漂亮的打印: public class MyImpl : MyInterface { // Property does not come from MyInterface public string …


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.