软件工程

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

4
命名空间中的类数-代码气味?
我有一个C#库,该库由多个可执行文件使用。库中只有几个命名空间,我只是注意到其中一个命名空间中包含许多类。由于分类,我总是避免在单个名称空间中包含太多的类,并且因为在潜意识里,我认为具有更深层次的名称空间层次结构看起来“更漂亮”。 我的问题是:当一个命名空间具有许多类时,即使这些类彼此相关,是否有人将其视为“代码气味”?您是否会花大力气在允许子分类的类中找到细微差别?
11 c#  count  namespace 

5
如何重构现有的Web应用程序?
最近我一直在阅读和思考很多,得出的结论是,也许我应该重新考虑我的Web开发策略。我正在做大量的即时编程,在过去两年中,我一直在研究PHP Web应用程序,当一个小工具变成一个相当大的项目时,它可能已经开始了。但是我和我的前任有很多遗留代码,这些代码片段在当时可能很有意义,但是现在我在质疑所说代码的实际形式。而且,直到最近,诸如单元测试和测试驱动开发之类的东西才在我的范围之内。 那么您将如何重构Web应用程序?我应该寻找什么东西,以什么顺序排列?浏览器游戏与功能性网络应用程序又如何?那么方法上会有区别吗?


4
C ++迭代器,为什么没有迭代器继承的所有迭代器基类
我正在为考试而学习,但是我有一个问题很难解决。 为什么没有迭代器基类存在所有其他迭代器继承的东西? 我猜我的老师是从cpp参考“ http://prntscr.com/mgj542 ”中引用层次结构的,我们必须提供其他原因,而不是为什么? 我知道什么是迭代器(某种),并且它们用于在容器上工作。据我了解,由于底层数据结构可能不同,因此不同的容器具有不同的迭代器,例如,您可以随机访问数组,但不能访问链表,并且不同的容器需要不同的遍历它们的方式。 根据容器的不同,它们可能是专门的模板,对吗?
11 c++  iterator 

2
使用方括号作为数组元素的习惯是如何发展的?
许多编程语言都使用该语法a[i]来引用i数组,序列或向量的'th元素a-特别是C和Pascal(从1960年代末至1970年代初)。另一方面,某些较早的语言(例如Fortran(1950年代))不使用此约定。另外,我学习了一些数学,数学家使用方括号作为间隔,下标用于数组和矩阵的下标(如果将数组视为非负整数的函数,则使用正则括号)。 因此,我的问题是:用于数组下标的方括号在哪里/如何/在什么情况下发展?由谁开发? 注意:这个问题完全不是关于在C中使用大括号的问题。
11 history  array  syntax 

