软件工程

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

8
Scrum团队不遵循YAGNI原则
在SCRUM会议上,产品团队讨论了移动应用程序将使用的API功能。我们进行了一次模拟,显示了屏幕的外观以及屏幕应包含的关键元素(“布局”)。 基于此以及与产品所有者的讨论,我创建了API响应(HAL + JSON)的原型。这是非常简单的,符合HAL规范的JSON,仅能代表模型中的内容而已。我没有受到商人所预见的未来想法的影响,因为他们倾向于经常改变他们的想法,因此我决定采用简约的方法。我的提议被团队拒绝,而我的提议以7比1胜负。 团队决定使用更复杂的,非语义的抽象json结构,该结构允许在布局布局中提供更大的灵活性。这种方法的缺点是我们最终得到了一组统一的对象,这些对象在设计上可能具有null和empty属性。他们还认为最好进行A / B测试,但这只是基于他们的预测,因为我们没有这样的要求。 大多数时候,我们都在争论那些不是冲刺的一部分,也不是在样机上提到的东西。所描述的问题是“未来的市场营销将如何……”,“企业可能希望我们...如何”。 我和产品负责人都是经验丰富的程序员,我们过去已经看到过这类问题。我们尝试遵循YAGNI和KISS原则。团队的其他成员经验不足,尽管他们了解这些原则,但似乎并不了解它们。 我们同意他们的解决方案,因为整个团队对我们来说更重要,我们不想为那些不那么重要的事情而战。但是我担心这样的事情是否会成为即将来临的,更复杂的辩论的先例?如何应对这种行为?作为团队负责人,我有什么可以做得更好的? 值得一提的是,该产品是早期MVP。

2
是否有任何将相对预期任务时间纳入计划的构建系统?
这是我的问题的一个小例子: 假设一个构建作业包含名为AD的4个独立任务。总而言之,D花费的时间比AC花费的时间更长。 无法包含相对任务时间的构建系统可能会安排如下任务: --------------------------------------- CPU1: A | C | --------------------------------------- CPU2: B | D | --------------------------------------- 相反,如果调度程序知道任务时间差异,则可以提出以下更短的调度: --------------------------------------- CPU1: A | B | C | --------------------------------------- CPU2: D | --------------------------------------- 我的问题: 是否有任何将相对预期任务时间纳入计划的构建系统? 对于这种构建系统有哪些学术研究? 这些构建系统(如果存在)从哪里获取时间信息?试探法,以前的构建过程中收集的时间? 如果不存在这样的构建系统,为什么?是否有一个陷阱使他们不如乍一看看上去那么有价值?

1
MVP和干净架构之间有什么区别
这个问题是不言而喻的,只是增加了我的想法: 据我所读,Clean arch中的表示层与MVP中的MV具有相同的职责。 一个人如何决定选择一种模式而不是另一种?
13 architecture  mvp 

4
大班单责任
我有一个2500行Character类: 跟踪游戏中角色的内部状态。 加载并保持该状态。 处理大约30个传入命令(通常=将它们转发到Game,但是一些只读命令会立即得到响应)。 从Game正在采取的行动和他人的相关行动中收到约80个电话。 在我看来,这Character只有一个责任:管理角色的状态,在传入的命令和游戏之间进行调解。 还有其他一些职责已经分解: Character具有Outgoing调用的,以为客户端应用程序生成传出更新。 Character有一个Timer跟踪下一次允许它做某事的时间。对此验证了传入的命令。 所以我的问题是,在SRP和类似原则下拥有如此大的课程是否可以接受?是否有任何最佳实践来减轻它的麻烦(例如,将方法拆分为单独的文件)?还是我错过了一些东西,真的有很好的方法将其拆分吗?我意识到这是非常主观的,希望获得其他人的反馈。 这是一个示例: class Character(object): def __init__(self): self.game = None self.health = 1000 self.successful_attacks = 0 self.points = 0 self.timer = Timer() self.outgoing = Outgoing(self) def load(self, db, id): self.health, self.successful_attacks, self.points = db.load_character_data(id) def save(self, db, id): db.save_character_data(self, health, self.successful_attacks, self.points) …

