软件工程

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

5
为什么将单元测试专用方法视为不良做法?
内容: 我目前正在使用Python进行一个小项目。我通常使用一些公开的方法来构造我的类,这些方法已记录在案,但主要处理高级概念(类的用户应了解和使用的内容),以及一堆隐藏的(从下划线开始)负责方法的类。复杂或低级别的处理。 我知道测试对于确保代码的信心并确保以后进行的任何修改都不会破坏以前的行为至关重要。 问题: 为了在受信任的基础上构建更高级别的公共方法,我通常会测试私有方法。我发现查找代码修改是否已引入回归以及在何处更容易。这意味着这些内部测试可能会因次要修订而中断,并且需要修复/替换 但是我也知道,单元测试私有方法至少是一个有争议的概念,或者更经常被认为是不好的做法。原因是:仅应测试公共行为(参考) 题: 我确实关心以下最佳做法,并希望了解: 为什么在私有/隐藏方法上使用单元测试不好(有什么风险)? 当公共方法可以使用低级和/或复杂处理时,最佳实践是什么? 精度: 这不是一个如何的问题。Python没有真正的隐私概念,隐藏的方法根本没有列出,但是当您知道它们的名称时就可以使用 我从没学过编程规则和模式:我的上一堂课是80年代的...我主要通过尝试和失败以及在Internet上的引用来学习语言(多年来,Stack Exchange是我的最爱)

5
MVC:控制器是否违反了单一责任原则?
单一责任原则指出“班级应该有一个改变的理由”。 在MVC模式中,Controller的工作是在视图和模型之间进行中介。它为View提供了一个界面,以报告用户在GUI上进行的操作(例如,允许View调用controller.specificButtonPressed()),并且能够在Model上调用适当的方法,以操纵其数据或调用其操作(例如model.doSomething()) 。 这意味着: 控制器需要了解GUI,以便为“视图”提供合适的界面来报告用户操作。 它还需要了解模型中的逻辑,以便能够在模型上调用适当的方法。 这意味着有两个更改的原因:GUI的更改和商务逻辑的更改。 如果GUI发生更改,例如添加了新按钮,则控制器可能需要添加新方法,以允许视图报告用户对该按钮的按下情况。 而且,如果模型中的业务逻辑发生了变化,则控制器可能必须进行更改才能在模型上调用正确的方法。 因此,控制器有两个可能的变化原因。它会破坏SRP吗?

3
GDB如何暂停执行
您可能知道,我们可以使用GDB并在代码上设置断点来暂停执行以进行调试。 我的问题是,GDB如何暂停进程,并允许您使用i r例如查看寄存器的内容。这些寄存器不是经常被其他OS进程使用吗?他们怎么不被覆盖? 它只是内容的快照,而不是实时数据吗?
16 c++  debugging 


