Questions tagged «anti-patterns»

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


8
“故障驱动开发”怎么办?
在我们的商店,我们努力做到敏捷。我想说我们正在取得长足进步。就是说,我们中的一些人发现了一种模式,我们已经开始将其称为“故障驱动开发”。 基本上,可以将失败驱动开发描述为一个敏捷的发布/迭代周期,其中的错误/功能不是由具有接受标准的任务和故事来指导,而是由缺陷跟踪软件中输入的缺陷来指导。 我们的团队有一个出色的项目经理,他努力从客户那里获得验收标准,但这并不总是可能的。从我的开发主席那里,这是由于客户要么不完全知道他们想要什么,要么是(这是踢球者)客户总公司的两个不同“营地”与故事的实现方式冲突。营A将松散决定了功能X的作品像这样,那么营B就失败,这是由于不喜欢运行的是。因此,术语“ FDD”。该过程是由“故障”驱动的。 这引出我的问题:是否还有其他人遇到过这种情况? 当然,我们已经尽力让A和B营地达成一致,但每个人都知道并非总是如此。 谢谢

12
哪种设计模式定义最差或定义最窄?[关闭]
对于每个编程项目,都有过编程经验的管理人员会在为您的项目推荐一些设计模式时大放异彩。当设计模式有意义或您需要可扩展的解决方案时,我喜欢它们。例如,我以积极的方式使用了代理,观察员和命令模式,并且每天都这样做。但是,如果只有一种创建对象的方法,我真的很犹豫地说出Factory模式,因为工厂将来可能会使一切变得更容易,但是却使代码复杂且纯属开销。 因此,我的问题是关于我的未来职业以及我对经理类型的回答,这些类型周围会出现随机的模式名称: 您使用了哪些设计模式,这使您整体退缩?哪些是最糟糕的设计模式,除了在一种有意义的单一情况下,您应该考虑哪些(请阅读:哪些设计模式定义非常狭窄)?(这就像我在寻找对亚马逊整体产品的负面评价,以了解使用设计模式的人最讨厌的东西。)而且我在这里不是在谈论反模式,而是通常被认为是“好的”模式。 编辑:正如一些回答所言,问题通常是模式不是“不良”而是“使用错误”。如果您知道一些经常被滥用甚至难以使用的模式,那么它们也可以作为答案。

9
单例模式的替代方案
我对单例模式有不同的看法。一些人主张应不惜一切代价避免使用它,而另一些人则认为在某些情况下它可能是有用的。 我使用单例的一种情况是当我需要一个工厂(假设类型F的对象f)来创建某个类A的对象时。工厂使用一些配置参数创建一次,然后每次使用类型A被实例化。因此,要实例化A的代码的每个部分都获取单例f并创建新实例,例如 F& f = F::instance(); boost::shared_ptr<A> a = f.createA(); 所以我的一般情况是 出于优化原因(不需要多个工厂对象)或共享公共状态(例如,工厂知道仍可以创建A的实例),我只需要一个类的实例即可 我需要一种方法可以在代码的不同位置访问F的此实例f。 我对讨论此模式的好坏不感兴趣,但是假设我想避免使用单例,我还可以使用其他什么模式? 我的想法是(1)从注册表获取工厂对象,或(2)在程序启动期间的某个时候创建​​工厂,然后将工厂作为参数传递。 在解决方案(1)中,注册表本身是一个单例,因此我刚刚将不使用单例的问题从工厂转移到了注册表。 在情况(2)中,我需要工厂对象来自的一些初始源(对象),因此恐怕我会再次落入另一个单例(提供我的工厂实例的对象)。通过跟踪此单身人士链,我可以将问题简化为一个单身人士(整个应用程序),通过它 可以直接或间接管理所有其他单身人士。 最后一种选择(使用一个初始单例创建所有其他唯一对象并将所有其他单例注入正确的位置)是否可以接受?当有人建议不要使用单例时,这是隐式建议的解决方案,还是其他解决方案,例如在上述示例中? 编辑 由于我认为我的问题的重点已经被某些人误解了,因此这里提供了更多信息。如所解释的,例如这里,词语 单可指示(a)中的一类具有单个实例对象和(b)用于创建和访问这样的对象的设计模式。 为了使事情更清楚,让我们对(a)使用术语唯一对象, 对(b)使用术语单例模式。因此,我知道单例模式和依赖项注入是什么(顺便说一句,最近我一直在大量使用DI从我正在处理的某些代码中删除单例模式的实例)。 我的观点是,除非整个对象图都是从位于main方法堆栈上的单个对象实例化的,否则始终需要通过singleton模式访问一些唯一的对象。 我的问题是,完整的对象图创建和连接是否取决于主要方法(例如,通过一些不使用模式本身的强大DI框架)是唯一的无 单例模式解决方案。