5
“静态接口”是一种好习惯吗?
我刚刚注意到,在接口中可以选择使用静态方法。与接口的静态字段相同,有一个有趣的行为:这些不是继承的。 我不确定它在要实现的实际接口中是否有用。但是,它使程序员能够创建仅仅是静态内容的信封的接口,例如实用程序类。 一个简单的例子只是全局常量的包络。与班级相比,您可以轻松地注意到public static final那些假定的样板丢失了(使它不太冗长)。 public interface Constants { String LOG_MESSAGE_FAILURE = "I took an arrow to the knee."; int DEFAULT_TIMEOUT_MS = 30; } 您还可以使事情变得更复杂,例如配置键的伪枚举。 public interface ConfigKeys { static createValues(ConfigKey<?>... values) { return Collections.unmodifiableSet(new HashSet(Arrays.asList(values))); } static ConfigKey<T> key(Class<T> clazz) { return new ConfigKey<>(clazz); } class ConfigKey<T> { private …
13 java  java8 


1
TDD方法可以自上而下应用吗?
我不清楚TDD(该方法论)如何处理以下情况。假设我想在Python中实现mergesort算法。我首先写 assert mergesort([]) === [] 并且测试失败 NameError:未定义名称“ mergesort” 然后我添加 def mergesort(a): return [] 我的测试通过了。接下来我添加 assert mergesort[5] == 5 我的测试失败了 断言错误 我通过 def mergesort(a): if not a: return [] else: return a 接下来,我添加 assert mergesort([10, 30, 20]) == [10, 20, 30] 现在我必须尝试通过此步骤。我“知道” mergesort算法,所以我这样写: def mergesort(a): if not a: return [] else: …
13 tdd 

3
多存储库环境中的打包和版本策略
我们是一家小型公司,拥有多个团队管理自己的git存储库。这是一个Web平台,每个团队的工件都在一天结束时部署以进行夜间测试。我们正在尝试使围绕版本控制和打包的过程正式化。 每个团队都有一个主分支,负责日常开发。每个团队的质量保证成员都希望将他们团队变更中的工件部署到测试台中,由厨师将所有组件组合在一起。工件是压缩包,但我想将其转换为RPM,以便我们可以正确思考和推理版本。 发布过程涉及从每个git存储库的开发分支(在大多数情况下为master)切断发布分支。然后将其提供给质量保证,由质量保证对一组工件进行测试和签核。 例如,这是一个典型的git存储库及其相关的发行分支: 0-0-0-0-0-0-0-0-0-0 (master) | | 0 0 (rel-1) | 0 (rel-2) 我一直在试图找出一种方案来执行来自开发分支的软件包的版本控制。我们不想过多地标记每个仓库的主分支,并限制标签仅释放分支。但是我们应该能够使用标准的yum / rpm语义查询测试机器中已部署的软件包。当master分支没有标签时,开发版本会是什么样?我知道这git describe可以为我提供构建版本的有用表示,但是当标记分支上的各个发行点时,它可以很好地工作。 编辑1:响应@ Urban48的答案 我认为我应该多解释一下发布过程。为了便于讨论,我们假设master在所有存储库中都有分支。该master分支被视为开发分支,并且已部署到支持CI-CD的自动化QA环境。这是每晚测试的子集,用于确保主服务器的稳定性。在削减发行分支之前,我们先看一下这一系列工作。我们的发行分支是短暂的。假设(从稳定的主服务器上)剪切了一个发布分支之后,将运行完全回归,进行修复并将其部署到生产中。这大约需要一周的时间。我们几乎每两周发布一次产品。 我们的功能分支总是从母版中剪切下来的,并在与母版合并之前经过一定量的开发人员测试,然后对它们进行CI-CD稳定性检查。 修补程序是在修补程序分支(从发行版分支切下的)上进行的,并以最小的影响测试将其部署到生产环境中。 以下是我们针对发行版和修补程序分支的版本控制策略。在质量检查周期中,发行分支会经历的版本v2.0.0-rc1,v2.0.0-rc2最后在质量检查批准后变为v2.0.0。 有时,我们会针对一些小功能进行点发布,这些小功能会合并到版本变为的版本分支(然后合并到母版)中v2.1.0。修补程序采用该v2.1.1模式。 但是,问题不在于对这些分支进行版本控制。我不希望完全更改此版本控制方案。唯一的变化来自开发部门。主。如何在CI-CD环境中可靠地指示在生产中的先前发行版中存在哪个版本。理想情况下,这可以通过智能git标记完成,但最好不要过度标记master分支。

4
是否有关于如何编写现代C的公认准则?
我有很强的Java / Groovy背景,并且已被分配给一个为管理软件维护大量C代码库的团队。 Java Web服务已经外部化了一些痛点,例如处理数据库中的Blob或生成PDF和Excel中的报告。 但是,作为Java开发人员,我对代码的某些方面感到有些困惑: 它很冗长(尤其是在处理“异常”时) 有很多巨大的方法(很多2000行以上的方法) 没有高级数据结构(我很想念List,Set和Map) 无需关注(SQL在代码中充满欢乐) 结果,我觉得企业隐藏在大量的技术代码中,而我的大脑(由面向对象和少量的功能编程所塑造)并不轻松。 该项目的好处是代码简单明了:没有框架,没有运行时的字节码操作,也没有AOP。并且服务器可以通过使用比Java吐出“ hello world”所需的内存更少的内存,在一台计算机上同时回答10000多名用户。 我想学习如何根据公认的现代原理编写C代码。关于如何编写和构造现代C,是否有任何公认的原则? 有点像“有效Java”书的等效内容,但适用于C。 根据答案和评论进行编辑: 我将尝试使我的思维方式适应C代码,而不是尝试将其镜像到OOP。 我已经开始从评论中扫描推荐的编码风格指南(GNU编码标准和Linux内核编码风格)。 然后,我将尝试向我的同事提出这种代码样式。最困难的部分可能是说服同事,将巨大的方法拆分为较小的部分,并且借助一种方法可以避免重复相同的4行错误处理代码。
13 c  maintenance 

4
如何鼓励初级开发人员参与代码审查?
我目前是一名高级开发人员,下面有3个初级人员,并介绍了一个代码审查过程来帮助管理进入生产阶段的代码的质量。 我觉得这对我们所有人互相审查工作非常有益,但是在大约5周的过程中,我是唯一在工具(BitBucket)中发表评论的人。 我认为工作中存在部分文化问题,如果他们的评论有误,也许会自然而然地不情愿,但是有什么办法,我可以帮助下辈们更加自在地批判我和彼此的工作吗?

3
对于涉及接口的仿真来说,这是糟糕的OOP设计吗?
我正在设计自己的小OOP程序来模拟吸血鬼,狼,人类和卡车,并试图实现自己对接口的有限理解。 (我在这里仍然是抽象的,还没有代码实现,所以这是一个OOP设计的问题……我想!) 我在这些类之间寻找“共同行为”并将其实现为接口是否正确? 例如,吸血鬼和狼咬人……那么我应该有一个咬人界面吗? public class Vampire : Villain, IBite, IMove, IAttack 同样对于卡车... public class Truck : Vehicle, IMove 对于人类... public class Man : Human, IMove, IDead 我的想法在这里吗?(感谢您的帮助)

1
为什么ASCII表中的标点符号到处都是?
在ASCII表中,标点符号出现在非打印字符之间以及数字(!"#$%&')*+,-./)之前,数字与大写字母(:;<=>?@)之间,大写字母([\]^_`)与小写字母之间以及小写字母({|}~)之后。 乍一看,人们希望将它们归为一类。可能在所有字母数字字符之前或之后。但这种情况并非如此; 他们喜欢散布在这些不同的群体中。 为什么会这样呢?是否有某些(可能是历史原因)将字符以这种方式分组的原因?
13 strings  ascii 

4
最小化函数参数数量的技术
在“干净代码”中,写有“函数的理想参数个数为零”。解释原因并讲得通。我所需要的是重构具有4个或更多参数的方法来解决此问题的技术。 一种方法是将参数提取到新的类中,但是那肯定会导致类的爆炸式增长吗?那些类可能以违反某些命名规则的名称结尾(以“ Data”或“ Info”等结尾)? 另一种技术是使多个函数使用的变量成为私有成员变量,以避免传递它们,但这扩大了变量的范围,可能使它向实际上不需要它的函数开放。 只是寻找使函数参数最小化的方法,就已经接受了这样做的好主意。

5
为什么静态方法不能被重写?
在回答这个问题时,普遍的共识是静态方法不应被覆盖(因此C#中的静态函数不能是虚拟的或抽象的)。但是,不仅在C#中是这种情况。Java也禁止这样做,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.