软件工程

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

6
我是否在这种体系结构上打破了面向对象的实践?
我有一个Web应用程序。我不认为这项技术很重要。该结构是一个N层应用程序,如左图所示。共3层。 UI(MVC模式),业务逻辑层(BLL)和数据访问层(DAL) 我的问题是我的BLL非常庞大,因为它具有通过应用程序事件调用的逻辑和路径。 通过应用程序的典型流程可能是: 在UI中触发的事件遍历BLL中的方法,执行逻辑(可能在BLL的多个部分中),最终执行DAL,返回到BLL(可能还有更多逻辑),然后向UI返回一些值。 此示例中的BLL非常繁忙,我正在考虑如何将其拆分。我也有自己不喜欢的逻辑和对象。 右边的版本是我的努力。 逻辑仍然是应用程序的UI和DAL之间的流动,但也有可能没有属性...只有方法(在这一层中的大多数类可能可能是静态的,因为他们不存储任何状态)。Poco层是存在具有属性的类的地方(例如Person类,其中会有名称,年龄,身高等)。这些与应用程序的流程无关,它们仅存储状态。 流可以是: 甚至从UI触发,并将一些数据传递到UI层控制器(MVC)。这将转换原始数据并将其转换为poco模型。然后将poco模型传递到逻辑层(即BLL),最后传递到命令查询层,可能会在途中被操纵。Command查询层将POCO转换为数据库对象(几乎是同一件事,但是一个是为持久性而设计的,另一个是为前端设计的)。存储该项目,并将数据库对象返回到“命令查询”层。然后将其转换为POCO,在其中返回到逻辑层,可能进行进一步处理,然后最终返回到UI 共享逻辑和接口是我们可能拥有持久数据的地方,例如MaxNumberOf_X和TotalAllowed_X以及所有接口。 共享逻辑/接口和DAL都是体系结构的“基础”。这些人对外界一无所知。 除了共享的逻辑/接口和DAL,其他一切都与poco有关。 流程仍然与第一个示例非常相似,但是它使每一层都对一件事情负责(无论是状态,流程还是其他)……但是我是否用这种方法打破了OOP? 演示Logic和Poco的示例可能是: public class LogicClass { private ICommandQueryObject cmdQuery; public PocoA Method1(PocoB pocoB) { return cmdQuery.Save(pocoB); } /*This has no state objects, only ways to communicate with other layers such as the cmdQuery. Everything else is just …

3
在C#中,为什么在try块内声明的变量的作用域受到限制?
我想将错误处理添加到: var firstVariable = 1; var secondVariable = firstVariable; 以下内容无法编译: try { var firstVariable = 1; } catch {} try { var secondVariable = firstVariable; } catch {} 为什么try catch块必须像其他代码块一样影响变量的范围?除了保持一致性之外,对于我们而言,无需重构就能够使用错误处理包装代码是否有意义?

7
先发布还是先发布文件?
我从事一个项目已经有几年了,并且我开始收集一个不错的用户群。我已经创建了一个项目页面,其中包含一些基本文档,但实际上,这仅是一个FAQ。我知道我需要改进它,以便它对新用户和高级用户都提供更多信息,并且这是下一发行版的任务清单中的下一个。 但是,下一个版本具有用户群渴望获得的功能。我已经准备好立即发布它,它已经打包并可以使用了。我只需要将其部署到适当的分发服务。 要点。这些功能对我的用户很重要,但是文档对我很重要。我应该等到重写文档后再发布吗?我当前的用户群足够了解如何使用新功能,因此我不必担心。由于我的空闲时间有限,因此可能需要花费几周才能完成文档,但是如果我让他们再等待的话,社区就会把我烤死。 客户在这种情况下正确吗?对于现有用户而言,梦幻般,直接的功能是否应该优先于针对新用户的强大文档? 更新:哇,这么多优质的回复!您确实帮助我更好地了解了我应该如何与项目及其用户进行交互和支持。太感谢了!

8
谎言2:代码应该围绕世界模型进行设计吗?[关闭]
已关闭。这个问题是基于观点的。它当前不接受答案。 想改善这个问题吗?更新问题,以便通过编辑此帖子以事实和引用的形式回答。 3年前关闭。 我最近读了《三大谎言》博客,我很难证明第二种谎言的正确性,在此引用: (LIE#2)应该围绕世界模型设计代码 代码是虚拟世界的某种模型或地图,没有任何价值。我不知道为什么这个程序对某些程序员如此引人注目,但是它非常受欢迎。如果游戏中有火箭,请放心,有一个“火箭”类(假设代码是C ++),其中包含仅一枚火箭的数据并具有火箭的功能。完全不考虑实际上是在进行什么数据转换,也不考虑数据的布局。或就此而言,如果没有基本的了解,那就是哪里有一件东西,可能不止一件。 尽管这种设计会带来很多性能损失,但最重要的是它无法扩展。完全没有 一百枚火箭的成本是一枚火箭的一百倍。而且极有可能它的成本甚至更高!即使对于非程序员,这也没有任何意义。规模经济。如果您有更多东西,它应该会更便宜,而不是更贵。做到这一点的方法是正确设计数据并通过类似的转换对事物进行分组。 特别是这是我的问题。 作为虚拟世界的模型/地图,代码具有价值,因为对虚拟世界进行建模有助于(至少个人而言)可视化和组织代码。 对我来说,开设“火箭”课是一个完全有效的选择。也许“火箭”可以分为多种类型的火箭,例如AGM-114地狱火等,其中包含有效载荷强度,最大速度,最大转弯半径,瞄准类型等,但仍然每个发射的火箭都需要有一个位置和速度。 当然拥有100枚火箭弹的成本要高于1枚火箭弹的成本。如果屏幕上有100个火箭,则必须进行100次不同的计算才能更新其位置。第二段听起来好像是在宣称如果有100枚火箭,更新状态的花费应该少于100次计算? 我的问题是作者提出了一个“有缺陷的”编程模型,但没有提出“纠正”的方法。也许我在模仿Rocket类,但我真的很想了解这个谎言的原因。有什么选择?

3
在哪个过程中发生语法错误?(标记或解析)
我正在尝试了解编译和解释,逐步找出总体图像。因此,在阅读http://www.cs.man.ac.uk/~pjj/farrell/comp3.html本文时,我遇到一个问题 它说 : 编译器的下一个阶段称为解析器。编译器的这一部分对语言的语法有所了解。它负责识别语法错误,并将无错误程序转换为可以用另一种语言解释或写出的内部数据结构。 但是我无法弄清楚令牌化器如何正确地令牌化具有语法错误的给定流。 它应该卡在此处或向解析器提供一些错误的信息。我的意思是标记化不是一种翻译器吗? 因此,它如何在标记化时克服了词汇中的错误代码行。 在Tokenizer标题上方的链接中有一个令牌示例。 据我了解,令牌的形式似乎是,如果代码中有错误,令牌也会被破坏。 您能澄清一下我的误会吗?

1
Redux内存消耗
关闭。这个问题是题外话。它当前不接受答案。 想改善这个问题吗? 更新问题,使它成为软件工程堆栈交换的主题。 3年前关闭。 Redux框架支持不变的状态/纯函数范式,该范式促进了根据当前操作从先前状态创建新状态。这种范例的适用性是毋庸置疑的。 我的一个主要问题是,由于Redux精简器急于为每个调用的每个动作从以前的状态返回新的新状态,因此,大量的内存消耗(不要与内存泄漏混淆)将在许多实际应用程序中屡见不鲜。 。考虑到Javascript应用程序通常可以在普通用户设备的浏览器中运行,而该浏览器也可以运行其他几个特定于设备的应用程序以及更多浏览器选项卡和窗口,那么节省内存的必要性就变得越来越明显。 有人真的将Redux应用程序的内存消耗与传统的Flux架构进行了比较吗?如果是这样,他们可以分享他们的发现吗?

6
将编码进度拆分为有意义的提交而无需太多开销
当处理修订或功能时,有时我会偶然发现其他细微的问题,这些问题可以在几秒钟内即时得到改善。当我立即执行它们,然后提交完成的功能/修复程序时,提交包含不止一件事。例如"add feature X and code clean up"或"fix bug X and improved logging"。最好将其分为两个提交。万一这两个更改发生在同一个文件中,我不能简单地添加一个文件,提交,添加另一个文件然后再次提交。因此,我看到以下三个选项: 在处理某些事物时故意忽略无关的事物。 复制具有两个更改的文件,将其还原,包括一个更改,提交,包括另一个更改,然后再次提交。 不要更改无关紧要的小东西,而是将它们添加到待办事项列表中,然后再做。 我不太喜欢这三个选项,原因如下: 如果不能解决小问题,则代码质量可能会受到影响。如果我有意识地错过了一次不费吹灰之力就可以改善的机会,那我就会感到难过。 这会增加人工工作,并且容易出错。 这对于不太小的待办事项很好,但是将一个微小的项目添加到待办事项列表中并稍后再访问通常比立即修复要花费更长的时间。 您如何处理这种情况?

3
为什么不调用isPresent()而不是iterator.next()的Optional.get()不好?
当使用新的Java8流api在集合中查找一个特定元素时,我编写如下代码: String theFirstString = myCollection.stream() .findFirst() .get(); 此处IntelliJ警告说,在不首先检查isPresent()的情况下调用get()的情况。 但是,此代码: String theFirstString = myCollection.iterator().next(); ...没有警告。 两种技术之间是否存在深刻的区别,从而使流传输方法在某种程度上更加“危险”,所以在不首先调用isPresent()的情况下永远不要调用get()至关重要。到处搜寻,我发现一些文章谈论程序员对Optional <>粗心大意,并假定他们可以随时调用get()。 问题是,我想在我的代码有错误的地方尽可能近地引发异常,在这种情况下,这是我在找不到元素时调用get()的地方。我不想写无用的文章,例如: Optional<String> firstStream = myCollection.stream() .findFirst(); if (!firstStream.isPresent()) { throw new IllegalStateException("There is no first string even though I totally expected there to be! <sarcasm>This exception is much more useful than NoSuchElementException</sarcasm>"); } String …
23 java8 

5
为什么在构造函数中使用setter并没有成为常见的模式?
访问器和修饰符(又名setter和getter)之所以有用,主要有以下三个原因: 它们限制了对变量的访问。 例如,可以访问但不能修改变量。 他们验证参数。 它们可能会引起一些副作用。 大学,在线课程,教程,博客文章和Web上的代码示例都在强调访问器和修饰符的重要性,如今,它们几乎像是代码的“必备”。因此,即使它们不提供任何附加值,也可以找到它们,例如下面的代码。 public class Cat { private int age; public int getAge() { return this.age; } public void setAge(int age) { this.age = age; } } 话虽如此,找到更有用的修饰符是很常见的,这些修饰符实际上会验证参数并抛出异常,或者如果提供了无效输入,则返回布尔值,如下所示: /** * Sets the age for the current cat * @param age an integer with the valid values between …

1
为什么.Net中的数组具有Length,而其他集合类型具有Count?[关闭]
已关闭。这个问题是基于观点的。它当前不接受答案。 想改善这个问题吗?更新问题,以便通过编辑此帖子以事实和引用的形式回答。 4年前关闭。 例如,在C#中,数组具有Length属性。但是其他收集类型(如列表等)具有Count属性。这两个有何不同的原因吗?如果是这样,我想知道。

1
所谓的是什么?[关闭]
关闭。这个问题是题外话。它当前不接受答案。 想改善这个问题吗? 更新问题,使它成为软件工程堆栈交换的主题。 4年前关闭。 谷歌搜索这个问题已被证明是无用的,因此该¬符号: 这是为了什么 什么叫做? 是否在任何编程语言中使用它?

4
CI如何用于解释语言?
我以前从未使用过持续集成系统(CI)。我主要使用MATLAB,Python或PHP进行编码。这些都没有构建步骤,我看不到如何将CI用于我的工作。一家大型公司的大型项目中的一位朋友告诉我,语言并不重要。 如果没有构建步骤,我看不到CI对我有什么用。我可以将CI视为可以运行单元测试的测试环境。我想念什么吗?

4
是否可以存储千字节块和指针的所有可能排列?
这是一个很难缠住我的主意的想法,我将不胜感激任何编辑/帮助,以使其对于那些熟悉的人来说更具可读性。 从理论上讲,是否有可能在硬盘上保存一个千字节的每个可能二进制排列的一个副本,然后让系统的其余部分简单地创建指向这些位置的指针? 这样制作的系统会比简单地直接存储信息快吗? 要解释另一种方式,请说而不是句子: “你好,我是鲍勃。” 和“那个三明治看起来很好吃。” ...存储在硬盘驱动器上,我们会将字母和其他字符的所有排列替换为某个数字(例如1000个字符左右),然后将句子存储为: [Pointer#21381723]

4
在构造函数中合法的“实际工作”?
我正在设计,但是一直遇到障碍。我有一个特定的类(ModelDef),它实际上是通过解析XML模式(例如DOM)构建的复杂节点树的所有者。我想遵循良好的设计原则(SOLID),并确保生成的系统易于测试。我打算使用DI来将依赖项传递到ModelDef的构造函数中(以便在测试过程中可以根据需要轻松地将其替换掉)。 不过,我正在努力的是创建节点树。该树将完全由简单的“值”对象组成,而这些对象无需独立测试。(但是,我仍然可以将抽象工厂传递到ModelDef中,以帮助创建这些对象。) 但是我一直在读,构造函数不应该做任何实际的工作(例如Flaw:Constructor可以进行实际工作)。如果“实际工作”意味着构造重量较重的相关对象,而以后可能希望将其存根进行测试,则这对我来说非常有意义。(这些应通过DI传递。) 但是像该节点树这样的轻量级对象呢?必须在某个地方创建树,对不对?为什么不通过ModelDef的构造函数(例如使用buildNodeTree()方法)呢? 我真的不想在ModelDef之外创建节点树,然后再通过(通过构造函数DI)将其传递进去,因为通过解析架构来创建节点树需要大量复杂的代码-需要进行彻底测试的代码。我不想将其委托给“胶合”代码(这应该是相对琐碎的,并且可能不会被直接测试)。 我曾考虑过将代码创建节点树放在一个单独的“构建器”对象中,但是犹豫称它为“构建器”,因为它与“构建器模式”并不完全匹配(后者似乎与消除伸缩无关。构造函数)。但是,即使我将其称为其他名称(例如NodeTreeConstructor),也只是为了避免让ModelDef构造函数构建节点树而感到有些破绽。它必须建在某个地方。为什么不在要拥有它的对象中?

5
一个字符有什么好的搜索算法吗?
我知道几种基本的字符串匹配算法,例如KMP或Boyer-Moore,但是所有这些算法都在搜索之前就对模式进行了分析,但是,如果有一个字符,就没有太多要分析的了。那么,有什么比天真搜索更好的算法来比较文本的每个字符呢?

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.