软件工程

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

3
制作图像镶嵌的算法-有比这更快的方法吗?
我一直在玩制作图像马赛克。我的脚本拍摄了大量图像,将它们缩小为缩略图大小,然后将它们用作平铺以逼近目标图像。 该方法实际上非常令人愉快: 我计算每个图块位置中每个拇指的均方误差。 起初,我只是使用贪婪的放置方式:将误差最小的拇指放在最适合的图块上,然后放置下一个,依此类推。 贪婪的问题在于,无论它们是否紧密匹配,最终都会让您最终将最不相同的指尖放在最不受欢迎的图块上。我在这里显示示例:http : //williamedwardscoder.tumblr.com/post/84505278488/making-image-mosaics 因此,我然后进行随机交换,直到脚本被中断。结果还可以。 随机交换两个图块并不总是一种改进,但是有时三个或更多图块的旋转会导致整体改进,即A <-> B可能不会改进,但A -> B -> C -> A1可能会。 因此,在选择了两个随机图块并发现它们没有改善之后,我选择了一堆图块来评估它们是否可以成为这种旋转中的第三个图块。我不探讨是否可以使四个图块中的任何一组进行有利可图的旋转,等等。很快就会变得非常昂贵。 但这需要时间。。很多时间! 有没有更好,更快的方法? 赏金更新 我测试了匈牙利方法的各种Python实现和绑定。 到目前为止最快的是纯Python https://github.com/xtof-durr/makeSimple/blob/master/Munkres/kuhnMunkres.py 我的直觉是,这近似于最佳答案。当在测试映像上运行时,所有其他库都对结果达成了共识,但是这个kuhnMunkres.py虽然快了几个数量级,但是却非常非常接近其他实现所同意的分数。 速度与数据密切相关;蒙娜丽莎(Mona Lisa)在13分钟内冲过kuhnMunkres.py,但猩红胸鹦鹉(Scarlet Chested Parakeet)花了16分钟。 结果与长尾小鹦鹉的随机互换和轮换非常相似: (左侧为kuhnMunkres.py,右侧为随机交换;用于比较的原始图像) 但是,对于我测试过的《蒙娜丽莎》图像,结果得到了明显改善,实际上,她定义的“微笑”闪闪发光: (左侧为kuhnMunkres.py,右侧为随机交换)

4
修改自身后,类的方法何时应返回相同的实例?
我有一个具有三个方法的类A(),B()并且C()。这些方法修改了自己的实例。 当实例必须是一个单独的副本时,方法必须返回一个实例(与一样Clone()),但是在修改方法中的同一实例而不返回任何其他值时,我可以自由选择返回void还是相同的实例(return this;)。 在决定返回相同的修改实例时,我可以进行整洁的方法链,例如obj.A().B().C();。 这是这样做的唯一理由吗? 修改自己的实例并返回它还可以吗?还是应该只返回副本并像以前一样保留原始对象?因为当返回相同的修改实例时,用户可能会假定返回的值是副本,否则将不会返回?如果可以的话,在方法中阐明此类问题的最佳方法是什么?

1
菜单构建模式
当菜单不用于路由时,我难以理解菜单的活动状态处理。 我来自Drupal,菜单系统也处理路由。因此,设置活动状态和活动尾随状态由路由处理(也充当菜单渲染系统)。 现在,许多PHP框架都有处理路由的Router类。这似乎是一个很好的分隔,因为菜单不应该知道POST ||。选项|| ... 要求。 但是在编写前端时,我发现自己很难对菜单进行编码。或者将所有内容存储在数据库中,然后将这些值传递给视图。我不喜欢这种方法的原因是您正在创建已经在Router中写过的内容的副本,但是现在使用Menu类。 一个例子: Route::get('/somewhere','routename.somewhere','showStuffController'); Route::post('/somewhere','routename.somewhere','saveStuffController'); Menu::add('label.somewhere','routename.somewhere'); 您在这里分离关注点,所以很好。但是Menu在很大程度上取决于Route来设置其活动状态。菜单还必须了解有关设置活动跟踪的层次结构。 因此,是的,设置活动路径和活动状态类实际上是一种视图。但是有 if ( Route::currentName() === $menuitem->getRouteName() ) { print 'active'; } 您的所有观点看来都是愚蠢的。然后添加所有那些烦人的活动提示if,这确实是个肿。我知道,在视图渲染之前处理该问题并将active-trail标志设置为true似乎很丑陋(foreach遍历所有子级,遍历所有子级,...) 我的问题是: 有没有一种模式或聪明的方法来使这种清洁剂变得更好,更好……?一个人应该如何应对主动式“问题”? 我当时想渲染子级->父级。因此,从最深层次的广告开始,然后逐步发展。但是,孩子对父母一无所知,但父母对孩子一无所知(似乎很奇怪)。

