Questions tagged «anti-patterns»

反模式是尽管无效或适得其反却很常见的行为或做法。

6
用有意义的类名屏蔽Java集合的好坏方法?
最近,我习惯于用人类友好的类名“掩盖” Java集合。一些简单的例子: // Facade class that makes code more readable and understandable. public class WidgetCache extends Map<String, Widget> { } 要么: // If you saw a ArrayList<ArrayList<?>> being passed around in the code, would you // run away screaming, or would you actually understand what it is and what // …

8
代码维护:在扩展新代码时是否保持一致的错误模式?
我必须扩展项目的现有模块。我不喜欢它的完成方式(涉及很多反模式,例如复制/粘贴的代码)。由于多种原因,我不想执行完整的重构。 我是不是该: 使用现有约定创建新方法,即使我觉得错了,也可以避免对下一个维护者造成混淆并与代码库保持一致? 要么 尝试使用我感觉更好的方法,即使它在代码中引入了另一种模式? 精确度在第一个答案后进行了编辑: 现有的代码不是一团糟。很容易理解和理解。但是,它引入了许多可以通过良好设计避免的样板代码(结果代码可能会变得更难遵循)。在我当前的情况下,这是一个很好的旧JDBC(内置弹簧模板)DAO模块,但是我已经遇到了这个难题,我正在寻求其他开发人员的反馈。 我不想重构,因为我没有时间。而且即使有时间,也很难证明一个完整的正常工作的模块需要重构。重构成本将超过其收益。请记住:代码并不凌乱或过于复杂。我不能在那里提取一些方法并在这里介绍一个抽象类。这在设计中更是一个缺陷(我认为极端“保持愚蠢简单”的结果) 因此,也可以这样问这个问题: 作为开发人员,您是喜欢维护简单的愚蠢无聊的代码,还是希望有一些帮助程序来代替您的愚蠢无聊的代码? 最后一种可能性的缺点是,您必须学习一些知识,也许您还必须维护简单的愚蠢无聊代码,直到完成完整的重构为止)

11
错误变量是反模式还是好的设计?
为了处理不应停止执行的几种可能的错误,我有一个error变量,客户端可以检查并使用该变量引发异常。这是反模式吗?有没有更好的方法来解决这个问题?有关此操作的示例,您可以查看PHP的mysqli API。假定正确处理了可见性问题(访问器,公共和私有范围,是类中的变量还是全局变量?)。


5
从库中的STDIN读取是否被认为是反模式?
在为我正在工作的大型项目编写库时,出现了一个问题,该问题要求将令牌发送到电子邮件地址,然后传递回代码中,以供以后使用。 我的同事说,只是从STDIN中读取(使用Python:)code = input("Enter code: "),然后让用户传递它,但是对我来说,这似乎是一种不好的做法,因为该库可能(在这种情况下肯定会)用在服务器上的后台任务中。 我想知道这是否被视为反模式。

9
只有静态成员的实用程序类是C ++中的反模式吗?
我应该在何处放置与类无关的函数这个问题引发了一些争论,即在C ++中将实用程序函数组合到类中是否有意义或者只是将它们作为自由函数存在于命名空间中。 我来自C#背景,后者不存在该选项,因此自然倾向于在我编写的C ++小代码中使用静态类。该问题的最高投票答案以及一些评论都说,自由函数是首选,甚至暗示静态类是反模式。为什么在C ++中会这样?至少从表面上看,类上的静态方法似乎与命名空间中的自由函数没有区别。为什么要选择后者呢? 如果实用程序功能的集合需要一些共享数据,例如可以将其存储在私有静态字段中的缓存,情况会有所不同吗?

