软件工程

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


7
经理想要一个结合的开发和生产环境
我在一个小型的编程团队中工作,为较大的组织提供支持。今年,我们的经理决定我们将使用Oracle Apex技术来处理我们公司的绝大多数数据。 可以,除非我们只有一台Apex服务器。我们的经理已下令一切都发生在那个实例中。我们的团队正在开发应用程序,而经理演示的是应用程序,而内部客户则在使用它们,这显然已经引起了问题! 我只能期望随着我们对Apex的投入越来越大,应用程序变得更加复杂以及用户数量的增长,这种情况会变得更糟。我听说最佳实践是拥有单独的开发,测试和生产环境,但是为什么会这样呢? 问题:为什么我们要有单独的开发,测试和生产环境?

6
编程语言中一等/二等/三等值的数学基础是什么?
添加 刚发现两个相关问题 /math//q/1759680/1281 /programming//a/2582804/156458 在编程语言中,来自Michael Scott的Programming Language Pragmatics 通常,如果编程语言中的值可以作为参数传递,从子例程返回或分配给变量,则称其具有 第一类状态。在大多数编程语言中,简单类型(例如整数和字符)是第一类的值。相比之下,“第二类”值可以作为参数传递,但不能从子例程返回或分配给变量,并且“第三类”值甚至不能作为参数传递。 标签是大多数编程语言中的三等值,但在Algol中是二等值。子例程显示最多的变化。它们是所有函数式编程语言和大多数脚本语言中的一流值。它们也是C#中的第一类值,并且在某些限制下,在其他几种命令性语言中(包括Fortran,Modula-2和-3,Ada 95,C和C ++),也是第一类值。11在大多数其他命令式语言中,它们是二等值,在Ada 83中是三等值。 编程语言中一等/二等/三等值的数学基础是什么? 该术语使我想起了一阶/二阶逻辑,但是它们有关系吗? 在我看来,它们之间的区别在于可以使用哪种特定情况下的值 作为参数传递, 从子例程返回,或者 分配给变量。 为什么特定案例很重要,而其他案例没有提到? 谢谢。

8
防止分支堆积
随着我们变得越来越大,我们开始遇到问题,其中的功能使其可以分阶段进行测试,但是到所有测试和批准的新功能都在分阶段进行测试时。 这创造了一个环境,在该环境中我们几乎永远无法投入生产,因为我们拥有经过测试和未经测试的功能的组合。我敢肯定这是一个普遍的问题,但是我还没有找到对我们有用的资源。 一些细节: BitBucket上的GIT Jenkins用于脚本部署到Azure 我希望找到一种隔离特征的方法,使它们在环境中移动并仅推送准备就绪的产品。

5
设计语言是否可以强制执行“干净代码”?[关闭]
已关闭。这个问题是基于观点的。它当前不接受答案。 想改善这个问题吗?更新问题,以便通过编辑此帖子以事实和引用的形式回答。 3年前关闭。 因此,我正在用C ++编写我的第一个项目,似乎需要更多的精力来使代码“干净”,而不仅仅是工作。也就是说,似乎C ++允许编写丑陋但有效的代码。 这让我开始思考, 编程语言可以通过设计强制执行干净的代码吗?已经有这样的语言了吗? 另外,如何将其作为设计原则纳入编程语言开发/理论中?使用什么样的措施?

4
事件驱动的编程:什么时候值得?
好的,我知道这个问题的标题几乎与何时应该使用基于事件的编程相同?但是上述问题的答案并没有帮助我确定我是否应该在遇到的特定情况下使用事件。 我正在开发一个小型应用程序。这是一个简单的应用程序,大部分功能是基本CRUD。 在发生某些事件时(修改某些数据时),应用程序必须在文件中写入所述数据的本地副本。我不确定实现此目标的最佳方法是什么。我可以: 修改数据时触发事件,并将响应(生成文件)绑定到此类事件。或者,实现观察者模式。这似乎是不必要的复杂性。 直接从修改数据的代码中调用文件生成代码。简单得多,但是依赖关系应该是这种方式似乎是错误的,也就是说,将应用程序的核心功能(修改数据的代码)与额外的特权(生成备份文件的代码)耦合起来似乎是错误的。我知道,但是,这个应用程序不会发展到那种耦合带来问题的地步。 在这种情况下最好的方法是什么?

