软件工程

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

2
Mono Project如何在MIT下重新许可其LGPLed库?
Mono项目曾经具有LGPLed库。实际上mbundle还是说你运行的时候 请注意,静态链接LGPL Mono运行时比动态链接具有更多的许可限制。有关许可的详细信息,请参见http://www.mono-project.com/Licensing。 截至2016年3月,他们在麻省理工学院重新授权了它们。鉴于该项目已有多年历史,并且可能有许多外部贡献者提供了这些贡献,而这些贡献只是作为LGPLed贡献提供的,如何更改许可证?在过去的12年中,他们是否不必获得每个贡献者的许可?也许那些贡献者必须签署一些协议?

4
Java:如何实现设置程序的顺序无关紧要的步骤生成器?
编辑:我想指出,这个问题描述了一个理论上的问题,并且我知道我可以使用构造函数参数作为强制参数,或者如果API使用不正确则抛出运行时异常。然而,我在寻找,它的解决方案不要求构造函数参数或运行时检查。 假设您有一个Car这样的界面: public interface Car { public Engine getEngine(); // required public Transmission getTransmission(); // required public Stereo getStereo(); // optional } 正如评论所暗示的,a Car必须具有Engineand,Transmission而a Stereo是可选的。这意味着可以build()将Car实例创建的Builder 仅应在已将和都指定给该Builder实例的情况下才具有build()方法。这样,类型检查器将拒绝编译任何尝试在不使用or 的情况下创建实例的代码。EngineTransmissionCarEngineTransmission 这需要一个步骤构建器。通常,您将实现以下内容: public interface Car { public Engine getEngine(); // required public Transmission getTransmission(); // required public Stereo getStereo(); // optional public class Builder …

3
在类构造函数中注入数据(相对于行为)意味着什么,为什么这被认为是不好的做法?
我正在阅读Remo Jansen的书“ Learning TypeScript”。在一个部分中,作者描述了如何创建一个非常简单的概念验证MVC框架,包括如何创建Model类,并说了以下几点: 需要向模型提供其使用的Web服务的URL。我们将使用一个名为ModelSettings的类装饰器来设置要使用的服务的URL。我们可以通过其构造函数注入服务URL,但通过类构造函数注入数据(与行为相反)被认为是一种不好的做法。 我不明白那句话。特别是,我不明白“注入数据”的含义。在我看来,在几乎所有使用过度简化示例的JavaScript类介绍中,数据都是通过其参数引入(“注入”?)到构造函数中的。例如: class Person { constructor(name) { this.name = name; } } 我当然想到 name是数据,而不是行为,并且在此类示例中普遍将其作为构造函数参数包含在内,并且从未有人提到这是不好的做法。因此,我认为我误解了上面引用中的某些内容,无论是“数据”还是“注入”或其他含义。 您的答案可能包括在JavaScript / TypeScript中何时,何地,如何以及为什么使用装饰器的解释,因为我强烈怀疑该概念与我寻求的理解密切相关。但是,更重要的是,我想更广泛地理解通过类构造函数注入数据的含义以及为什么这样做很糟糕。 为了使上面的引用有更多的上下文,这是这种情况:Model创建了一个类,在本示例中,该类将用于创建股票交易模型,一个用于NASDAQ,一个用于NYSE。每个模型都需要提供原始数据的Web服务或静态数据文件的路径。该书指出,应该使用装饰器(而非构造器参数)获取此信息,从而导致以下结果: @ModelSettings("./data/nasdaq.json") class NasdaqModel extends Model implements IModel { constructor(metiator : IMediator) { super(metiator); } ... } 我只是一直不明白为什么我应该通过装饰器而不是简单地作为构造函数的参数来添加服务网址,例如 constructor(metiator : IMediator, serviceUrl : string) {...

3
会议时间和节省开发时间之间是否存在相关因素?
我正在研究一个项目,我们定期(通常每周一次)召开非正式会议,讨论该项目的状态及其GUI。 我是那里唯一的开发人员,其他4-5个人具有非IT背景。 这次会议花了比平常更长的时间,但是有一次,我的一位同事询问了计划中的某些领域以及如何填补这些领域。我回答并在讨论中发现,我完全错觉了这个过程。 但是由于我们已经讨论过并且事先发现了错误,所以我可以很快地对其进行更改。 在考虑这一点时,我问自己,在节省开发时间方面,在会议时间之间是否存在因素? 例如,1分钟的会议时间可能节省X分钟的开发时间。 如果是这样,这将有助于定义我们的会议应该举行的频率和时间。 (只是为了澄清:我不想召开更好的会议,即使能够大致确定会议的时间也是可有可无的。如果会议时间和开发时间之间存在联系,我最感兴趣的就是我。我的理由是:好奇心! )

3
为什么“ make”中的增量构建不使用哈希算法?
我是的初学者,make我想知道何时使用make clean。 一位同事告诉我,增量构建make基于文件时间戳。因此,如果您在VCS中签出文件的旧版本,则它将具有“旧”时间戳,并将其标记为“无需重新编译此文件”。然后,该文件将不会包含在下一个版本中。 根据同一位同事的说法,这是使用的理由make clean。 无论如何,我make clean从其他StackExchange问​​题中大致得到了“何时使用” 问题的答案,但是我的另一个问题是: 为什么使用make依赖文件时间戳而不是例如SHA-1进行增量构建?例如,Git显示我们可以成功确定是否使用SHA-1修改了文件。 是为了速度问题吗?
10 builds  make 

2
有没有一种优雅的方法来检查域对象属性上的唯一约束,而又不将业务逻辑移入服务层?
我已经适应领域驱动设计大约8年了,即使经过了这些年,仍然有一件事困扰着我。那就是针对域对象检查数据存储中的唯一记录。 2013年9月,马丁·福勒(Martin Fowler)提到了TellDon'tAsk原则,如果可能的话,应将其应用于所有领域对象,然后应返回一条消息,说明操作如何进行(在面向对象的设计中,这通常是通过异常来完成的,操作失败)。 我的项目通常分为许多部分,其中两个部分是“域”(包含业务规则,没有其他内容,该域完全不考虑持久性)和“服务”。知道用于CRUD数据的存储库层的服务。 由于属于对象的属性的唯一性是域/业务规则,因此对于域模块来说应该很长,因此该规则正是它应该在的位置。 为了能够检查记录的唯一性,您需要查询当前数据集(通常是数据库),以查明是否存在另一个假设的记录Name。 考虑到域层对于持久性是无知的,并且不知道如何检索数据,而只知道如何对它们进行操作,因此它无法真正地访问存储库本身。 我一直在适应的设计如下所示: class ProductRepository { // throws Repository.RecordNotFoundException public Product GetBySKU(string sku); } class ProductCrudService { private ProductRepository pr; public ProductCrudService(ProductRepository repository) { pr = repository; } public void SaveProduct(Domain.Product product) { try { pr.GetBySKU(product.SKU); throw Service.ProductWithSKUAlreadyExistsException("msg"); } catch (Repository.RecordNotFoundException e) { // suppress/log …

1
为什么不能在Mercurial中认真执行Pull Request?
一周前,我曾在LFNW上,谈话后正与Larry Hastings交谈时,他说(释义): Git中的某些功能使Mercurial中不存在的Pull Request工作流成为可能。这就是为什么BitBucket上的Pull Request不好用的原因。 (就上下文而言,我们正在讨论的事实是,由于PR工作流程,而不是file-bug-then-attach-patch工作流程,Python正在从Mercurial迁移到Git。) 他在这里说什么?我们俩都想不出任何名字。我没有在网上搜索过。

3
使用接口进行松耦合代码
背景 我有一个项目,该项目取决于某种类型的硬件设备的使用情况,但是只要该硬件设备执行我需要的操作,则由谁来制造该硬件设备并不重要。话虽这么说,即使两个本来应该做同样事情的设备,如果不是由同一家制造商生产的,它们也会有差异。因此,我正在考虑使用一个接口将应用程序与所涉及设备的特定制造商/型号分离开,而使该接口仅涵盖最高级别的功能。这就是我在想我的体系结构的外观: 在一个C#项目中定义一个接口IDevice。 在另一个C#项目中定义的库中有一个具体的东西,它将用来表示设备。 有具体的设备实现IDevice接口。 该IDevice接口可能具有类似GetMeasurement或的方法SetRange。 使应用程序了解具体的知识,并将具体的知识传递给利用(而非实现)IDevice设备的应用程序代码。 我非常确定这是正确的做法,因为这样我就可以在不影响应用程序的情况下更改正在使用的设备(这似乎有时会发生)。换句话说,具体的实现方式GetMeasurement或SetRange实际操作方式并不重要(设备制造商之间可能会有所不同)。 我唯一的疑问是,现在应用程序和设备的具体类都依赖于包含IDevice接口的库。但是,这是一件坏事吗? 我也看不到应用程序不需要知道设备的方式,除非设备与设备IDevice位于相同的名称空间中。 题 这似乎是实现接口以解耦应用程序与所使用设备之间的依赖关系的正确方法吗?

4
我编写的每个类都应该坚持一个接口吗?
我正在用Typescript编写游戏,并决定继续尝试坚持“ 基于接口的编程 ” 的思想,在该思想中,您基于对象的接口而不是实现来编写代码。 我写了很多接口和实现它们的类,然后退后一步,意识到这些类足够简单,以至于我可能永远不需要更改实现,因为实际上只有一种方法可以完成班级确实做到了(Phaser.Sprite以受限方式移动坦克就像坦克一样)。 然后,我记得几年前读过有关YAGNI的想法,这基本上是您不应过度设计代码以包含您可能永远不会使用的东西。 遵循最佳实践,每个类都应该实现一个接口,还是应该将其限制为您希望将来可能替换掉的类?

3
在对称下唯一生成nxnxn立方晶格中所有m个点的集合的算法
我正在实现一个算法,该算法将在计算上非常复杂,并且想要尝试确保我没有做不必要的工作。 有一个nxnxn立方晶格,例如,如果n = 2,则由(0,0,0),(0,1,0),(1,0,0),(1,1,0),(0, 1,1),(0,0,1),(1,0,1),(1,1,1)。 从这个格子中,我将递归地生成所有m点的集合,例如: solve(set_of_points) { if set_of_points.size = m, finish do some useful computation here for each point in lattice not in set_of_points: solve(set_of_points + new_point); } 然后可以从一个空的set_of_points开始调用。 问题的本质是,我实际上不需要m个点的所有排列,而只需要在立方体自然对称下唯一的那些点。 例如,拿一个2x2x2的多维数据集,并假设我们希望所有1点的集合。在以上基本算法下,有8个不同的1点集。 但是,使用立方体的对称性,我们可以将其减少到1个唯一的1点集,因为在立方体的对称性下所有原始的8个点都是等效的(在这种情况下,它们都是“角”)。 如果立方体是2x2x2且m = 2,则基本算法中有28个集合,但是在对称情况下,该集合减少为3个(例如{(0,0,0),(1,0,0)},{(0 ,0,0),(1,1,0)},{(0,0,0),(1,1,1)}) 显然,对3个点集进行计算要比28个点好得多,所以我的问题是如何不生成与已经生成的点对称对称的点集?或者,如果这不可能,那么我如何至少减少套数。 (请注意-如果m = 1,这相对容易-只需选择比其他任何一个顶点更接近(0,0,0)的点,并且边界处会有一点毛刺。这是因为m> 1成为一个真正的问题)

3
确保不意外使用不安全的代码
函数f()将eval()我创建并存储在local_file运行程序的计算机上的数据使用(或存在危险): import local_file def f(str_to_eval): # code.... # .... eval(str_to_eval) # .... # .... return None a = f(local_file.some_str) f() 安全运行,因为我提供的字符串是我自己的。 但是,如果我决定将其用于不安全的事物(例如用户输入),则可能会发生严重错误。另外,如果local_file停止在本地,则将创建漏洞,因为我需要信任也提供该文件的计算机。 如何确保我永远不会“忘记”该功能使用不安全(除非满足特定条件)? 注意:eval()很危险,通常可以用安全的东西代替。

3
责任分担后如何管理单一责任?
我有两堂课,Operation和Trigger。每个类都有许多专门用于某些类型的操作或触发器的子类。一个Trigger可以触发特定的Operation。虽然Operation可以由特定触发Trigger。 我需要编写将给定映射Operation到给定Trigger(反之亦然)的代码,但是我不确定将其放置在何处。 在这种情况下,代码显然不属于一个类或另一类。因此,就单一职责原则而言,我不确定代码应属于何处。 我可以看到三个选项都可以使用。虽然1和2似乎只是语义的选择,但3和3完全代表了一种不同的方法。 触发时,例如bool Triggers(Operation o)。 关于操作,例如bool TriggeredBy(Trigger t)。 在管理映射的全新类中,例如bool MappingExists(Trigger t, Operation o)。 我应该如何根据单一责任原则决定将共享映射代码放置在何处? 责任分担后如何管理单一责任? 编辑1。 因此,实际代码如下所示。所有属性,或者是一string,Guid,collection<string>,或enum。它们基本上只是代表一小部分数据。 编辑2。 返回布尔类型的原因。另一个类将使用Trigger和的集合Operation。它需要知道在Trigger和之间存在映射Operation。它将使用该信息来创建报告。

3
如果可以使用def重新定义变量,那么如何将其视为不可变的?
尝试学习Clojure会让您不停地被告知,Clojure是如何处理不可变数据的。但是您可以使用defright 轻松地重新定义变量?我知道Clojure开发人员可以避免这种情况,但是您可以避免在任何语言中都一样地更改变量。有人可以向我解释这有什么不同,因为我认为我正在阅读的教程和书籍中缺少此内容。 举个例子 a = 1 a = 2 在Ruby(或blub,如果您愿意)中与 (def a 1) (def a 2) 在Clojure中?
10 clojure 

5
使用编译时值参数生成Java类
考虑一个类实现相同的基本行为,方法等的情况,但是该类可能存在多种不同版本以用于不同用途。在我的特定情况下,我有一个向量(一个几何向量,而不是一个列表),并且该向量可以应用于任何N维欧几里德空间(1维,2维等)。如何定义此类/类型? 在C ++中,这很容易,因为C ++中的类模板可以将实际值作为参数,但是在Java中我们没有那么奢侈。 我可以想到的解决该问题的两种方法是: 在编译时实现每种可能的情况。 public interface Vector { public double magnitude(); } public class Vector1 implements Vector { public final double x; public Vector1(double x) { this.x = x; } @Override public double magnitude() { return x; } public double getX() { return x; } } public class …

2
Python的继承是“ is-a”继承样式还是组合样式?
考虑到Python允许多重继承,Python中的惯用继承是什么样的? 在具有单一继承的语言(例如Java)中,当您可以说一个对象是另一个对象的“是”并且想要在对象之间共享代码(从父对象到子对象)时,将使用继承。例如,您可以说这Dog是一个Animal: public class Animal {...} public class Dog extends Animal {...} 但是由于Python支持多重继承,我们可以通过将许多其他对象组合在一起来创建对象。考虑下面的示例: class UserService(object): def validate_credentials(self, username, password): # validate the user credentials are correct pass class LoggingService(object): def log_error(self, error): # log an error pass class User(UserService, LoggingService): def __init__(self, username, password): self.username = username self.password = password …

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.