1
OOP ECS与纯ECS
首先,我知道这个问题与游戏开发主题相关,但是我决定在这里提出这个问题,因为它实际上归结为一个更一般的软件工程问题。 在过去的一个月中,我阅读了很多有关实体组件系统的信息,现在对这个概念相当满意。但是,似乎有一个方面似乎缺少明确的“定义”,并且不同的文章提出了根本不同的解决方案: 这是ECS是否应该破坏封装的问题。换句话说,其OOP风格的ECS(组件是具有状态和行为的对象,它们封装了特定于它们的数据)与纯ECS(组件是c样式的结构,仅具有公共数据,并且系统提供了功能)。 请注意,我正在开发框架/ API /引擎。因此,目标是无论使用它的人都可以轻松扩展它。这包括添加新类型的渲染或碰撞组件之类的东西。 OOP方法的问题 组件必须访问其他组件的数据。例如,渲染组件的draw方法必须访问变换组件的位置。这将在代码中创建依赖项。 组件可以是多态的,这进一步引入了一些复杂性。例如,可能有一个Sprite渲染组件,它会覆盖渲染组件的虚拟绘制方法。 纯方法的问题 由于必须在某个地方实现多态行为(例如,用于渲染),因此它只是外包给了系统。(例如,精灵渲染系统创建一个继承渲染节点的精灵渲染节点,并将其添加到渲染引擎中) 系统之间的通信可能很难避免。例如,碰撞系统可能需要根据任何具体的渲染组件计算出的边界框。这可以通过让他们通过数据进行通信来解决。但是,这会删除即时更新,因为渲染系统将更新边界框组件,然后碰撞系统将使用它。如果未定义调用系统更新功能的顺序,则可能导致问题。存在一个事件系统,该事件系统允许系统引发其他系统可以订阅其处理程序的事件。但是,这仅适用于告诉系统该怎么做,即无效函数。 还需要其他标志。以图块地图组件为例。它将具有大小,图块大小和索引列表字段。瓦片贴图系统将处理相应的顶点数组,并根据组件的数据分配纹理坐标。然而,每帧重新计算整个图块地图是昂贵的。因此,将需要一个列表来跟踪所有更改,然后在系统中对其进行更新。以OOP方式,这可以由图块地图组件封装。例如,SetTile()方法将在调用顶点数组时对其进行更新。 尽管我看到了纯方法的美妙之处,但我真的不明白与传统OOP相比它将带来什么样的具体好处。组件之间的依赖性仍然存在,尽管被系统隐藏了。同样,我将需要更多的类来实现相同的目标。在我看来,这似乎是一种过度设计的解决方案,但这从来都不是一件好事。 此外,我对性能的关注并不那么深,所以面向数据设计和现金遗漏的整个想法对我来说并不重要。我只想要一个好的架构^^ 尽管如此,我阅读的大多数文章和讨论都建议使用第二种方法。为什么? 动画 最后,我想问一个问题:如何在纯ECS中处理动画。目前,我已将动画定义为根据0到1之间的进度操纵实体的函子。动画组件具有一个动画列表,该列表包含一个动画列表。然后,在其更新功能中,它将当前激活的任何动画应用于实体。 注意: 我刚刚读了这篇文章实体组件系统体系结构对象是否按定义导向?可以比我更好地解释问题。尽管基本上是同一主题,但对于纯数据方法为何更好,仍然没有给出任何答案。

4
什么是黑匣子单元测试?
我最近完成了针对硕士课程的软件工程课程的期末考试,该考试中的一个问题如下: Unit Testing is considered: a. White-box Testing b. Black-box Testing c. Either 在我7年的软件开发经验中,单元测试始终采用白盒方法。测试人员在编写测试时始终对单元的实施有充分的了解。黑盒测试总是以集成,系统和验收测试的形式出现。 但是,对考试的正确答案(根据教授的说法)是单元测试可以是白盒测试或黑盒测试。 我已经进行了一些研究,似乎很多情况下都使用“黑盒单元测试”来描述一种先测试的方法,即在代码之前编写单元测试。但是我认为这仍是白盒测试。尽管实现尚不存在,但是编写测试的人通常都对如何实现源代码有一个很好的了解。 有人可以告诉我黑匣子单元测试的工作原理(如果确实如此),以及它与白匣子单元测试有何不同?

3
DDD-贫血域模型是反模式吗?我们应该使用富域模型吗?[关闭]
已关闭。这个问题是基于观点的。它当前不接受答案。 想改善这个问题吗?更新问题,以便通过编辑此帖子以事实和引用的形式回答。 2年前关闭。 Enes 和Fowler很久以前就批评了贫血症领域模型,因为它显然违反了面向对象的原理等。DDD社区显然与此声明保持一致。 但是,近年来,一直有不同意见的人声称它根本不是反模式,并且它是遵循SOLID原则的一个示例。 我已经使用Spring Framework工作了很多年。每个公司中的每个项目都始终使用服务于贫乏模型(JPA实体)的存储库,其中包含业务逻辑的服务层。此外,大多数样本,甚至包括Spring员工的官方样本,都展示了这种工作方式。 我的问题是:贫血领域模型是否仍被视为反模式?我们所有人都在做关于DDD的事情吗?您是否不认为拥有Rich Domain模型违反了SOLID原则?