3
关系数据库和迭代开发
在许多软件开发方法中,例如敏捷方法论,领域驱动设计和面向对象的分析与设计,都鼓励我们采用一种迭代方法进行开发。 因此,我们不应该在第一次开始从事该项目时就正确完成我们的领域模型。相反,随着时间的流逝,我们重构模型,因为随着时间的流逝,我们对问题领域有了更深入的了解。 除此之外,即使我们已经尝试过建立一个完美的模型(我已经确信这很困难),需求也可能会发生变化。软件打完已经被部署到生产,最终用户可能会注意到,有一定要求的不完全了解,或者更糟的是,一些要求失踪了。 这里的要点是,在软件部署之后,我们可能最终需要更改模型。如果发生这种情况,我们就会遇到问题:生产数据库中的用户数据很重要,并且已经以旧模型的格式进行了拟合。 如果代码设计不当且系统很大,则更新代码可能是一项艰巨的任务。但这可以随着时间的推移而完成,我们拥有类似Git的工具,可以帮助我们做到这一点,而不会损坏可投入生产的版本。 另一方面,如果模型改变,类的属性消失或其他原因,则数据库也应改变。但是我们有一个问题:已经有不能丢失的数据,已经为旧模型格式化了。 关系数据库似乎是阻碍我们进行迭代开发甚至在最终用户需要时更新软件的障碍。 我已经使用的一种方法是编写一个特殊的类,该类将旧的数据库表映射到新的数据库表。因此,这些类选择旧格式的数据,将其转换为新模型使用的格式,然后保存到新表中。 这种方法似乎不是最好的方法。我在这里的问题是:是否存在任何众所周知的和推荐的方法来协调迭代开发与关系数据库?

2
在商业产品中授权Ghostscript
我们正在研究在商业产品(Windows桌面应用程序)中使用Ghostscript的前景。 我仅通过向用户建议他们可以自行下载并安装GS来改善他们的体验来了解有关完全放弃GS许可的信息(该软件实际上也可以在没有GS的情况下运行,但是大多数用户都希望呈现/加载PDF文档)。 因此,假设我们不是自己运送 Ghostscript,而是让我们的软件检查其可用性,并在不存在的情况下,建议如何获得它(简短的说明性文字并链接至其下载页面)。如果安装了该程序,则该程序将使用Ghostscript API。 对我来说,这听起来像是合法的,正如Artifex所说的那样,“ 如果您的应用程序不符合某某条件,则不可以运送 GS”。有人愿意对此发表意见吗?
19 licensing 

3
谈论C ++“方法”(相对于“成员函数”)有多错误?
我了解,根据C ++规范,不存在“方法”之类的东西,并且一些(很多?大多数?)C ++程序员认为“方法”是一种Java主义。另一方面,即使在C ++论坛上,人们似乎也在谈论方法而不会抽搐。我正在寻找有关此术语的已知约定或惯例。 我正在记录同时具有C ++和Java版本的API。开发人员实际上将类和方法/成员函数的名称在两者之间保持相同,以方便移植和测试。因此,有关这些API的一些文档需要放在语言选择的“上方”。我需要能够大致讨论Foos和Bars及其baz()和mumble()...方法? 如果我谈论Java程序员会认为它很自然的方法,那么看来C ++程序员可能会理解,但是有些人会认为它是不正确的。我的问题是:令人发指这是怎么在实践中?相对于C ++特定的函数,通常如何在“通用OOP”上下文中谈论C ++成员函数?有没有更好的方式来讨论成员函数,而这两种语言都不对吗?(“成员函数”有点冗长。) 这不是意见调查;我正在尝试确定是否存在实际的约定或通用做法来解决此问题。 我知道这个问题,但是它通常是关于OOP的,而不是关于特定语言的。

2
贫血域模型和域服务注入
所述贫血域模型被描述为由Martin Fowler在领域驱动设计的反模式。为了在域模型上具有业务逻辑,通常使用域服务。但是Vaughn Vernon认为将域服务注入域模型是有害的(请参阅“实施域驱动设计,第387页”)。 我认为这些意见是矛盾的,这是真的吗?如何兼顾这两点? 是注入域服务与贫血域模型和普通域服务相比真的富域模型吗?

