这个反模式的名称是什么?

5

可能有些人已经遇到过这个问题。当程序员过于关注面向对象,忘记了性能和数据库时,这种情况就会发生。

例如,假设我们有一个电子邮件表格,需要通过该程序发送。在启动时,它会按以下方式查找需要发送的任何内容:

Emails = find_every_damn_email_in_the_database();
FOR Email in Emails
  IF !Email.IsSent() THEN Email.Send()

从不重复自己的角度来看,这是一个好的方法,但有时候无法避免,因此应该采用以下方法:

Emails = find_unsent_emails();
FOR Email in Emails
  Email.Send()

这个有名称吗?

1
我相信你会得到很多回答告诉你性能已经不重要了。 :) - BobbyShaftoe
我不确定过度使用面向对象编程与此有什么关系? - Michael Burr
@MB:我猜询问电子邮件是否已发送是面向对象的,而非面向对象的方法则是直接查看列。 - Andrew Grimm
我提到OO的原因是因为Email类有一个漂亮整洁的Sent()方法。思路是“我将填充所有对象,然后它们就具有行为”。这很酷,但速度较慢。 - WW.
我明白了,是的,我猜这是一个常见的反模式。 - Michael Burr
13个回答

9

我会尝试为其创造一个名字——“懒惰过滤器(反)模式”。


5

我曾经见过这种情况。那个程序员没有待太久。

我们称之为“喷火龙法”


2
对我来说,这就是 Joel Spolsky 的 漏洞抽象
这并不完全是一种反模式,但写这段代码的人并没有真正理解 Active Record 模式抽象泄漏的地方。

这段代码让我想起了ActiveRecord,但伪代码不是Ruby(例如,它们会使用“Email.send除非Email.sent”)。你如何解决ActiveRecord的迭代抽象泄漏问题? - Andrew Grimm
伪代码并没有特定的含义。我第一次看到它是在C++中。 - WW.
是的,Active Record 是一种通用模式,可以在任何语言中实现。Ruby on Rails 只是有一个众所周知的实现。它有时也被称为“实体类”。 - Jesse Smith

2
我称之为“散弹枪方法”。

1

我不确定这是否必须与数据库相关,因为您可以有一个复杂且昂贵的过程(例如,超过一个标志)来应用组的筛选器。

我认为它没有名称,因为第一种设计并不好,而且违反了单一职责原则。如果您搜索、筛选和打印筛选结果,则正在执行多个操作,因此需要将其重构为“搜索筛选”和打印。

唯一与简单重构不同的是,它还会影响性能,就像内部循环可以以损害性能的方式设计一样。


1

1

这通常是因为使用现有查询并在代码中进行过滤比添加新的SQL查询要容易得多。可能是因为DBA控制所有查询,获得批准新查询需要数天时间,或者可能是因为您正在使用的ORM工具使定义自定义查询非常困难。

如果我要给它命名,我会称之为“捷径”(反)模式。它是否是反模式实际上取决于个人情况。如果您需要检索的项目始终是相当少量的,则在代码中进行过滤确实不是什么大问题。但是,如果项目数量很大并且有持续增长的潜力,那么显然应该在服务器上进行过滤。


1
我曾在其他地方看到类似的问题,其中不是一个简单的待办事项数组,而是基于“列表群集”的“交易群集”,基于“收藏群集”的“内存群集”。不用说,最简单的事情也变成了一个巨大的麻烦。
我称之为“奔跑的泛化”。

0
部分灵感来自于19世纪的“懒惰过滤器(反)模式”,那么“功能失调编程”(即功能编程的相反)怎么样?

0

愚蠢的业余爱好者。

说真的,我只在那些拥有计算机科学学位但没有任何专业经验的人中看到过这种错误。当我在杜克大学教书时,我的导师和我开设了一门“大规模编程”课程,我们让学生们查看这些类型的错误。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接