3
在代码中使用抑制警告是一种好习惯吗?
我用@SuppressWarnings("unchecked")与@SuppressWarnings("null")大多上面的方法,让没有任何警告的代码编译,但我有我的怀疑。找到了这个Stackoverflow 问题。乔恩·斯基特(Jon Skeet)为此回答了一个有趣的答案。 据他介绍, 有时Java泛型只是不允许您做您想做的事情,您需要有效地告诉编译器在执行时所做的事情实际上是合法的。 但是,如果有机会引发异常该怎么办?那抑制警告不是一个坏主意吗?我是否应该知道可能出现问题的地方? 另外,如果其他人稍后修改了我的代码并添加了一些可疑的功能却又没有删除SuppressWarnings,该怎么办?如何避免和/或有其他替代方法? 我应该使用@SuppressWarnings("unchecked")和@SuppressWarnings("null")吗? 更新#1 对于未检查的类型强制转换,根据此答案(由@gnat在下面的注释中指出),有必要抑制这些警告。 许多必不可少的Java库从未进行过更新,以消除对不安全类型转换的需求。抑制这些警告是必要的,以便其他更重要的警告将被注意到并得到纠正。 在禁止其他警告的情况下,仍在灰色区域中。 更新#2 根据Oracle文档(以下一些答案也提到): 作为样式问题,程序员应始终在最有效嵌套的最深层元素上使用此注释。如果要在特定方法中禁止显示警告,则应注释该方法而不是其类。

1
在Javascript文件中声明module.exports的约定
是否应声明module.exports没有Javascript / Node.js模块文件的约定? 应该在文件的开头,例如: module.exports = Foo; function Foo() { this.bar = 'bar'; } Foo.prototype.getBar = function() { return this.bar; } 还是应该在文件末尾: function Foo() { this.bar = 'bar'; } Foo.prototype.getBar = function() { return this.bar; } module.exports = Foo; 我知道没有技术差异。第一个示例由于声明悬挂而完全有效。 所以我想知道是否存在某种最佳实践。

2
多租户或多实例?
我试图构建一个基于Web的SaaS解决方案,但遇到了不确定使用多租户或多实例的道路。我将尝试描述我要实现的目标,以及每种方法的优缺点(根据我的阅读,我的观点)。请提出您的建议,以防万一我错过了其他任何方法。 正如我提到的那样,我要构建的应用程序是一个SaaS解决方案,公司可以在其中创建帐户,每个帐户/公司都有自己的用户,客户,产品,服务等。每个用户;谁是公司员工;与一个帐户/公司相关的信息将只能访问其公司的客户,产品和服务。公司可以拥有无​​限数量的客户,产品和服务,因此每个公司都应该拥有自己的数据中心。 为此,我决定创建一个共享数据库(保存所有用户凭据以用于登录)和多个数据库共享架构(每个帐户/公司的数据库)。基本上,多租户。 然后有人建议使用多实例代替,每个公司将有自己的应用程序实例(即代码,库,数据库,框架等),与其他公司完全分开。这听起来更好,因为我不必在需要确保每个租户的用户只能访问其公司数据的额外层上打理。我认为值得一提的是,我依靠Docker来实现这种方法(我以前从未使用过),但是我认为它缺乏将来我将需要的功能(以后会更多)(至少我没有这样做)。一点点搜索就找不到它们)。 但是,每种方法都各有利弊,因此我无法决定采用哪种方法。这是一个列表,但由于我对它们都不了解,所以对我几乎一无所知,因此可能存在一些我不知道的问题,或者是针对我在网上找不到的问题的解决方案:[每种方法都有我跟着一个一个的比较的有序列表] 多租户: 共享的主机/硬件,共享的代码和多数据库。 这是容易扩展的代码并修复错误的功能(共享代码)。 在不更改代码的情况下,很难扩展硬件(可以使用云服务)或将单个租户的数据库移至另一个系统。 最重要的是,如前所述,我需要在系统中添加一个额外的层,以确保用户实际上属于他/她的公司,而不访问其他公司的信息。 多实例: 共享或不共享的主机/硬件,每个实例的代码以及每个实例的数据库。 这是很难扩展功能或修复的错误(我不知道是否有办法做到这一点在码头工人在那里你可以添加功能/特性,以一个实例或码头集装箱,并将其部署到其他人)。 这是更容易对整个实例移动到不同的主机/硬件。 作为实例,我不需要照顾该层,因为每个实例将拥有自己的数据库。 万一我想手动做任何事情(例如为每个租户手动创建一个实例),所有的优点和缺点都是多余的,这就是为什么我怀疑Docker解决方案的原因,除非有一种解决方法,这也许是主要的问题的原因。如果您能通过参考解决方案来回答问题,以及为什么您认为这种方法比其他方法更好,我将不胜感激。 如果有帮助(也许?),我们使用Laravel作为后端的主要框架(全部为RESTful)。