1
Akka是否淘汰了JMS / AMQP消息代理?[关闭]
已关闭。这个问题是基于观点的。它当前不接受答案。 想改善这个问题吗?更新问题,以便通过编辑此帖子以事实和引用的形式回答。 4年前关闭。 我花了最后一周深入研究Akka文档,最终了解了什么是actor系统,以及它们解决的问题。 我对传统的JMS / AMQP消息代理的理解(和经验)是,它们存在以提供以下功能: 生产者和消费者之间的异步处理;和 消息传递保证,包括持久性,重试和回退 但是,如果没有所有必需的基础架构和运营开销,Akka是否可以提供此服务? 在Akka中,所有Actor通信都是异步且无阻塞的。和 在Akka中,SupervisorStrategies存在完成重试,后备和升级的功能。如果也需要的话,可以将Actor配置为持久存储到几乎任何类型的商店。 因此,这让我感到奇怪:如果我的应用程序使用Akka,是否需要将JMS / AMQP代理(例如ActiveMQ,RabbitMQ,Kafka)带入图片?换句话说,是否曾经有过这样的用例,那就是基于Akka的新应用程序还需要引入新的 JMS / AMQP代理集群?为什么或者为什么不? 唯一的论点是,也许我的Akka应用程序必须与另一个系统集成。但是在那种情况下,Akka-Camel模块使Akka可以利用Camel详尽无穷的,几乎无限的集成功能列表(TCP,FTP,ZeroMQ,这个列表不胜枚举……)。 有什么想法吗?

3
例外-“发生了什么”与“做什么”
我们使用异常来使代码的使用者以有用的方式处理意外行为。通常,异常是围绕“发生的情况”构建的,例如FileNotFound(我们无法找到您指定的文件)或ZeroDivisionError(我们无法执行1/0操作)。 如果有可能指定消费者的预期行为怎么办? 例如,假设我们有fetch资源,该资源执行HTTP请求并返回检索到的数据。而不是像ServiceTemporaryUnavailable或之类的错误,RateLimitExceeded我们只会提出一个RetryableError建议,即消费者应该重试该请求,而不关心特定的失败。因此,我们基本上是在建议呼叫者采取一项行动-“该做什么”。 我们不经常这样做,因为我们不了解消费者的所有用例。但是,想象一下这是一个特定的组成部分,我们确实知道呼叫者的最佳操作过程-那么我们应该使用“做什么”方法吗?
19 exceptions 


3
在通常返回集合的地方返回Streams是理智的事情吗?
在开发与任何旧代码无关的API时,我经常发现自己编写的方法纯粹是通过收集结果终止的Streams管道。像这个: ImmutableSet<T> deriveSomethingMeaningfulFromPrivateState() { return myPrivateThingies.stream() .map(this::ownerOfThing) .map(Owner::socialStatus) .filter(SocialStatus::isHeAFineMatey) .collect(MyCustomCollectors.toImmutableSet()); } 现在,此类的大多数客户端通常将需要Collection(在本例中为ImmutableSet)来搜索元素并对其进行迭代,但是某些客户端可能会受益于拥有Stream,因此可以在此基础上传递更多的操作流,而无需从集合中获取新的流。因此,返回Stream会给客户提供他们如果拥有Collection便拥有的选项超集(毕竟,他们总是可以collect()自己拥有Stream: Stream<T> deriveSomethingMeaningfulFromPrivateState() { return myPrivateThingies.stream() .map(this::ownerOfthing) .map(Owner::socialStatus) .filter(SocialStatus::isHeAFineMatey); // No collect } 这种方法对我来说很诱人,因为我看不到它可能存在的任何潜在缺陷。但是,我在任何库中都从未见过这种方法(可能是因为Java 8出现后没有发布太多的库),所以我有点害怕采用它。现有的库类通常在从私有状态派生出某些东西时返回Collections。 如果我决定在Java-8之前的我自己会返回Collection的任何地方返回Stream ,会发生什么不好的事情?还是我可能在这里做一些反模式的事情,而这一切都源于私人国家?

4
整理数据太麻烦时如何测试?
我正在编写一个解析器,作为其中的一部分,我有一个Expander将单个复杂语句“扩展”为多个简单语句的类。例如,它将扩展此内容: x = 2 + 3 * a 变成: tmp1 = 3 * a x = 2 + tmp1 现在,我正在考虑如何测试此类,特别是如何安排测试。我可以手动创建输入语法树: var input = new AssignStatement( new Variable("x"), new BinaryExpression( new Constant(2), BinaryOperator.Plus, new BinaryExpression(new Constant(3), BinaryOperator.Multiply, new Variable("a")))); 或者我可以将其编写为字符串并进行解析: var input = new Parser().ParseStatement("x = 2 + 3 * a"); …

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.