4
何时将公共字段移入基类?
我目前有两个派生类A和B,它们都有一个共同的字段,并且我试图确定它是否应该进入基类。 永远不会从基类中引用它,并且说如果在将来的某个时刻派生出另一个没有的类C,那么它不会_field1违反“最低特权”(或某些东西)的原则。是吗 public abstract class Base { // Should _field1 be brought up to Base? //protected int Field1 { get; set; } } public class A : Base { private int _field1; } public class B : Base { private int _field1; } public class C : Base { // …

2
将带有指针参数的C ++方法转换为C函数是否可以接受?
我在ESP-32上使用C ++。注册计时器时,我必须这样做: timer_args.callback = reinterpret_cast<esp_timer_cb_t>(&SoundMixer::soundCallback); timer_args.arg = this; 计时器在这里 soundCallback。 注册任务时也是如此: xTaskCreate(reinterpret_cast<TaskFunction_t>(&SoundProviderTask::taskProviderCode), "SProvTask", stackSize, this, 10, &taskHandle); 因此,该方法在单独的任务中启动。 GCC总是警告我这些转换,但它按计划进行。 生产代码中可以接受吗?有一个更好的方法吗?
16 c++  c  functions 

1
.NET解决方案的目录结构
我们最近有一个承包商访问,对我们的项目结构方法提出质疑。请注意,我专门指的是目录结构。他建议使用Microsoft指南。我以为我可以在Google“ Microsoft指南.NET项目目录结构”中找到有用的东西,但是事实证明并非如此。就目前而言,我们做这样的事情: [Company.System.Feature] |-doc |Sandcastle project |-lib |Nuget packages |-src |-Project1 e.g. web |-Project2 e.g. business logic |-UnittestProject1 |-Specs doc文件夹包含一个Sandcastle解决方案,如此处所述:https : //www.codeproject.com/Articles/15176/Sandcastle-Help-File-Builder(请参阅:绝对路径和相对路径)。因此,doc文件夹包含一个Help文件夹,其中包含生成的帮助文件。lib文件夹包含所有Nuget软件包。 是否有任何Microsoft准则,建议如何构建解决方案?我在这里看过:https : //stackoverflow.com/questions/789389/project-structure-for-c-sharp-development-effort/789554? noredirect =1# comment86756309_789554等。我读过的大多数文章和问题似乎都是在2007-2009年创建的。我相信Nuget是在2010年推出的。是否有Microsoft准则?我读到一些叫做Tree Surgeon的东西,但是似乎不再存在了:https : //archive.codeplex.com/? p =treesurgeon。 我正在使用TFS;巡航控制和DDD可以发挥任何作用。
16 c#  visual-studio 

4
Java-拥有完全静态的类是一个坏主意吗?
我正在一个更大的单独项目中工作,并且现在有几个类,在这些类中我看不到创建其实例的任何理由。 例如,我现在的骰子类静态地存储其所有数据,并且其所有方法也都是静态的。我不需要初始化它,因为当我想掷骰子并获得新值时,我只是使用Dice.roll()。 我有几个类似的类,它们只有一个这样的主要功能,我将开始研究一种“控制器”类,它将负责所有事件(例如,玩家移动时以及当前的转弯方向)是的),而且我发现我可以针对这一堂课遵循相同的想法。我从来没有打算为这些特定的类创建多个对象,因此使它们完全静态将是一个坏主意吗? 我想知道当涉及到Java时,这是否被视为“不好的做法”。从我所看到的,社区似乎在这个话题上有些分歧?无论如何,我希望对此进行一些讨论,并且与资源的链接也很棒!

4
无法解决Javascript函数之谜
我试图了解Javascript幕后的景象,并迷恋于了解内置对象的创建,尤其是对象和函数以及它们之间的关系。 当我读取到所有内置对象(如Array,String等)都是从Object扩展(继承)时,我假定Object是第一个被创建的内置对象,其余对象都继承自该对象。但是,当您知道对象只能由函数创建时,然后函数也不过是Function的对象而已,这没有任何意义。听起来开始像母鸡和鸡肉的困境。 另一个非常令人困惑的事情是,如果我console.log(Function.prototype)打印了一个函数,但是当我打印时console.log(Object.prototype)它打印了一个对象。为什么Function.prototype当它打算成为一个对象时是一个函数? 同样,根据Mozilla文档,每个javascript function都是Function对象的扩展,但是当您console.log(Function.prototype.constructor)再次将其作为函数时。现在,您如何使用自己创建的东西(思维=吹动)。 最后一件事Function.prototype是一个函数,但是我可以constructor使用来访问该函数Function.prototype.constructor,这意味着Function.prototype一个返回prototype对象的函数

3
为什么不立即提交合并的更改?
我的办公室使用Git和SourceTree进行版本控制。之所以如此,是因为当我加入时,版本控制为零,而SourceTree是我曾经使用过的唯一系统。我绝对不是专家,但是我是同事中经验最丰富的人,因此我是事实上的专家,负责教会每个人正确使用Git并纠正他们犯的任何错误。 我正在制作一个教程文档,其中涉及Git和SourceTree,并解释了该过程的每个步骤。在“拉”过程中,“ SourceTree”对话框允许您选择“立即提交合并的更改”选项。我了解它的作用以及为什么有用。我不明白的是为什么会有人不希望使用此功能。 有人可以解释为什么您永远不想自动提交合并的更改吗?我试图理解其原因,以便可以更好地解释该功能的用途,并了解将来需要注意的陷阱。 编辑:我不认为我的问题是链接的问题的重复。链接的问题广泛地询问多久提交一次。我在问为什么不选择不使用与在SourceTree中提交合并有关的特定功能。

