软件工程

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

5
如何实现RealNumber和ComplexNumber继承?
希望不是太学术... 假设我的SW库中需要实数和复数。 根据is-a(或here)关系,实数是复数,其中复数虚部中的b就是0。 另一方面,我的实现是,该子对象扩展父对象,因此在父对象RealNumber中,我将拥有实部,而子对象ComplexNumber将添加虚构图。 还有一种观点认为继承是邪恶的。 我记得像昨天一样,当我在大学学习OOP时,我的教授说,这不是继承的一个很好的例子,因为这两者的绝对值是用不同的方式计算的(但为此我们有方法重载/多态主义,对吗?)。 。 我的经验是,我们经常使用继承来解决DRY,因此,我们经常在层次结构中人工构造抽象类(由于名称不能代表真实世界中的对象,因此经常很难找到名称)。

4
乐观锁定不起作用怎么办?
我有以下这种情况: 用户向GET请求/projects/1并接收ETag。 用户从步骤1 开始使用ETag 进行PUT请求/projects/1。 用户/projects/1从步骤1 开始使用ETag 发出另一个PUT请求。 通常,第二个PUT请求将收到412响应,因为ETag现在已过时-第一个PUT请求修改了资源,因此ETag不再匹配。 但是,如果同时发送两个PUT请求(或者一个又一个发送)怎么办?在PUT#2到达之前,第一个PUT请求没有时间处理和更新资源,这导致PUT#2覆盖PUT#1。乐观锁定的全部目的是要避免这种情况的发生。

2
DDD中的例外
我正在学习DDD,并且正在考虑在某些情况下引发异常。我知道对象不能进入错误状态,因此这里的异常很好,但是在许多示例中,例如,如果我们尝试使用数据库中存在的电子邮件添加新用户,也会抛出异常。 public function doIt(UserData $userData) { $user = $this->userRepository->byEmail($userData->email()); if ($user) { throw new UserAlreadyExistsException(); } $this->userRepository->add( new User( $userData->email(), $userData->password() ) ); } 因此,如果存在使用此电子邮件的用户,那么我们可以在应用程序服务中捕获异常,但我们不应该使用try-catch块来控制应用程序的操作。 最好的方法是什么?

