Design Patterns Suck
Design Patterns Suck
In software engineering, the term “design pattern” (which, honestly, is kind of redundant — aren’t all patterns designs?) gets thrown around a lot. It originally came from architecture — actual architecture, with buildings and floorplans — not software. But in 1994, the software world got its own version when the now-infamous book “Design Patterns” was published by Gamma, Helm, Johnson, and Vlissides — aka the “Gang of Four” (GoF).
在软件工程中,“设计模式”(老实说,这个词有点多余——难道所有的模式不都是设计吗?)这个术语被频繁提及。它最初源于建筑学——真正的建筑学,涉及建筑物和平面图,而非软件。但在 1994 年,随着 Gamma、Helm、Johnson 和 Vlissides(即“四人帮”,GoF)出版了那本臭名昭著的《设计模式》一书,软件界也有了自己的版本。
They introduced 23 canonical patterns as higher-level abstractions than function calls. These patterns were meant to be language-agnostic, reusable templates for solving recurring software design problems. Sounds nice, right? Almost too nice… The problem is that design patterns have been elevated from useful vocabulary into something closer to dogma. They’re taught as universal solutions, applied where they aren’t needed, and treated as a mark of good engineering.
他们引入了 23 种经典模式,作为比函数调用更高层级的抽象。这些模式本意是作为与语言无关、可重用的模板,用于解决反复出现的软件设计问题。听起来不错,对吧?甚至好得有点过头了……问题在于,设计模式已经从有用的词汇被提升到了近乎教条的地位。它们被当作通用解决方案来传授,被应用在根本不需要的地方,并被视为优秀工程的标志。
The reality is: Design patterns suck. Yeah, I said it. Design patterns are overrated, overused, and often flat-out unnecessary. That might sound harsh, especially for those of you who keep their Gang of Four books near their bedsides, but hear me out. Most of the time, design patterns are nothing but ugly workarounds for the fact that our programming languages aren’t powerful enough or flexible enough to express what we actually want.
现实情况是:设计模式很烂。没错,我就是这么说的。设计模式被高估了、被滥用了,而且往往完全没必要。这听起来可能很刺耳,尤其是对那些把“四人帮”的书放在床头的人来说,但请听我说完。大多数时候,设计模式只不过是丑陋的权宜之计,用来掩盖我们的编程语言不够强大或不够灵活,无法表达我们真正需求的事实。
Java and Its Love Affair with Boilerplate
Java 与样板代码的“恋情”
Take Java, for example (I’ll be bashing Java quite a bit today, so get comfortable). Where do we even start? Java is the poster child for “design-pattern-mania”. Every single project looks like a carbon copy of itself because Java developers are taught to just dump in as many patterns as possible. It’s the language that practically forced design patterns into mainstream use. Why? Because Java is verbose, stiff, and lacks expressiveness. It’s like writing a novel where you’re only allowed to use three-syllable words — every problem feels ten times harder than it has to be.
以 Java 为例(今天我会狠狠地抨击 Java,所以请做好心理准备)。我们从哪儿开始呢?Java 是“设计模式狂热”的典型代表。每一个项目看起来都像是另一个项目的翻版,因为 Java 开发者被教导要尽可能多地堆砌模式。正是这门语言实际上将设计模式推向了主流。为什么?因为 Java 冗长、死板且缺乏表现力。这就像写小说时只允许使用三音节单词——每个问题看起来都比实际难度大十倍。
Oh, you’re working on a simple CRUD app? Better throw in a Factory, maybe an Observer for that database change notification, and don’t forget the Singleton — because, y’know, we all need a global logger, right?
哦,你正在做一个简单的 CRUD 应用?最好加个工厂模式(Factory),也许再加个观察者模式(Observer)来处理数据库变更通知,别忘了单例模式(Singleton)——因为,你知道的,我们都需要一个全局日志记录器,对吧?
Pattern vs Language Feature
模式 vs 语言特性
The crux of why design patterns are often garbage is that most of the time they exist only because the language itself is missing some capability. You’re basically doing workarounds for language limitations. Take the Singleton pattern as an example. You’ve seen this a thousand times:
设计模式之所以往往是垃圾,核心原因在于它们的存在大多仅仅是因为语言本身缺失了某些能力。你本质上是在为语言的局限性打补丁。以单例模式为例,你一定见过无数次这样的代码:
public class Logger {
private static Logger instance;
private Logger() {}
public static Logger getInstance() {
if (instance == null) {
instance = new Logger();
}
return instance;
}
}
That’s like 15 lines of code just to say, “I want only one instance of this thing”. What are we, cavemen? We shouldn’t need to hand-write this kind of thing. A modern language should provide constructs to handle this elegantly, but nope, not Java. Instead, we get tons of boilerplate and complexity masquerading as “best practices”.
这足足 15 行代码,仅仅是为了表达“我只需要这个东西的一个实例”。我们是穴居人吗?我们不应该需要手写这种东西。现代语言应该提供优雅的结构来处理这个问题,但很遗憾,Java 没有。相反,我们得到了大量的样板代码和复杂性,并将其伪装成“最佳实践”。
Want to see how Scala handles it? object Logger. That’s it. That’s the entire Singleton pattern. Done. No need to mess around with static blocks, thread safety, or lazy instantiation nonsense. Scala does what Java should have done in the first place: treat this as a basic language feature, not a pattern you need to manually enforce.
想看看 Scala 是怎么处理的吗?object Logger。就这样。这就是整个单例模式。搞定。不需要折腾静态块、线程安全或延迟初始化的废话。Scala 做了 Java 本该做的事:将其视为一种基本的语言特性,而不是你需要手动强制执行的模式。
Java forces you into this mess because it doesn’t have first-class functions. It’s the language’s fault, not yours, that you’re writing a Strategy pattern. Design patterns aren’t solving problems with your code; they’re solving problems with your language. A Factory pattern? That’s just Java’s refusal to give you proper constructors or a way to handle complex object creation natively.
Java 强迫你陷入这种混乱,因为它没有一等公民函数。你写策略模式(Strategy pattern)是语言的错,而不是你的错。设计模式解决的不是你代码中的问题,而是你语言中的问题。工厂模式?那只是 Java 拒绝提供合适的构造函数或原生处理复杂对象创建方式的结果。
The Cult of Overengineering
过度工程的邪教
Design patterns also feed into a deeper problem in the software world: overengineering. I’ve seen junior engineers (and some senior ones, unfortunately) who get this wide-eyed look when they hear “design patterns” and immediately try to shoehorn as many as possible into their project. They’re solving imaginary problems. When this happens, the codebase goes from something understandable to something unreadable, fragile, and overly abstracted.
设计模式还助长了软件界一个更深层的问题:过度工程。我见过一些初级工程师(不幸的是,还有一些高级工程师),当他们听到“设计模式”时,眼睛会发亮,并立即试图将尽可能多的模式强塞进他们的项目中。他们是在解决虚构的问题。当这种情况发生时,代码库就会从易于理解变得不可读、脆弱且过度抽象。
“Good” design patterns tend to be over-engineered because they are required to cater to as many use cases as possible. Over-engineered code has a cost though: you have to read it, understand what it does, and understand how it works within the context of the entire software system. Consequently, as with any other software development technique, you have to evaluate the technique against the cost of using the technique, and decide if the benefits exceed the cost.
“好的”设计模式往往是过度工程的,因为它们需要尽可能满足更多的用例。然而,过度工程的代码是有代价的:你必须阅读它,理解它的功能,并理解它在整个软件系统上下文中的工作方式。因此,正如任何其他软件开发技术一样,你必须权衡该技术的使用成本,并决定其收益是否超过成本。
Not every problem needs a design pattern. In fact, most problems don’t. Often the simplest, most straightforward solution is the right one. As a rule of thumb, if your solution needs a diagram to explain it, you’ve gone too far.
并非每个问题都需要设计模式。事实上,大多数问题都不需要。通常,最简单、最直接的解决方案才是正确的。作为一条经验法则,如果你的解决方案需要一张图表来解释,那么你已经做得过头了。
Where Patterns are Actually Useful
模式在何处真正有用
The most honest value of patterns: giving a short name to a big idea. In a team, it’s easier to say “that’s a facade” than to…
模式最诚实的价值在于:为一个宏大的概念提供一个简短的名称。在团队中,说“那是一个外观模式(Facade)”比说……要容易得多。