8
如果空值是邪恶的,那么当值可以有意义地缺失时应该使用什么?
这是一遍又一遍重复的规则之一,这令我感到困惑。 空是邪恶的,应尽可能避免。 但是,但是-出于我的天真,让我尖叫-有时可能会有意义地缺乏价值! 请让我在一个示例中问这个问题,该示例来自我目前正在研究的此反模式缠身的可怕代码。从本质上讲,这是一个基于多人网络回合的游戏,其中两个玩家的回合都同时运行(例如在Pokemon中,与Chess相反)。 每次转动之后,服务器都会广播客户端JS代码的更新列表。Update类: public class GameUpdate { public Player player; // other stuff } 此类被序列化为JSON并发送到连接的播放器。 大多数更新自然都会有一个与之相关的玩家-毕竟,有必要知道哪个玩家在此回合​​中做出了哪个动作。但是,某些更新无法使Player有意义地与它们相关联。示例:游戏被强行捆绑,因为超出了没有动作的回合限制。我认为,对于此类更新,让播放器为空是有意义的。 当然,我可以利用继承来“修复”此代码: public class GameUpdate { // stuff } public class GamePlayerUpdate : GameUpdate { public Player player; // other stuff } 但是,由于两个原因,我看不到有什么改进: 现在,JS代码将简单地接收不带Player的对象作为已定义的属性,这与它为null相同,因为两种情况都需要检查该值是否存在。 如果将另一个可为空的字段添加到GameUpdate类中,则我必须能够使用多重继承来继续进行此设计-但是MI本身是邪恶的(根据经验更丰富的程序员),更重要的是,C#不会有它,所以我不能使用它。 我有一个暗示,这段代码是经验丰富的优秀程序员惊骇地尖叫的其中之一。同时,我看不到这个null会如何伤害任何事物,而应该怎么做。 你能向我解释这个问题吗?

12
是否有描述这种编码方法的反模式?[关闭]
已关闭。这个问题是基于观点的。它当前不接受答案。 想改善这个问题吗?更新问题,以便通过编辑此帖子以事实和引用的形式回答。 5年前关闭。 我有一个代码库,程序员倾向于将其包装在没有意义的区域中。例如,给定一个错误日志,我们可以通过 ErrorLog.Log(ex, "friendly message"); 他添加了其他各种方法来完成完全相同的任务。例如 SomeClass.Log(ex, "friendly message"); 它只是转过身来并调用第一个方法。这增加了复杂性级别,并且没有任何额外的好处。是否有一个反模式来描述这一点?

1
“ exit(-1)”来自哪里?
我看到在建议使用在互联网上有很多传统的软件和坏的教程exit(-1),return -1或类似的表示“异常终止”。问题是,至少在POSIX中,该问题-1从未存在过,并且不是有效的状态码。man 3 exit说明了exit()将的值返回status & 0377给父对象,即-1变为255。在非POSIX系统上,EXIT_FAILURE建议可移植。但是我从没看到“ -1表示异常终止”和“ EXIT_FAILURE可能不是1”,这表明他们清楚地相信“ -1”即使在非POSIX系统上也是常规的。 这是一个StackOverflow问题的例子,这个问题可以永久存在。软件“ unrealircd”也是exit(-1)用于终止程序的程序示例。实际上,这使与的交互变得困难systemd。 这种反模式是从哪里来的?在某些情况下有效吗?

6
为什么注释掉代码然后逐渐将其删除以跟踪我已经完成的工作和尚待完成的工作是错误的?
每当我发现需要更改我的代码的很大一部分时,要么是因为它不正确,要么是因为需要将其修改为由于其他原因而需要进行的主要体系结构更改,这通常是我要做的: 我注释掉了我怀疑可能需要更改的所有代码。我将注释掉的代码视为我的TODO列表。 我逐步查看注释掉的代码并取消注释该代码的部分,或者将它们复制粘贴到其他位置,然后根据需要对其进行编辑,或者从头开始重写此代码的部分,查看注释掉的代码以供参考。每当我认为对部分注释掉的代码完成处理后,便将其删除。 我继续进行此操作,直到看不到更多注释掉的代码为止。 我应该注意,我主要是在自己开发的个人项目上进行此操作。 但是,有人告诉我,我应该停止这样做。有人告诉我,我应该开始使用git,指代旧的提交以查看旧的代码,而不是留下注释掉的代码。有人告诉我: 注释掉代码是一个坏习惯,应该清除掉。您缺乏经验,因此无法理解。如果几年后您看到另一个喜欢注释代码的人的代码,您将开始对这个人发誓。每当我看到注释掉的代码时,我都将其完整删除,甚至根本不看它,因为通常这样的代码是完全不值钱的。您肯定不会看到在一个人的小型项目中注释掉代码的弊端。但是,如果您找到工作并保持这种习惯,那将是一种耻辱。 我想问一下我现在看不到的正在做的事情有哪些弊端吗? 我必须说我不太热衷于仅使用git查看过去的代码。如我所说,我将注释掉的代码视为待办事项列表。虽然git会向我展示代码的外观,但无法清楚地告诉我哪些代码部分仍需要检查以及哪些部分已经完成。我担心我可能会错过一部分代码并引入错误。 为了完整起见,我想补充一点,我要引用的人是一位经验丰富的开发人员,并且是Bob叔叔的“ Clean Code”的拥护者-Bob叔叔确实批评了他的书中严厉地注释掉了代码。

5
使用仅包含静态方法的*** Helper或*** Util类是AntiPattern
我经常遇到Java或任何类型的语言中的helper或util类。因此,我问自己这是否是某种反模式,而此类类的存在只是软件设计和体系结构中缺少一些缺失。 通常,这些类仅使用静态方法进行限制,该方法可以完成很多工作。但大多数情况下,确实是上下文相关的并且是全状态的。 我的问题是,您对此类静态辅助程序/ util类有何看法,因为其优势当然是仅使用类名进行快速调用。 在哪种抽象级别上,您将避免使用此类? 我认为关键字“ static”应该只允许在类(Java)的声明中使用,而不能用于方法。我认为以这种方式使用它,是在Java中结合过程式和OO-范式并避免滥用关键字的一种很好的选择,也是中间的选择。 由于答案而增加的内容: 起初,我认为能够组合不同的范例甚至在机器或vm编译的代码中使用运行时解释的脚本语言是完全合法的。 我的经验是,在项目的开发过程中,此类帮助器和utils或其他名称正在不断增长,并在最初被设计为模块化和灵活的代码库的每个被遗忘的角落使用。而且由于缺乏时间进行重构或重新考虑设计,随着时间的推移,您的情况只会变得更糟。 我认为static应该从Java中删除。尤其是在现在可以使用更复杂的功能语言元素的地方。

8
有没有比TryGetValue使用C#词典更好的方法?
我发现自己经常在网上查找问题,许多解决方案都包括字典。但是,每当我尝试实现它们时,我的代码都会令人讨厌。例如,每次我想使用一个值时: int x; if (dict.TryGetValue("key", out x)) { DoSomethingWith(x); } 这是4行代码,基本上可以执行以下操作: DoSomethingWith(dict["key"]) 我听说使用out关键字是一种反模式,因为它会使函数改变其参数。 另外,我发现自己经常需要“反向”字典,在其中翻转键和值。 同样,我经常想遍历字典中的各项,发现自己将键或值转换为列表等以更好地做到这一点。 我觉得几乎总是有一种更好,更优雅的字典使用方式,但是我很茫然。

1
如果我们记录异常消息并抛出其他异常,它仍然是反模式吗?
我们的网络应用程序正在使用将ExceptionMapper某些异常映射到Response。我们记录异常消息,然后引发新异常,如下所示: catch (SomeException ex) { LOG.error(ex.getMessage()); throw new MyException(ex.getMessage()); } 我们不会再次抛出相同的异常,所以我的问题是,是否将其视为Log and Throw反模式。因此,最好删除相似位置的日志并将它们移至以下几个ExceptionMapper类: @Provider public class MyExceptionMapper implements ExceptionMapper<MyException> { // bla bla @Override public Response toResponse(final MyException ex) { LOG.error(ex.getMessage()); return Response.status(400).entity("something").build(); } }

2
什么是案例反模式?
今天的TDWTF文章以作者的告白开头: 直到最近,我才知道什么是For-Case反模式,当时有大量文章谴责它为反模式。我确定在某个时候我可能已经使用过它,但是我从来不知道它的名字。它被认为是教科书的反模式,通常意味着对for循环,case语句,要解决的问题或这三者的某种组合的误解。 然后,他继续前进,就好像读者自然会知道For-Case反模式是什么,而无需任何进一步的解释。 但是我没有!我还没有看过Remy谈论的“大量文章”,而且我唯一可以在Google上找到的重要参考文献(除了Remy的文章)是Raymond Chen的博客文章,内容是关于if-if反模式的问题。 。不过,他也没有定义“针对案例的反模式”。 这些家伙在谈论的“案例反模式”是什么,又是什么使它成为反模式?

1
什么是灌注泵?有时称为预读
过去,我已经学会了这种表达方式和模式。当然,这个名字来自于那些老式泵,在泵水之前必须先注满水,但是谁在乎呢?我们在这里谈论代码。 我们将欢迎您提供一些非常好的示例,并对模式的完成情况进行解释。今天如何看待这种模式? 灌注有时会导致有缺陷的循环工作,但要付出DRY的代价。因此,这可能是短暂停止更好设计的途中。这被认为是反模式吗?有其他选择吗?

7
将对象传递到更改对象的方法中,这是常见的(反)模式吗?
我正在阅读Martin Fowler的《重构》一书中的常见代码气味。在这种情况下,我想知道我在代码库中看到的一种模式,并且可以客观地将其视为一种反模式。 模式是一种将对象作为参数传递给一个或多个方法的模式,所有这些方法都会更改对象的状态,但是没有一个返回对象。因此,它依赖于C#/。NET(在这种情况下)的按引用传递特性。 var something = new Thing(); // ... Foo(something); int result = Bar(something, 42); Baz(something); 我发现(尤其是方法名称不正确时),我需要研究此类方法以了解对象状态是否已更改。由于我需要跟踪调用堆栈的多个级别,因此这会使代码理解更加复杂。 我想建议改进此类代码,以返回具有新状态的另一个(克隆的)对象,或在调用站点更改该对象所需的任何操作。 var something1 = new Thing(); // ... // Let's return a new instance of Thing var something2 = Foo(something1); // Let's use out param to 'return' other info about the operation …

2
从外部文件加载或不加载用于单元测试的数据
在进行单元测试时,我经常会辩论自己要馈入的数据量,并期望从被测单元中回来,我应该将它们包含在实际的测试文件中。 我不断努力的权衡是: 如果测试的很大一部分(以代码量计)由输入和输出数据组成,那么似乎很难实际读取测试,但是我可以很容易地看到实际的输入和输出。 如果我从文件中加载测试数据,则可以轻松地对可能的数据输入进行一堆测试,轻松地将测试数据重复用于多个测试,但是我必须离开源代码来查看另一个文件,以查看输入的确切含义。 。 其中之一是反模式吗?

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.