3
什么时候应该在接口中使用string_view?
我正在使用一个内部库,该库旨在模仿拟议的C ++库,并且在过去几年中的某个时候,我看到其接口已从使用更改std::string为string_view。 因此,我忠实地更改了代码,以适应新的界面。不幸的是,我必须传递的是std :: string参数,以及返回的std :: string值。所以我的代码从这样的事情改变了: void one_time_setup(const std::string & p1, int p2) { api_class api; api.setup (p1, special_number_to_string(p2)); } 至 void one_time_setup(const std::string & p1, int p2) { api_class api; const std::string p2_storage(special_number_to_string(p2)); api.setup (string_view(&p1[0], p1.size()), string_view(&p2_storage[0], p2_storage.size())); } 除了更多的代码(可能搞砸了)之外,我真的看不到这种变化给我作为API客户端带来了什么。API调用不太安全(由于API不再拥有其参数的存储空间),可能保存了我的程序0的工作(由于编译器现在可以进行移动优化),即使确实保存了工作,也只能在启动后或在某个地方的大循环中,将不会并且永远不会完成的一些分配。不适用于此API。 但是,这种方法似乎遵循我在其他地方看到的建议,例如,以下答案: 顺便说一句,从C ++ 17开始,您应该避免传递const std :: string&,而推荐使用std :: …

6
按需求或方法划分单元测试
首先,对标题表示歉意,我想不出最简单的解释方法! 我有一个要为其编写单元测试的方法。我将使其保持相当通用,因为我不想讨论该方法的实现,而只是讨论它的测试。方法是: public void HandleItem(item a) { CreateNewItem(); UpdateStatusOnPreviousItem(); SetNextRunDate(); } 因此,此类有一个公共方法,然后调用一些私有方法来执行逻辑。 因此,在编写单元测试时,我想检查所有三件事。因为它们都在同一运行中被调用,所以我认为我可以将其作为一项测试: public void GivenItem_WhenRun_Thenxxxxx { HandleItem(item); // Assert item has been created // Assert status has been set on the previous item // Assert run date has been set } 但我认为我也可以将其编写为三个单独的测试: public void GivenItem_WhenRun_ThenItemIsCreated() { HandleItem(item); } public …
16 c#  unit-testing 

3
您如何测试仅用于查询外部API但API使用复杂查询语法的函数?
唯一的逻辑是外部API的查询语法。我不想测试它是否查询api,我想测试它是否以返回正确数据的方式查询它。例如,一些伪代码: function retrieve_related_data(id) { query = "[potentially long, syntactically complex query that uses param id to get some data]"; results = api_wrapper.query(query); return results; } 一个由API组成的更具体的示例: function retrieveLifeSupportingObjectsWithinRegion(id) { query = " within region(" + id + ") as r find objects matching hydration>0 and temp_range has 75 send name, …

5
随着更具表现力的编程语言的发展,对软件设计规范的需求是否大大减少了?
对于许多IT人员(包括几年前的我自己),理想的软件开发过程是在编写一行代码之前,先创建带有许多UML图的详细设计文档。(这看起来像是瀑布模型的描述,但与敏捷相同,只是迭代次数较小。) 在过去的两三年中,我完全改变了主意。我仍然认为,带有相关测试用例的详细需求规范绝对是必不可少的。对于大型项目,在开始编写代码之前,我还需要概述总体体系结构。但是所有其余的都应该尽可能地用代码完成。在理想情况下,除了代码本身外,不应该对软件设计进行任何描述。 我是如何得出这个结论的?以下是一些参数: 反馈 用于编写文档或创建图表的工具几乎没有反馈。是的,有些建模工具可以对UML图进行一些一致性检查,但是它们是有限的,并且会产生大量开销。 没有反馈,很难识别和修复错误。 编写代码后,您将获得大量反馈,例如: 来自编译器的错误和警告 静态代码分析结果 单元测试 错误可以快速识别并解决。 一致性 为了确保代码与您的文档一致,您必须一次又一次地检查。如果经常进行更改,则很难使代码和文档保持同步。 重构 有许多强大的工具和技术可用于重构代码,而重构文本描述或图表通常很困难且容易出错。 进行这项工作有一个先决条件:代码必须足够容易阅读和理解。这可能无法用Assembler,Basic或Fortran来实现,但是现代语言(和库)更具表现力。 因此,如果我的论点是正确的,则应该有一个趋势,即越来越少的轻量级软件设计规范和文档。这种趋势是否有任何经验证据?

4
快速的主要版本是否表明设计不良?
几个月前,我开始担任初级程序员的工作。我们正在研究的系统已投入生产约2年。我没有参与系统和设计的乞讨。 我注意到的一件事是,系统主要版本已经是11.YZ。根据我在其他系统和库上的使用经验,我不记得看到如此快的产品碰撞主要版本的情况。有些产品已经在1.XY中使用多年,并且仍在接收功能和错误修正。 假设正确使用了语义版本控制,这是否表明系统设计不佳,因为它几乎每四个月进行一次重大更改?

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.