1
测试单元与集成之间的差距:小型,组件,单元集成测试中的集成
在过去的几周中,我一直在研究和研究如何填补我们的测试方法中的空白。简而言之,单元测试太小,而传统的集成测试太大。 经常出现的情况是A,B两者都使用component C。但是A,B对的要求略有不同,并且对做出略有不同的假设C。如果我是A如何以及在哪里测试我的假设的开发人员C? 显然,A带有模拟假设的单元测试C可以很好地进行A隔离测试,但是它不能测试假设本身。 另一种可能性是为添加单元测试C。但是,这不是理想的,因为A在开发过程中,C根据不断变化的假设更改测试A将非常笨拙。确实,A开发人员甚至可能没有足够的权限访问C(例如,外部库)的单元测试。 用一个更具体的例子来说明这一点:假设这是一个节点应用程序。 A,并B依赖于C读取文件(以及其他内容)并将文件内容存储在传递给的对象中C。最初,所有C处理的文件都很小,可以同步读取而不会产生明显的阻塞。但是,的开发人员B意识到他的文件越来越大,需要切换C到异步读取。这会导致中出现零星的同步错误A,该错误仍假定C是正在同步读取文件。 众所周知,这种错误很难从完整的集成测试中找到,并且根本不会在集成测试中发现。它也不受As单元测试的影响,因为As的假设是模拟的。但是,可以通过“ just” A和“ C。”行使的“迷你”集成测试轻松抓住它。 我只找到了关于这种测试的一些参考。小型集成,组件集成测试,单元集成测试。它还与BDD测试的方向有关,而不是正式的TDD单元测试。 如何填补这个测试空白?具体来说-我应该在哪里进行此类测试?如何嘲笑的投入A,并C为“迷你型”集成测试?在分离这些测试和单元测试之间的测试关注点上应该付出多少努力?还是有更好的方法来填补测试空白?

4
在C中省略“析构函数”是否会使YAGNI过分?
我正在使用类似于OO的技术来开发C中的嵌入式媒体应用程序。我的“类”是.h / .c模块,它们使用数据结构和函数指针结构来模拟封装,多态和依赖项注入。 现在,人们期望一个myModule_create(void)功能会与之myModule_destroy(pointer)对应。但是,在嵌入的项目中,切勿释放实际实例化的资源。 我的意思是,如果我有4个UART串行端口,并使用所需的引脚和设置创建4个UART实例,则绝对没有理由要在运行时的某个时候销毁UART#2。 因此,遵循YAGNI(您将不需要它)原则,我应该省略析构函数吗?这对我来说似乎很奇怪,但我想不出对他们有什么用。设备下电后释放资源。

3
用于定义命名函数的重复语法是否会成为错误的语言设计决策?
我正在为有趣的编程语言建模,并且语法在很大程度上受Scala的影响-特别是函数定义。 我遇到了一个设计问题,因为我的语言无法区分通过def语法定义的函数(类方法)和分配给值的匿名函数(使用创建的值=>)-它消除了实现和行为上的差异。 结果是以下两个定义含义相同: def square(x: Int) = x*x val square = (x: Int) => x*x 没有任何理由在任何正常情况下都使用后一种形式(立即匿名函数赋值)- 可以使用它代替def形式。 具有用于定义命名函数的重复语法是否会损害语言或其他设计方面的正交性? 我更喜欢这种解决方案,因为它允许对方法和命名函数进行简短直观的定义(通过def),以及对匿名函数进行简短定义(使用=>)。 编辑:Scala 确实区分了两者 -匿名函数与defScala中定义的方法不同。不过,差异相对较细微-请参阅我之前链接的帖子。

6
拆分大型接口
我正在使用一个带有大约50种方法的大型接口来访问数据库。该界面是由我的一位同事编写的。我们讨论了这一点: 我:50种方法太多了。这是代码气味。 同事:我该怎么办?您需要数据库访问权限-您拥有它。 我:是的,但是目前还不清楚,将来很难维护。 同事:好的,您是对的,不好。界面应该如何? 我:有5种方法返回的对象各有10种方法怎么样? 嗯,但这不一样吗?这真的会导致更加清晰吗?值得付出努力吗? 我时不时地处于需要界面的情况,而想到的第一件事就是一个大型界面。是否有通用的设计模式? 更新(响应SJuan的评论): “种类的方法”:它是用于从数据库中获取数据的接口。所有方法都具有形式(伪代码) List<Typename> createTablenameList() 方法和表并不完全是1-1关系,而是更多地关注您总是从数据库中获得某种列表的事实。

