软件工程

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

1
更改方法签名以在PHP中实现类
有没有关于PHP缺少泛型的体面工作,这些泛型允许静态代码检查以检测类型一致性? 我有一个抽象类,我想对其进行子类化,并且还强制其中一种方法从采用一种类型的参数更改为采用作为该参数的子类的参数。 abstract class AbstractProcessor { abstract function processItem(Item $item); } class WoodProcessor extends AbstractProcessor { function processItem(WoodItem $item){} } PHP不允许这样做,因为它正在更改不允许的方法签名。使用Java样式泛型,您可以执行以下操作: abstract class AbstractProcessor<T> { abstract function processItem(T $item); } class WoodProcessor extends AbstractProcessor<WoodItem> { function processItem(WoodItem $item); } 但是很明显,PHP不支持这些功能。 谷歌针对这个问题,人们建议使用instanceof在运行时检查错误,例如 class WoodProcessor extends AbstractProcessor { function processItem(Item $item){ if …

9
在不同的编程语言上学习OOP有什么区别吗?[关闭]
已关闭。这个问题需要更加集中。它当前不接受答案。 想改善这个问题吗?更新问题,使其仅通过编辑此帖子来关注一个问题。 6年前关闭。 我想学习OOP。我了解Python,但对OOP知之甚少。 但是,当我在论坛上搜索“ learning OOP”时,我看到一个家伙在说:“ Python太新了,这就是为什么您不能在Python上学习OOP的原因。应该先学习Java,然后再理解Java上的OOP”。 是真的吗 在不同的编程语言上理解OOP有什么区别吗?喜欢在Java,C#,C ++,Perl或Python上学习它?

6
为什么将线程称为线程?
我了解一个进程是资源所有权和可执行指令的单元。线程允许一个进程通过多次执行共享其资源,并且由于与整个进程相关的所有开销,操作系统更容易调度线程。 但是为什么要命名线程?它是否有对字符串或执行交错的引用?即使这样,在我看来这也不是一个直观的术语。

2
DDD:不可变的对象也可以是实体吗?
我已经阅读了无数关于实体和值对象之间差异的文章,尽管我确实认为至少在概念上我理解两者之间的区别,但似乎在其中一些文章中,作者认为特定领域概念是一个VO,仅仅是因为它是不可变的(因此,其状态将永远不会改变,至少在该特定域模型内)。 您是否同意,如果某个对象的状态在特定的域模型内永远不会改变,那么该对象永远不应是一个实体?为什么?

2
如何解释我们浪费开发人员时间来添加不必要的功能?
因此,我已经带领同工们一起负责,至少开始“思考”精益。我们遇到了一些主要的浪费问题,而2/3导致了完全相同的一点……“额外功能”。我们在销售和项目管理两个方面对自己的软件进行审查。它非常适合销售,因为这就是CRM的优势。它对管理项目不是很好,并且我们经常要承担添加额外功能以使其适用于此用例的任务。 继续添加不会增加任何客户价值的功能是否更有意义,还是我们应该接受让我们的销售团队使用我们自己的产品“足够好”,或者寻找现成的解决方案?


2
C标准递归考虑一致性的原因是什么?
C99标准在6.5.16:2中指出: 赋值运算符的左值应为可修改的左值。 并在6.3.2.1:1中: 可修改的左值是不具有数组类型,不完整的类型,不具有const限定类型的左值,并且如果是结构或联合,则不具有任何成员(递归包括任何成员)或const限定类型的所有包含的集合或联合的元素)。 现在,让我们考虑一个非const struct带const字段。 typedef struct S_s { const int _a; } S_t; 按照标准,以下代码是未定义行为(UB): S_t s1; S_t s2 = { ._a = 2 }; s1 = s2; 这样做的语义问题是,根据实体(struct)的声明类型,应将包围实体()视为可写(非只读S_t s1),但不应通过标准措辞将其视为可写(第2条在顶部),因为const现场_a。对于读代码的程序员,该标准不清楚,该赋值实际上是一个UB,因为无法分辨出struct S_s ... S_t类型的定义是不可能的。 此外,无论如何,仅以语法方式强制执行对该字段的只读访问。不可能const将非字段的某些部分const struct真正放置到只读存储中。但是这样的标准措辞使故意丢弃const这些字段的访问程序中的字段限定符的代码无效,就像这样(对C中的结构字段进行const限定是一个好主意吗?): (*) #include <stdlib.h> #include <stdio.h> typedef struct S_s { const int _a; } S_t; …
9 design  c 

4
CQRS + ES中的对象应该在哪里进行完全初始化:在构造函数中,还是在应用第一个事件时?
在OOP社区中似乎已经达成广泛的共识,即类构造函数不应将对象部分或什至完全未初始化。 我所说的“初始化”是什么意思?粗略地讲,原子过程将新创建的对象带入其所有类不变式都成立的状态。它应该是发生在对象上的第一件事(每个对象只能运行一次),并且任何内容都不应该拥有未初始化的对象。(因此,经常建议在类构造函数中执行对象初始化。出于同样的原因,Initialize方法常常被皱眉,因为这些方法打破了原子性并使得可以持有和使用尚未使用的对象成为可能。处于定义良好的状态。) 问题:当CQRS与事件源(CQRS + ES)结合使用时,对象的所有状态变化都被捕获在一系列有序的事件(事件流)中,我想知道对象何时真正达到完全初始化的状态:在类构造函数的末尾,还是在将第一个事件应用于对象之后? 注意:我避免使用“聚合根”一词。如果愿意,在阅读“对象”时将其替换。 讨论示例:假定每个对象由某个不透明Id值唯一标识(请考虑GUID)。可以使用相同的Id值在事件存储中标识表示该对象状态变化的事件流:(不用担心正确的事件顺序。) interface IEventStore { IEnumerable<IEvent> GetEventsOfObject(Id objectId); } 进一步假设有两种对象类型Customer和ShoppingCart。让我们关注ShoppingCart:创建时,购物车为空,必须与一个客户完全关联。最后一点是类不变式:ShoppingCart与a无关的对象Customer处于无效状态。 在传统的OOP中,可以在构造函数中对此建模: partial class ShoppingCart { public Id Id { get; private set; } public Customer Customer { get; private set; } public ShoppingCart(Id id, Customer customer) { this.Id = id; this.Customer = customer; } } …

2
堆栈+堆+静态内存模型是否可以替代?
我见过的所有程序都将其数据存储器组织到一个或多个调用堆栈(通常是固定大小,但有时不是),堆和静态存储器中。最近,线程本地静态存储也已添加到其中。 有没有尝试以根本不同的方式来组织数据存储器布局,例如没有调用堆栈?还是以完成同一件事的另一种方式组织记忆?

4
.NET编程和POCO类
今晚我在思考需要更改的某些应用程序时思考了一下,这让我开始思考。实体框架实体是POCO(普通的旧CLR对象),而ASP.NET MVC中使用的模型通常也是POCO。这基本上意味着仅属性,没有方法。 现在,OO编程通常允许对象封装其功能,包括其属性和方法,这允许多态发生。随着使用POCO类的兴起,通用存储库之类的设计模式变得越来越流行。过去,当我的对象有自己的CRUD操作时,现在将它们放在存储库中。 这仅仅是OO的发展而已,它从对象中删除了CRUD操作以使它们解耦,或者CRUD操作过去不应该处于对象级别,而我错了吗?哎呀,也许两者都是合法的,而且一直都是。这只是一个让我思考的观察,所以我想寻求其他意见。

4
为什么大数据需要发挥作用?
我开始从事与大数据相关的新项目的实习。我的经理们建议开始学习函数式编程(他们强烈推荐Scala)。我使用F#的经验很卑鄙,但是我看不到使用这种编程范例的重要性,因为在某些情况下它很昂贵。 迪恩(Dean)在这个话题上做了有趣的演讲,并在这里分享了他对“大数据”为何的想法:http : //www.youtube.com/watch?v=DFAdLCqDbLQ 但这并不十分方便,因为大数据并不意味着只有Hadoop。 由于BigData是非常模糊的概念。我暂时忘记了。我尝试提出一个简单的示例,以便在处理数据时比较不同方面,以查看功能方式是昂贵的还是没有。如果小数据的功能编程昂贵且占用大量内存,那么为什么大数据需要它? 我远没有花哨的工具,而是尝试使用三种方法针对一个特定且普遍存在的问题构建解决方案:命令式和功能性方法(递归,使用集合)。我比较了时间和复杂性,以比较这三种方法。 我使用Scala编写这些函数,因为它是使用三种范式编写算法的最佳工具 def main(args: Array[String]) { val start = System.currentTimeMillis() // Fibonacci_P val s = Fibonacci_P(400000000) val end = System.currentTimeMillis() println("Functional way: \n the Fibonacci sequence whose values do not exceed four million : %d \n Time : %d ".format(s, end - start)) val …

4
使用多个不同的库时的编码样式
我正在研究一些使用多个库(包括一些C库)的C ++代码,它们都具有不同的编码样式。一旦达到可用阶段,它将开源。对于签出代码以修复一个错误或添加一个功能的短期贡献者,这将给他们带来最少的混乱? 即使整个应用程序偶尔与所使用的库的典型编码风格都不匹配,在整个应用程序中也要具有一种一致的编码风格。 当某个模块中大量使用某个库时,请遵循该模块中该库的典型编码样式(即该库自己的代码和文档中使用的编码样式)。 我的想法是,后者将使该特定库中的专家更容易做出一次性贡献,并使得在开发过程中合并教程/示例代码更加容易。但是,这也使整个应用程序中的编码样式不一致。每种方法的优缺点是什么?

4
确保交易与DDD的一致性
我从DDD开始,并了解使用聚合根来确保跨国一致性。我们不应在一项应用程序服务中修改多个聚合。 但是,我想知道如何处理以下情况。 我有一个称为“产品”的聚合根。 还有一个称为“组”的聚合根。 两者都有ID,并且可以独立编辑。 多个产品可以指向同一组。 我有一个可以更改产品组的应用程序服务: ProductService.ChangeProductGroup(string productId, string groupId) 检查组存在 从仓库获取产品 设置组 将产品写回到存储库 我还有一个可以删除组的应用程序服务: GroupService.DeleteGroup(string groupId) 1.从其groupId设置为提供的groupId的存储库中获取产品,确保计数为0或中止2.从组存储库中删除组3.保存更改 我的问题是以下情况,如果发生以下情况: 在ProductService.ChangeProductGroup中,我们检查该组是否存在(确实存在),然后在此检查之后,一个单独的用户(通过另一个GroupService.DeleteGroup)删除了productGroup。在这种情况下,我们为刚刚删除的产品设置了参考? 这是我设计中的缺陷吗?我应该使用其他域设计(如有必要,添加其他元素),还是必须使用事务处理?

3
正在使用具有可接受的副作用(REST)的PUT
每当用户更新表单时,我都想创建一个撤消历史记录。因为这是更新,所以我想使用PUT请求。但是,我读到PUT不需要有副作用。 在这里使用PUT是否可以接受?有更好的选择吗? PUT /person/F02E395A235 { time: 1234567, fields: { name: 'John', age: '41' } } 在服务器中 doPut('person/:personId', // create a new person snapshot ) 编辑: 用户可以看到该历史记录,多次调用将产生多个版本。 解决方案是在创建版本之前检查该版本是否唯一。

2
Scala中的自我类型和特质继承有什么区别?
谷歌搜索后,出现了许多有关该主题的回复。但是,我觉得它们中的任何一个都无法很好地说明这两个功能之间的区别。所以我想再尝试一次,特别是... 使用自我类型而不是继承可以做什么,反之亦然? 对我来说,两者之间应该有一些可量化的物理差异,否则它们只是名义上的差异。 如果特征A扩展了B或自类型B,它们是否都说明存在B是必要条件?区别在哪里?

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.