11
仅限构造方法的子类:这是反模式吗?
我当时正在与一位同事进行讨论,但最终我们对继承的目的产生了矛盾的直觉。我的直觉是,如果子类的主要功能是表达其父级的可能值的有限范围,则它可能不应该是子类。他主张相反的直觉:子类化表示对象的“特定性”更高,因此子类关系更合适。 更具体地讲,我认为如果我有一个扩展父类的子类,但是该子类覆盖的唯一代码是构造函数(是的,我知道构造函数通常不会“重写”,请耐心等待),然后真正需要的是一种辅助方法。 例如,考虑一下这个现实生活的类: public class DataHelperBuilder { public string DatabaseEngine { get; set; } public string ConnectionString { get; set; } public DataHelperBuilder(string databaseEngine, string connectionString) { DatabaseEngine = databaseEngine; ConnectionString = connectionString; } // Other optional "DataHelper" configuration settings omitted public DataHelper CreateDataHelper() { Type dataHelperType = DatabaseEngineTypeHelper.GetType(DatabaseEngine); DataHelper …


3
使用peek()修改流元素是否是反模式?
假设我有一个事物流,并且想在流中“丰富”它们,我可以使用peek()它,例如: streamOfThings.peek(this::thingMutator).forEach(this::someConsumer); 假设在代码的这一点上对事物进行变异是正确的行为-例如,该thingMutator方法可以将“ lastProcessed”字段设置为当前时间。 但是,peek()在大多数情况下,它的意思是“看起来,但不要碰”。 是使用peek()到发生变异流元素的反模式或不明智的? 编辑: 另一种更常规的方法是转换消费者: private void thingMutator(Thing thing) { thing.setLastProcessed(System.currentTimeMillis()); } 到返回参数的函数: private Thing thingMutator(Thing thing) { thing.setLastProcessed(currentTimeMillis()); return thing; } 并map()改用: stream.map(this::thingMutator)... 但这会引入敷衍的代码(return),但我不认为它会更清晰,因为您知道peek()返回的对象相同,但是map()乍一看并不清楚它是同一类对象。 此外,使用peek()lambda可以突变,但是map()您必须构建火车残骸。比较: stream.peek(t -> t.setLastProcessed(currentTimeMillis())).forEach(...) stream.map(t -> {t.setLastProcessed(currentTimeMillis()); return t;}).forEach(...) 我认为peek()版本更清晰,lambda也很明显是变异的,因此没有“神秘的”副作用。同样,如果使用方法引用,并且该方法的名称明确暗含了突变,则该名称也很明显。 就个人而言,我不会回避使用peek()变异-我觉得这很方便。

10
存在哪些命名反模式?[关闭]
有一些名字,如果您发现自己喜欢这些名字,那您就知道自己已经搞砸了。 例如: XxxManager 这很不好,因为一个类应该描述该类做什么。如果您能为该班级提出的最具体的词是“管理”,则该班级太大。 还有哪些其他命名反模式? 需要澄清的是,我并不是在问“名字不好”的问题-这个问题完全是主观的,无法回答。我问,“什么名字表示系统的总体设计问题”。也就是说,如果您发现自己想调用组件Xyz,则可能表明该组件不安全。还要注意,每条规则都有例外-我只是在寻找警告标志,以指示何时确实需要停止并重新考虑设计。

6
将值转换为不同表示形式,然后再将其转换回其起始位置的代码很不好,但是如何?[关闭]
我正在阅读一篇有关不良编程习惯的文章。 它提到- “ Yo-Yo代码”将值转换为不同的表示形式,然后将其转换回其起始位置(例如:将十进制转换为字符串,然后转换为十进制,或者填充字符串然后对其进行修整) 我不明白为什么他给出的特定示例对编写程序来说是一种不好的方式。如果情况需要,我可以将其转换回去,以便可以使用该值。 有人可以解释更多吗?

8
在这里抛出异常是一种反模式吗?
代码审查后,我刚刚讨论了设计选择。我想知道您的意见是什么。 有一个此类Preferences,它是键-值对的存储桶。空值是合法的(这很重要)。我们希望某些值可能尚未保存,并且我们希望通过在请求时使用预定义的默认值对其进行初始化来自动处理这些情况。 讨论的解决方案使用以下模式(注意:显然,这不是实际的代码-出于说明目的而进行了简化): public class Preferences { // null values are legal private Map<String, String> valuesFromDatabase; private static Map<String, String> defaultValues; class KeyNotFoundException extends Exception { } public String getByKey(String key) { try { return getValueByKey(key); } catch (KeyNotFoundException e) { String defaultValue = defaultValues.get(key); valuesFromDatabase.put(key, defaultvalue); return defaultValue; } …

7
我的公司合并分支机构错了吗?
最近,我碰到了一篇有关分支和合并以及SCM的MSDN文章:分支和合并入门-Chris Birmele。 他们在文章中说“大爆炸合并”是一种合并的反模式: 大爆炸合并-将分支合并推迟到开发工作的尽头,并尝试同时合并所有分支。 我意识到这与我公司对所有开发分支的工作非常相似。 我在一家非常小的公司里工作,只有一个人担任最终审查+干线合并授权。我们有5个开发人员(包括我在内),我们每个人都会被分配一个单独的任务/错误/项目,我们每个人都将离开当前主干(subversion),然后在我们的分支中执行开发工作,测试结果,编写文档如有必要,请与其他开发人员进行同行评审和反馈循环,然后将分支提交给我们的项目管理软件进行评审+合并。 我的老板是主干存储库的唯一授权,实际上将把分支的所有审核推迟到一个时间点,在该时间点他将尽其所能进行审核,一些​​分支将被退回以进行增强/修复,有些则被丢弃。分支将直接合并到主干中,由于冲突等原因,一些分支将被退回。 对于我们来说,在最终审阅队列中有10-20个活动分支合并到主干中并不少见。 在最后的审阅和合并阶段,我们经常还必须解决冲突,因为两个分支是在同一主干上创建的,但修改了同一段代码。通常,我们可以通过重新分支,重新应用更改并解决冲突,然后提交新分支进行审核(可怜的人变基)来避免这种情况。 我有一些直接的问题是: 我们是否展示了被称为“大爆炸合并”的非常反模式? 我们看到的某些问题是此合并过程的结果吗? 我们如何在不增加我老板的瓶颈的情况下改善这一合并过程? 编辑:我怀疑我的老板会放松对中继存储库的控制,还是允许其他开发人员合并到中继。不知道他这样做的原因是什么,但是我真的不打算提出这个话题,因为这个话题以前被提出过并且很快就被否决了。我认为他们只是不信任我们,这是没有意义的,因为无论如何都跟踪了一切。 任何其他见解这种情况将不胜感激。

2
历史增长的软件是否有命名的反模式?[关闭]
是否有一种反模式来描述一个历史悠久的软件系统,其中多个开发人员只是向系统添加了新功能,但没有人真正关注整个体系结构,也从未进行过重构? 我认为,当管理人员/客户不断要求新功能并且没有人重构任何东西而只是增加其他开发人员以前所做的事情时,就会发生这种情况。 原因还可能是开发人员对软件系统不知所措,并不真正了解它当前的工作方式,然后只是在最后添加/粘上了他的代码(而不是重构和更改代码)。 因此,随着时间的推移,维护系统变得越来越困难。 (我想知道是否有针对这种反模式的图片,以使所有编程人员都无法清楚了解它-就像一辆通过添加越来越多的功能而无需考虑整体设计而制造的汽车。就像有人需要拖曳拖车时向后骑,然后工程师只是将牵引杆焊接到汽车的前部。工作已经完成。但是现在,前围不再打开了。)

2
以下(反)模式的名称是什么?它的优缺点是什么?
在过去的几个月中,我偶然发现了以下技术/模式。但是,我似乎找不到一个特定的名称,也不能百分百确定其所有优点和缺点。 模式如下: 在Java接口中,照常定义了一组常用方法。但是,使用内部类,默认实例会通过接口泄漏。 public interface Vehicle { public void accelerate(); public void decelerate(); public static class Default { public static Vehicle getInstance() { return new Car(); // or use Spring to retrieve an instance } } } 对我来说,最大的优势似乎在于,开发人员只需要了解接口,而无需了解其实现,例如,在他快速想要创建实例的情况下。 Vehicle someVehicle = Vehicle.Default.getInstance(); someVehicle.accelerate(); 此外,我已经看到该技术与Spring一起使用,以便根据配置动态提供实例。在这方面,它看起来也可以帮助模块化。 但是,我无法撼动这是滥用接口的感觉,因为它将接口与其实现之一结合在一起。(相关性反转原理等。)有人可以向我解释该技术的调用方式以及它的优缺点吗? 更新: 经过一段时间的考虑后,我重新检查并注意到,使用以下单例版本的模式的频率更高。在此版本中,公共静态实例通过接口公开,该接口仅初始化一次(由于字段为final)。另外,几乎总是使用Spring或将接口与实现分离的通用工厂来检索实例。 public interface Vehicle …

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.