软件工程

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

11
为什么C ++具有“未定义的行为”(UB),而其他语言(如C#或Java)却没有?
这篇Stack Overflow帖子列出了C / C ++语言规范声明为“未定义行为”的情况的相当全面的列表。但是,我想了解为什么其他现代语言(例如C#或Java)没有“未定义行为”的概念。这是否意味着编译器设计者可以控制所有可能的方案(C#和Java)或不能控制(C和C ++)?

5
Python为什么不允许多行lambda?
有人可以解释BDFL选择使Python Lambdas单行的具体原因吗? 这很好: lambda x: x**x 这会导致错误: lambda x: x**x 我了解到,使lambda多行处理会以某种方式“干扰”正常的缩进规则,并且需要添加更多的例外,但这不值得吗? 以JavaScript为例。没有这些匿名功能,怎能生存?它们是必不可少的。难道Pythonista使用者不希望为了将每个多行函数都作为参数传递而不得不命名吗?
50 lambda  python 


4
为什么创建带有反射的通用setter和getter是一个坏主意?
前一段时间,我写了这个问题的答案,它关于如何避免每个可变变量都具有getter和setter方法。当时,我只有一种难以言表的直觉,认为这是一个坏主意,但OP明确要求这样做。我在这里搜索了这可能是个问题的原因,然后发现了这个问题,其答案似乎认为,除非绝对必要,否则使用反射是不好的做法。 那么,有人可以说出为什么应该避免反射的原因,特别是在通用getter和setter的情况下?
49 java  reflection 

7
切换到SOLID后管理和组织大量增加的课程?
在过去的几年中,我们一直在缓慢地转换为逐渐更好的书面代码,每次只需几个小步骤。我们终于开始切换到至少与SOLID类似的东西,但是我们还没有到那儿。自从进行切换以来,开发人员最大的抱怨之一就是他们无法忍受同行审查和遍历数十个文件,而以前的每个任务只需要开发人员触摸5-10个文件即可。 在开始进行转换之前,我们的体系结构非常类似于以下内容(已授予,但又增加了一个或两个数量级的文件): Solution - Business -- AccountLogic -- DocumentLogic -- UsersLogic - Entities (Database entities) - Models (Domain Models) - Repositories -- AccountRepo -- DocumentRepo -- UserRepo - ViewModels -- AccountViewModel -- DocumentViewModel -- UserViewModel - UI 从文件的角度来看,所有内容都非常线性且紧凑。显然有很多代码重复,紧密耦合和令人头疼的问题,但是,每个人都可以遍历并弄清楚。完全的新手,从来没有像以前那样打开过Visual Studio的人,就可以在几周内解决这个问题。缺乏整体文件的复杂性,对于新手开发人员和新员工来说,在不增加太多时间的情况下就开始进行贡献相对容易。但这几乎就是代码风格的任何好处都无法体现的地方。 我全心全意地支持我们为改善代码库所做的一切尝试,但是在这样的大规模范式转换中,从团队的其他成员那里得到一些回击是很普遍的。当前几个最大的症结是: 单元测试 班数 同行评审的复杂性 单元测试对于团队来说是一笔难以置信的辛苦卖点,因为他们所有人都认为这是浪费时间,并且他们能够比单个代码更快地整体测试代码。使用单元测试作为SOLID的认可在大多数情况下是徒劳的,并且在这一点上已经成为一个笑话。 上课人数可能是要克服的最大障碍。过去需要5-10个文件的任务现在可以占用70-100!尽管每个文件都有不同的用途,但文件的数量却是巨大的。团队的反应主要是吟和头部抓挠。以前,一项任务可能需要一个或两个存储库,一个或两个模型,一个逻辑层和一个控制器方法。 现在,要构建一个简单的文件保存应用程序,您需要一个类来检查文件是否已存在,一个类来编写元数据,一个类来进行抽象,DateTime.Now以便您可以投入时间进行单元测试,为每个包含逻辑的文件插入接口,包含每个类的单元测试,以及一个或多个文件以将所有内容添加到您的DI容器中。 对于中小型应用程序,SOLID非常容易出售。每个人都看到了可维护性的好处和便利。但是,他们只是没有看到SOLID在超大型应用程序中具有很好的价值主张。因此,我正在尝试寻找改善组织和管理的方法,以使我们度过不断增长的痛苦。 我以为基于最近完成的任务,可以更详细地说明文件量的示例。我被赋予一项任务,以在我们的一种较新的微服务中实现某些功能,以接收文件同步请求。收到请求后,服务将执行一系列查找和检查,最后将文档以及2个单独的数据库表保存到网络驱动器。 要将文档保存到网络驱动器,我需要一些特定的类: - …

6
为什么许多在C中返回结构的函数实际上返回结构的指针?
return与在函数的语句中返回整个结构相比,返回指向结构的指针有什么好处? 我说的是像fopen其他底层函数一样的函数,但是可能还有一些高层函数也返回指向结构的指针。 我相信这更多是一种设计选择,而不仅仅是编程问题,而且我很想知道更多关于这两种方法的优缺点。 我认为返回指向结构的指针的一个好处的原因之一是能够通过返回NULL指针更容易地判断函数是否失败。 我想返回一个完整的结构NULL会比较困难,或者效率较低。这是正当的理由吗?

2
与MVC相比,MVP有哪些改进?
我已经阅读了三天的有关Model-View-Controller(MVC)和Model-View-Presenter(MVP)模式的信息。有一个问题令我非常困扰。当已经有MVC时,为什么软件设计者会发明MVP? 他们遇到了什么问题,MVC无法解决(或解决得很差),但是MVP可以解决?MVP打算解决哪些问题? 我已经阅读了很多有关MVP的历史和解释,或者关于MVC和MVP之间差异的文章,但是没有一个对我的问题有明确的答案。 在我读过的一篇文章中,有人说: 现在进入Model View Presenter,这是对MVC模式应用于现代基于组件的图形用户界面时的不足之处的回应。在现代GUI系统中,GUI组件本身而不是某些中央控制器来处理诸如鼠标移动和点击之类的用户输入。 因此,我听不懂,但实际上可以以另一种方式使用,例如GUI组件不能自行处理用户输入吗?“单独处理”到底是什么意思?

7
具有相同成员但命名不同的两个结构,这是一个好主意吗?
我正在编写一个涉及极坐标和笛卡尔坐标的程序。 为每种类型的点创建两个不同的结构是否有意义,一个结构与X和Y成员,一个结构与R和Theta成员。 还是太多了,最好只有一个结构体,first并second作为成员。 我写的内容很简单,不会有太大变化。但是我很好奇从设计的角度来看哪个更好。 我认为第一种选择更好。似乎更具可读性,我将获得类型检查的好处。
49 design 

11
“易于推理”-这是什么意思?[关闭]
我听到过很多次其他开发人员使用该短语“宣传”某些模式或开发最佳做法的消息。在大多数情况下,当您谈论函数式编程的好处时,都会使用此短语。 短语“易于推理”按原样使用,没有任何解释或代码示例。因此,对我而言,它就像下一个“嗡嗡声”一词,更多“经验丰富”的开发人员在演讲中使用。 问题:您能否提供一些“不容易推理的”示例,以便将其与“不容易推理的”示例进行比较?

10
我们应该避免将自定义对象作为参数吗?
假设我有一个自定义对象Student: public class Student{ public int _id; public String name; public int age; public float score; } 还有一个窗口Window,用于显示学生的信息: public class Window{ public void showInfo(Student student); } 它看起来很正常,但是我发现Window很难单独测试,因为它需要一个真正的Student对象来调用该函数。因此,我尝试修改showInfo,使其不直接接受Student对象: public void showInfo(int _id, String name, int age, float score); 以便更轻松地单独测试Window: showInfo(123, "abc", 45, 6.7); 但是我发现修改后的版本还有另一个问题: 修改学生(例如:添加新属性)需要修改showInfo的方法签名 如果Student具有许多属性,则Student的方法签名将非常长。 因此,使用自定义对象作为参数或接受对象中的每个属性作为参数,哪个更可维护?

6
许多小请求与几个大请求(API设计)
我目前正在与一个组织一起从事以下项目: 客户端 -通过REST API从主服务器获取数据。 服务器 -通过第三方API向其他各种服务器请求数据 第三方API-无法控制的向服务器提供数据的服务(Reddit,Hackernews,Quora等) 出于争论的目的,假设客户端首先需要每个第三方API的项目列表。从该列表中,将选择一个项目,此时客户需要查看该项目的全部内容以及对该项目的响应(即评论)。我试图在三个选项之间做出选择: 点菜 用这种方法,我的服务器上将有3个单独的端点:一个用于获取项目列表,一个用于获取项目的主要内容,以及一个用于获取项目的响应。 优点:我从来没有发出比我需要更多的请求,请求应该很小,因此通常它们应该更快。 缺点:我必须提出很多要求。从列表中选择一个项目后,用户可能必须先等待才能看到主要内容,然后再等待更长的时间才能看到响应 服务器端缓存 在此请求中,我将对服务器进行一次调用以“获取”所有源的所有数据。然后,数据将被缓存在服务器上。然后,客户端将具有与以前相同的REST终结点,但是在两次调用之间不会有太多等待,因为我的服务器已经拥有了数据,只需要将其提供给客户端即可。 优点:仍然易于在客户端实现,但没有延迟问题 缺点:更多涉及服务器端,第一次调用可能要花很长时间。 客户端缓存 除了客户端只向服务器发出一个请求外,此方案与上一个相似:将所有数据提供给我。从这里开始,客户有责任保存数据并正确使用它们。 优点:易于服务器实施,在首次通话后非常快速 缺点:第一次调用将非常缓慢,客户端实现更为复杂 我不确定哪种方法是最好的,或者不确定是否缺少明显的解决方案。任何建议将不胜感激!

8
是否有理由在编程语言中使用底部类型?
底部类型是一种主要出现在数学类型理论中的构造。也称为空类型。它是没有值的类型,但是是所有类型的子类型。 如果函数的返回类型是底部类型,则表示它不返回。期。也许它永远循环,或者抛出异常。 在编程语言中使用这种奇怪的类型有什么意义?这种情况并不常见,但是它存在于某些环境中,例如Scala和Lisp。

3
C ++强类型typedef
我一直在尝试一种声明强类型typedef的方法,以在编译阶段捕获某些类的错误。通常,我会将int类型定义为几种类型的id,或者将矢量类型化为位置或速度: typedef int EntityID; typedef int ModelID; typedef Vector3 Position; typedef Vector3 Velocity; 这可以使代码的意图更加清晰,但是经过一整夜的编码之后,人们可能会犯一些愚蠢的错误,例如比较不同类型的id或在速度上增加位置。 EntityID eID; ModelID mID; if ( eID == mID ) // <- Compiler sees nothing wrong { /*bug*/ } Position p; Velocity v; Position newP = p + v; // bug, meant p + v*s but …
49 c++  c++11  type-safety 

5
为什么所有<algorithm>函数仅采用范围,而不采用容器?
中有许多有用的功能&lt;algorithm&gt;,但所有功能都对“序列”(一对迭代器)起作用。例如,如果我有一个容器并且喜欢std::accumulate在其上运行,则需要编写: std::vector&lt;int&gt; myContainer = ...; int sum = std::accumulate(myContainer.begin(), myContainer.end(), 0); 我打算做的是: int sum = std::accumulate(myContainer, 0); 在我看来,这更具可读性和清晰度。 现在我可以看到,在某些情况下,您可能只希望对容器的某些部分进行操作,因此选择传递范围绝对对您有用。但是至少以我的经验来看,这是一种罕见的特殊情况。我通常要对整个容器进行操作。 可以很容易地编写一个包装函数,它接受一个容器,并呼吁begin()和end()就可以了,但是这样的便利功能,不包含在标准库。 我想知道这种STL设计选择背后的原因。

6
Java检查的异常的解决方法
我非常感谢有关lambda和默认方法接口的Java 8新功能。但是,我仍然对检查的异常感到无聊。例如,如果我只想列出对象的所有可见字段,我想简单地写一下: Arrays.asList(p.getClass().getFields()).forEach( f -&gt; System.out.println(f.get(p)) ); 但是,由于该get方法可能会抛出一个与Consumer接口协定不同的已检查异常,所以我必须捕获该异常并编写以下代码: Arrays.asList(p.getClass().getFields()).forEach( f -&gt; { try { System.out.println(f.get(p)); } catch (IllegalArgumentException | IllegalAccessException ex) { throw new RuntimeException(ex); } } ); 但是,在大多数情况下,我只希望将异常作为a抛出,RuntimeException并让程序处理或不处理没有编译错误的异常。 因此,我想就我对有争议的异常进行检查的方法发表您的看法。为此,我创建了一个辅助接口ConsumerCheckException&lt;T&gt;和一个实用程序功能rethrow(根据Doval的评论进行了更新),如下所示: @FunctionalInterface public interface ConsumerCheckException&lt;T&gt;{ void accept(T elem) throws Exception; } public class Wrappers { public static &lt;T&gt; Consumer&lt;T&gt; rethrow(ConsumerCheckException&lt;T&gt; c) …

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.