4
如何包装服务,使其更简单
我们依赖于第三方服务,该服务公开了一个巨大的接口,我们只需要像3种方法。此外,界面经常更改... 我决定将接口包装在我们项目的一个类中,只公开我们需要的方法。 但是我不确定如何处理返回值...接口返回类型为的对象Storage。我们内部有一个类型StorageModel,它是a的内部表示形式Storage。 您将在映射器中返回什么:Storage或StorageModel?我们有一个DataService StorageService,它获得了注入的包装的依赖关系。 目前,我基本上是这样的: public class StorageService { private readonly IExternalStorageWrapper externalStorageWrapper; public StorageService(IExternalStorageWrapper externalStorageWrapper) { this.externalStorageWrapper = externalStorageWrapper; } public StorageModel GetStorage(int storageId) { return this.externalStorageWrapper.GetStorage(storageId).ConvertToStorageModel(); } } public class ExternalStorageWrapper : IExternalStorageWrapper { public Storage GetStorage(int storageId) { using(var ext = new ExternalStorage()) { return ext.GetStorage(storageId); …

6
实体方法调用上的DDD注入服务
问题的简短格式 在DDD和OOP的最佳实践中,是否可以在实体方法调用上注入服务? 长格式示例 假设我们在DDD中有一个经典的Order-LineItems案例,其中有一个称为Order的域实体,它也充当聚合根,并且该实体不仅由其Value Objects组成,而且还包含Line Item的集合实体。 假设我们希望在应用程序中使用流利的语法,以便我们可以做类似的事情(请注意第2行中的语法,在此称为getLineItems方法): $order = $orderService->getOrderByID($orderID); foreach($order->getLineItems($orderService) as $lineItem) { ... } 我们不想将任何LineItemRepository注入OrderEntity,因为这违反了我能想到的几个原则。但是,语法的流畅性是我们真正想要的,因为它易于阅读和维护以及测试。 考虑下面的代码,指出该方法getLineItems中OrderEntity: interface IOrderService { public function getOrderByID($orderID) : OrderEntity; public function getLineItems(OrderEntity $orderEntity) : LineItemCollection; } class OrderService implements IOrderService { private $orderRepository; private $lineItemRepository; public function __construct(IOrderRepository $orderRepository, ILineItemRepository $lineItemRepository) { $this->orderRepository …

6
是拉要求培训青年的地方
我们有一个概念,即向主请求请求中的所有代码都应准备好生产。这是有道理的,我认为这是一个公正的声明。 这里的想法是,一旦创建了PR,就说明您已经将它放到了主控器中,但是希望某些审稿人仅与您“同意”,并发现您碰巧遇到的任何问题。 由于我们只是人,所以我们会犯错,并希望其他审阅者可以找到单元测试找不到的项目-拼写错误,不正确的javadocs等。 但是,“拉取请求”是我们应该向开发人员提供某种程度的帮助/培训的地方,如果需要,应该达到什么程度? 每次您推送新更改时,审阅者都必须重新审阅您的更改,这要花费他们的开发时间,并导致重新审阅更改。 因此,在请求请求中应该允许接受多少培训?我的一部分感到,这从大三到大四。但是,我也觉得这里不应该是发现大量问题的地方-即使对于初中生也是如此。 是否还有其他人在努力使开发人员实现“我的拉取请求应该准备好生产”的目标?

3
在Python 3.4+中,为什么不使用dict时,为什么我应该在SimpleNamespace上使用namedtuple,它们看起来非常相似
在某一点上,您可能会遇到带有很多参数的函数。有时将一些参数组合成超级参数是有意义的。我经常用字典来做,但是现在我正在寻找更好的做事方法。 我想转身... def do_something(ax, ay, az, bu, bv, c): # Do something ...进入... def do_something(a, b, c): # Do something ... a并b包含其子变量。 一种方法是执行以下操作: A = namedtuple('A', 'x, y, z') a = A(ax, ay, az) B = namedtuple('B', 'u, v') b = B(bu, bv) 但是,这似乎更简单: a = SimpleNamespace(x=ax, y=ay, z=az) b …

2
评估是先在蓝天/原型项目上编写单元测试还是集成测试
我最近注意到的是,当我执行以下类型的项目时: 开始项目时 处理MVP /原型 添加未完全定义的功能 从事较小规模的项目 作为参考,我正在研究一个Python项目,该项目目前有大约1k行代码,包括一些注释和所有空格。 我发现首先编写集成测试,处理代码,然后对API进行某种程度的加固后,实际上可以轻松地添加单元测试。可以说,我可以在我的main函数上运行的测试类型比其他任何东西都更“端到端”。 这是因为当API发生相当快速的更改时,单元测试确实很烦人,而在与以上任何或大多数条件匹配的项目上工作时,通常就是这种情况。 这种方法是否是一种好的方法,并且在针对这些类型的项目做出是否首先从单元测试或集成测试开始的决策时应考虑哪些标准?在API更加巩固之前,我是否错过了对这类项目进行单元测试的价值?

4
标记通过反射调用的方法的最佳实践?
我们的软件有几个类,应该通过反射来动态找到。这些类都有一个带有特定签名的构造函数,反射代码通过该签名实例化对象。 但是,当有人检查是否引用了该方法时(例如,通过Visual Studio Code Lens),则不计入通过反射进行的引用。人们可能会错过他们的引用,并删除(或更改)表面上未使用的方法。 我们应该如何标记/记录打算通过反射调用的方法? 理想情况下,应以同事和Visual Studio / Roslyn以及其他自动化工具都“看到”该方法旨在通过反射调用的方式进行标记。 我知道我们可以使用两个选项,但都不太令人满意。由于Visual Studio找不到引用,因此: 使用自定义属性,并使用此属性标记构造函数。 问题在于,属性属性不能是方法引用,因此构造方法仍将显示为具有0个引用。 不熟悉custom属性的同事可能会忽略它。 我当前方法的一个优点是反射部分可以使用该属性来查找应调用的构造函数。 使用注释来证明打算通过反射调用方法/构造函数。 自动化工具会忽略评论(同事也可能会忽略评论)。 XML文档注释可以用于具有Visual Studio计数的额外参考方法/构造: 让MyPlugin是它的构造经由反射调用的类。假设调用反射代码搜索采用int参数的构造函数。以下文档使代码透镜显示了具有1个引用的构造函数: /// <see cref="MyPlugin.MyPlugin(int)"/> is invoked via reflection 存在哪些更好的选择? 标记要通过反射调用的方法/构造函数的最佳实践是什么?


2
如何正确管理C / C ++项目的依赖关系?
我有一个使用3-4个不同的开源C / C ++库的项目。 我为多个平台构建了这些库,并在我的项目中检入了针对不同平台的包含文件和静态库。 但是,我遇到了两个问题。所有这些项目都与依赖项管理有关。我正在寻找最佳实践建议。 1)我怎么知道我到底使用什么? 我没有办法获得静态库的版本。结果,我需要以某种方式跟踪我正在使用哪个版本的静态库(可能是生成它的提交的SHA)? 当我需要确定何时升级这些库时,这一点尤其重要。 2)如何复制构建? 我可能很难为特定平台构建一些特定库。我花了一段时间才弄清楚。 下次需要构建相同的库可能需要半年时间(无论出于何种原因都需要升级。但是,到那时,我绝对不会记住任何东西以及构建它的环境将早已不复存在。 3)我应该分叉这些库以获取源代码的副本吗? 这是一个较小的问题。但是,这仍然是一个问题。确保构建是可复制的(这需要源代码)是一件很高兴的事。

1
创建一个好的问题陈述
<背景故事> 前几天,我在一家二手书店里买了一本叫做《代码完成》的书,因为我听说这是一本很棒的书,所以开始阅读。大约10页之后,我意识到自己对最近正在从事的项目感到有些愚蠢。在这一点上,我需要澄清一下:我没有工作,也不适合上学;它几乎是非正式的(尽管我偶尔也问过一些问题,但我也是唯一从事此工作的人)。我在中学时期,正在尝试创建一个软件。 长话短说,我直接进入了编码(现在我质疑当场就他的编码方式如何做出的一些决定)。因此,我正在尝试以正确的方式重新开始。 </背景故事> 好的,所以我正在尝试创建问题陈述,我想知道一些好的提示,以了解我是否有一个好的提示。Code Complete表示,这应该是非技术性的,并且从用户的角度来看,这是我试图做到的。任何建议,将使其更好。 据我所知,目前尚没有很好的方法来模拟大型复杂的量子计算电路,包括去相干,纠错,纠缠和经典计算机上的算法等功能,更不用说使用标准/井井有条的系统了。已知且易于访问。 抱歉,如果绝对如此,这是我第一次这样做。 编辑-草稿2: 我改写了评论和答案中的建议。 量子计算领域的理论家,研究人员和学生没有一种方法可以直接,高效地模拟和测试复杂的大型量子电路,而无需自己为应用创建代码。一个可以在流行的浏览器中运行的Web应用程序,其简单的界面可以准确地产生有关量子算法,纠错码,纠缠,退相干以及理想界面和实际界面的其他方面的结果,从而使专业人员和学生都可以测试他们的想法,并更好地了解量子计算领域。

2
应用程序服务层调用数据库功能。架构不好?
场景: 堆栈:Java,Spring,Hibernate。 型号:客户端-服务器应用程序。 模式:模型-视图-控制器(MVC)。 服务层类具有三种行为: 一些服务在方法内具有业务规则,并将持久性委托给应用程序。喜欢: EntityManager.save(entity); 一些服务只是调用数据库函数(传递参数),例如: CallableStatement cls = con.prepareCall(“ {call databaseFunction(args)}”); 某些服务同时具有两种行为的方法。 我的问题: 让应用程序服务直接调用数据库功能有什么问题吗?这不是不好的做法吗?适用于这样的项目的架构模型是什么? 在同一服务中混合行为是否有问题?如交易和一致性? 在维护的情况下,这种封装是否使开发人员不清楚他也应该更改数据库中的功能?如何避免这种情况? 这种情况是否会在世界各地的其他应用程序中发生,或者仅仅是架构错误?

3
在Java 8中,使用方法引用表达式或返回功能接口实现的方法在样式上是否更好?
Java 8添加了功能接口的概念,以及许多旨在采用功能接口的新方法。这些接口的实例可以使用方法引用表达式(例如SomeClass::someMethod)和lambda表达式(例如(x, y) -> x + y)来简洁地创建。 我和一位同事对什么时候最好使用一种或另一种形式(在这种情况下,“最佳”实际上可以归结为“最易读”和“最符合标准做法”)有不同的看法,因为他们基本上是相反的当量)。具体而言,这涉及以下所有情况: 所涉及的函数不在单个范围内使用 给实例起个名字有助于提高可读性(与之相反,例如,逻辑足够简单以一目了然地看到正在发生的事情) 没有其他编程原因可以解释为什么一种形式优于另一种形式。 我目前对此事的看法是,添加私有方法并通过方法引用进行引用是更好的方法。感觉这就是设计功能使用方式的方式,并且似乎更容易通过方法名称和签名传达正在发生的事情(例如,“ boolean isResultInFuture(Result result)”显然是在说要返回布尔值)。如果将来对类的增强希望使用相同的检查,但不需要功能接口包装器,则这也可使private方法可重用。 我的同事希望使用一种方法来返回接口的实例(例如“ Predicate resultInFuture()”)。对我而言,这感觉不完全是该功能的预期用途,感觉有点笨拙,而且似乎很难通过命名来真正传达意图。 为了使这个示例具体,下面是使用不同样式编写的相同代码: public class ResultProcessor { public void doSomethingImportant(List<Result> results) { results.filter(this::isResultInFuture).forEach({ result -> // Do something important with each future result line }); } private boolean isResultInFuture(Result result) { someOtherService.getResultDateFromDatabase(result).after(new Date()); } …

2
在MVVM中,ViewModel或View应该负责创建新视图吗?
在我的WPF应用程序中,我想创建一个新视图。在ViewModel或Model中应该在哪里做? 该应用程序是一个(现在非常简单)单窗口形式的工具,带有单个“发送”按钮。如果选中其中一个复选框,则应弹出使用相同ViewModel的新窗口,要求用户提供一些其他详细信息。出于这个问题的目的,我们只考虑新窗口方法,而不考虑显示/隐藏面板之类的其他方法。 理想情况下,在View中应该没有任何代码。此外,由于View中没有任何逻辑,因此VM最初需要检查是否需要创建新视图,并且-在需要时-将这种责任退还给View,从而导致代码膨胀。 另一方面,在ViewModel中创建新视图违反了ViewModel不应该了解View的原则。 因此,在View或ViewModel中创建新视图更好吗?
11 c#  design  wpf  mvvm 

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.