4
类复制模式?
我目前是我当前项目的独立开发人员。我从另一个离开公司的开发商那里继承了这个项目。它是C#中的模型视图控制器样式的Web应用程序。它使用实体框架进行对象关系映射。域模型中的类型有两组不同的类。一组用于与ORM进行交互,另一组用作MVC系统中的模型。例如,可能有两个类别,如下所示: public class Order{ int ID{get;set;} String Customer{get;set;} DateTime DeliveryDate{get;set;} String Description{get;set;} } 和 public class OrderModel{ String Customer{get;set;} DateTime DeliveryDate{get;set;} String Description{get;set;} public OrderModel( Order from){ this.Customer= from.Customer; // copy all the properties over individually } public Order ToOrder(){ Order result =new Order(); result.Customer = this.Customer; // copy all …

5
函数返回字符串,风格好吗?
在我的C程序中,我经常需要一种方法来对我的ADT进行字符串表示。即使我不需要以任何方式将字符串打印到屏幕上,使用这种调试方法也很简洁。因此,经常会出现这种功能。 char * mytype_to_string( const mytype_t *t ); 我实际上意识到我在这里有(至少)三个选项来处理返回字符串的内存。 备选方案1:将返回字符串存储在函数的静态char数组中。除了每次调用都会覆盖该字符串外,我不需要太多思考。在某些情况下这可能是个问题。 备选方案2:使用函数内部的malloc在堆上分配字符串。真的很整洁,因为我那时无需考虑缓冲区的大小或覆盖的问题。但是,我确实必须记得在完成操作后将字符串free(),然后还需要分配一个临时变量,以便可以释放。然后堆分配实际上比堆栈分配要慢得多,因此如果在循环中重复进行,则将成为瓶颈。 备选方案3:将指针传递到缓冲区,然后让调用方分配该缓冲区。喜欢: char * mytype_to_string( const mytype_t *mt, char *buf, size_t buflen ); 这给呼叫者带来了更多的努力。我还注意到,该替代方案在参数顺序方面为我提供了另一个选择。我应该首先讨论哪个论点?(实际上有六种可能性) 那么,我该选择哪个呢?为什么?C开发人员中是否存在某种不成文的标准?

2
使用字符串或int引用系统的Java部分之外的枚举更好吗?
我们在工作中讨论了Java中枚举的使用。 一位同事争辩说,在服务器端使用枚举时,每当需要时,我们都应该使用字符串来引用它(例如,当从JS向服务器发送数据或存储在数据库中时),认为这更加清楚了。对于开发人员来说也很困难,如果出现拼写错误,它将很快失败。 在这些情况下,我总是使用整数来标识枚举,因为它是不可变的标识符,并且不会出现大小写和拼写错误(即使开发人员错误地使用了值2而不是1,也不会很快失败)。 对这些参数非常分析,我会说使用字符串会更好,但是我对此有一种奇怪的感觉(好像这不是一个好方法)。 关于此讨论,是否有任何最佳实践可以指导我? 编辑:只要有可能,我们就使用枚举本身,因此我们所有的Java代码都使用枚举。“引用枚举”的意思是:在将数据从JavaScript交换到服务器或将数据存储在数据库中时,引用枚举中的值

1
在C ++中移动语义-局部变量的移动返回
我的理解是,在C ++ 11中,当您按值从函数返回局部变量时,允许编译器将该变量视为r值引用,并将其“移出”函数以返回它(如果当然不会发生RVO / NRVO)。 我的问题是,这不能破坏现有代码吗? 考虑以下代码: #include <iostream> #include <string> struct bar { bar(const std::string& str) : _str(str) {} bar(const bar&) = delete; bar(bar&& other) : _str(std::move(other._str)) {other._str = "Stolen";} void print() {std::cout << _str << std::endl;} std::string _str; }; struct foo { foo(bar& b) : _b(b) {} ~foo() …
11 c++  c++11 

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.