4
.NET的IObserver <T>是否打算订阅多个IObservable?
.NET中也有IObservable和IObserver接口(也在此处和此处)。有趣的是,IObserver的具体实现并没有直接引用IObservable。它不知道订阅了谁。它只能调用取消订阅者。“请拉销以退订。” 编辑:取消订阅者实现IDisposable。我认为,采用这种方案是为了防止监听程序失效。 但是,有两件事对我来说并不完全清楚。 内部的Unsubscriber类是否提供“订阅并忘记”行为?谁(确切地说是何时)致电IDisposable.Dispose()取消订阅者?垃圾收集器(GC)不确定。 [免责声明:总体而言,与C#相比,我在C和C ++上花费的时间更多。] 如果我要向观察者K订阅可观察的L1并且观察者已经订阅了其他一些可观察的L2,应该怎么办? K.Subscribe(L1); K.Subscribe(L2); K.Unsubscribe(); L1.PublishObservation(1003); L2.PublishObservation(1004); 当我针对MSDN的示例运行此测试代码时,观察者仍然订阅L1。这在实际开发中将是特殊的。可能有3种方法可以改善此问题: 如果观察者已经有一个取消订阅者实例(即它已经订阅了),那么在订阅一个新的提供者之前,它会悄悄地取消订阅原始提供者。这种方法掩盖了一个事实,即它不再订阅原始提供程序,这以后可能会感到惊讶。 如果观察者已经具有取消订阅者实例,则将引发异常。行为规范的调用代码必须显式取消订阅观察者。 观察者订阅了多个提供者。这是最吸引人的选项,但是可以使用IObservable和IObserver来实现吗?让我们来看看。观察者可以保留一个非订户对象列表:每个源一个。不幸的是,IObserver.OnComplete()没有提供回发给提供者的参考。因此,具有多个提供程序的IObserver实现将无法确定要取消订阅的提供程序。 .NET的IObserver是否打算订阅多个IObservable? 教科书对观察者模式的定义是否要求一个观察者必须能够订阅多个提供者?还是可选的并且依赖于实现?


1
如何分别解析多部分字段/文件数据?
我想两次解析一个多部分的表单:一次获取传入的字段,然后解析文件上传。 我正在尝试在Node应用程序中保持适当的关注点分离: 控制器负责处理传入字段。 模型负责上传文件的逻辑。 我需要将字段数据传递到模型中以创建新实例,因此在文件上传开始之前,字段数据需要可用。 当前,每个form.parse()或等效函数都将字段和文件解析在一起。示例:一起req.pipe(busboy)处理文件和字段。 我已经检查了节点多方,强大,busboy,multer之类的模块。似乎没有人对此有解决方案。 我想要实现的示例在这里:https : //stackoverflow.com/questions/22336177/node-js-busboy-parse-fields-and-files-seperatly 这有可能吗?
9 data  node.js  upload 

2
是否应该将事件侦听器设置为弱引用?
通常,事件侦听器不应超出注册它们的对象的寿命。 这是否意味着事件侦听器默认情况下应由弱引用持有(由对象侦听器存储在弱集合中进行注册)? 是否存在有效的情况,使听众的生命力超越其创造者? 又或者像这样的情况是一个错误,不应允许?

1
在API和应用程序之间共享对象的模式
我对我的Web应用程序的设计有严重的怀疑。 我想将业务逻辑与接口分开,所以我制作了一个Web API,用于处理对数据库的所有请求。 它是具有实体框架,工作单元和通用存储库模式的ASP.NET Web API。到目前为止,一切都很好。 问题 我需要帮助的地方是,我找不到在API和应用程序之间共享对象的有效方法。 我不想直接序列化实体对象,我认为这将是一个坏习惯,因为如果实体模型发生更改,我最终可能会无缘无故地序列化大型对象。 现在如何实施 因为我的接口是C#中的ASP.NET Web应用程序,而我的API是C#中的API,所以我创建了一个公共库,其中定义了我想在它们之间共享的所有类。 我知道当我开发一个Android应用程序时该解决方案将不起作用,我将不得不再次用Java创建类,但这不是我最大的问题。 问题是我感觉自己一直在转换对象。 例 这是我的工作流程示例: 我从包含所有对象和表单数据注释的模型开始,然后用户将模型发布到控制器。 在控制器中,我必须将此模型转换为我的公共库中的类,然后将该对象发送到我的API。 然后,我的API中的控制器捕获了该调用,并将该对象转换为实体对象以更新数据库。 所以我有3节课 视图的模型以及用于验证的所有数据注释(客户端) 共享对象的公共库类(DLL) 实体类(API) 我感觉自己做错了什么。还有更优雅的东西吗?我想确保在这个项目变得太大之前,我有一个很好的解决方案。

3
是否存储可编辑的网站内容?
我们有一个基于Django的网站,我们希望对其内部一些内容(文本和诸如定价计划之类的业务逻辑)进行轻松地编辑,因此我们决定将其存储在代码库之外。通常原因是以下之一: 这是非技术人员想要编辑的东西。一个示例是网站的文案写作-程序员使用默认值为“ Lorem ipsum ...”的文本准备一个模板,然后将实际内容插入到数据库中。 我们希望能够快速进行更改,而无需部署新代码(我们目前每周执行两次)。一个示例是当前以不同定价级别向客户提供的功能。无需对它们进行硬编码,而是从数据库中读取它们。 所描述的解决方案是灵活的,但是出于某些原因我不喜欢它。 因为必须从数据库读取内容,所以会产生性能开销。 我们通过使用缓存方案来减轻这种情况,但这也增加了系统的复杂性。 与在生产环境上运行的方式相比,在本地运行代码的开发人员看到的系统处于截然不同的状态。自动化测试还会使系统处于不同的状态。诸如在登台服务器上测试新功能之类的情况也变得更加棘手-如果登台服务器没有数据库的最新副本,则它可能与生产意外地不同。 我们可以通过偶尔将新状态提交到存储库(例如通过添加数据迁移)来缓解这种情况,但这似乎是错误的方法。是吗? 任何想法如何最好地解决这些问题?有没有更好的方法来处理我忽略的内容?

4
这种方法纯吗?
我有以下扩展方法: public static IEnumerable&lt;T&gt; Apply&lt;T&gt;( [NotNull] this IEnumerable&lt;T&gt; source, [NotNull] Action&lt;T&gt; action) where T : class { source.CheckArgumentNull("source"); action.CheckArgumentNull("action"); return source.ApplyIterator(action); } private static IEnumerable&lt;T&gt; ApplyIterator&lt;T&gt;(this IEnumerable&lt;T&gt; source, Action&lt;T&gt; action) where T : class { foreach (var item in source) { action(item); yield return item; } } 它只是在返回序列之前对序列的每个项目执行操作。 我想知道是否应该将Pure属性(来自Resharper注释)应用于此方法,并且可以看到支持和反对该参数的参数。 优点: …

6
大量的时间,我想不出拥有对象而不是静态类的理由。对象有比我想象的更多的好处吗?[关闭]
已关闭。这个问题需要更加集中。它当前不接受答案。 想改善这个问题吗?更新问题,使其仅通过编辑此帖子来关注一个问题。 5年前关闭。 我了解对象的概念,作为Java程序员,我觉得OO范式在实践中自然而然地出现在我身上。 但是最近我发现自己在想: 等等,使用对象比使用静态类(具有适当的封装和OO做法)实际具有哪些实际好处? 我可以想到使用对象的两个好处(既重要又强大): 多态性:允许您在运行时动态灵活地交换功能。还可以轻松为系统添加新功能“零件”和替代品。例如,如果有一个Car设计用于处理Engine对象的类,并且您想向Car可以使用的系统中添加一个新的Engine,则可以创建一个新的 Engine子类并将该类的Car对象简单地传递给该 对象,而不必改变一切Car。您可以在运行时决定这样做。 能够“传递功能”:您可以动态地在系统中传递对象。 但是与静态类相比,对象还有更多优势吗? 通常,当我向系统添加新的“部件”时,我会通过创建新类并从中实例化对象来实现。 但是最近,当我停下来想一想时,我意识到在很多我通常使用对象的地方,静态类将与对象相同。 例如,我正在为我的应用程序添加一个保存/加载文件机制。 对于一个对象,代码的调用行将如下所示: Thing thing = fileLoader.load(file); 对于静态类,它看起来像这样: Thing thing = FileLoader.load(file); 有什么不同? 通常,当普通的静态类的行为相同时,我只是想不出实例化对象的理由。但是在OO系统中,静态类很少见。所以我一定想念一些东西。 除了上面列出的两个对象以外,对象还有其他优点吗?请解释。 编辑:澄清。在交换功能或传递数据时,我确实发现对象非常有用。例如,我写了一个组成旋律的应用程序。MelodyGenerator有几个不同的子类创建旋律,并且这些类的对象是可互换的(策略模式)。 旋律也是对象,因为传递它们很有用。和弦和音阶也是如此。 但是,系统的“静态”部分又将如何传递呢?例如-一种“保存文件”机制。为什么要在对象而不是静态类中实现它?

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.