---
title: "过度抽象"
date: "2026-05"
category: "设计模式与架构"
tags: ["设计模式与架构"]
description: "抽象是好的，这没错，能隐藏复杂实现背后的细节，而只将结果暴露出来——但这一切是有代价的。对于使用者来说，一般情况下我们希望达到的结果是方便和便捷，不需要理解背后的一切即可用一个调用解决问题..."
source: "https://enriquemark.com/zh-hans/posts/%E9%81%8E%E5%BA%A6%E6%8A%BD%E8%B1%A1"
---

抽象是好的，这没错，能隐藏复杂实现背后的细节，而只将结果暴露出来——但这一切是有代价的。对于使用者来说，一般情况下我们希望达到的结果是方便和便捷，不需要理解背后的一切即可用一个调用解决问题。可一旦遇到问题，事实上仍然会逼迫使用者不得不去深入分析那些我希望隐藏的抽象。换言之，抽象就和幕布一样，我只是将其遮掩，但不代表它永远不被打开。我们希望的是它尽可能的不出问题，也就没有让人打开的动机，以及另外一点：如果真的要被打开，那我也希望它是一个「井井有条」而非「遍地垃圾」。我只是将复杂隐藏在幕后，而不是「把垃圾扫到看不见的地方」。

垃圾——我指的就是过度抽象。也许这么说有点过分，但这种抽象造成的损害就和垃圾一样，腐败发臭，让人恶心。过度抽象（或者说过早抽象）是一种为了优化而优化的做法，也是常常会发生在（像我这样）不上不下的中级工程师身上的事情。我自己也能很常常感受到，判断一部分代码是否需要抽象，的确是考验能力的地方。

对于是否需要抽象，我自己最直觉的判断方式是「次数」，简单粗暴，也很容易理解次数：多次出现意味着繁复，既然能够复用，那为什么不封装一下？大部分情况下都对，但不尽然全都如此。仔细反思这部分直觉，其实会很容易发现，当我关注「次数」的时候，我不是只看到它出现了多少次，而还有另一个东西是隐藏的，那就是「收益」。为什么我要封装？因为重复调用的代码块多次出现不仅不利于阅读，维护起来也很痛苦。是的，降低这种繁复是对我而言显而易见的收益。

因此，是否需要抽象就需要纳入除了「次数」之外的「收益」这一层维度。如果一段代码显著出现了多次——但是对它抽象没有显而易见的收益，我就需要考虑是否有必要封装了。比如这段重复出现了三五次，但逻辑复杂，对它抽象要浪费我一天时间，并且未来也根本不会用到。那我就没必要非这个功夫。这不是从「美观」而是从「投入产出」的角度上去考量的，作为工程师，我不是艺术家；我的目的是保证产品的稳健和可用，而不是美学价值。美妙的代码的确让人身心余元，但需要明确的成本权衡，否则就会变成「劳民伤财的样子工程」。

继续延展思考，就会发现这里还存在第三个隐藏的判断标准，当我思考到「未来会不会用到」这样一个明显的收益时，我在考虑的其实就是「稳定的功能」。就像扳手和锤子这样的工具，我对它的需求是稳定且持续的：需要经常使用，并且场景都差不多。代码也是一样，如果这段代码需要复用，且每次都是类似的需求和功能，对它进行抽象就是很自然而然的决定。否则需求多变，今天是A明天是B，今天要是装水管但明天要挖地道，那你就算封装了这个扳手，那也不见得能一直使用。这种情况下的抽象就是没意义的。

接着上面，可以继续延展——场景变化，但如果这些变化也是稳定的呢？比如虽然我公司的业务横跨装水管和挖地道这些，但都是「持续且稳定的」，那我就可以去开发多个工具。没错，这就是「边界」，抽象很好，但它不该是毫无边界的。我隐藏了什么？你不需要知道扳手跟锤子是怎么造的，只需要知道怎么用——职责清晰，用途明确。我暴露给你的是开箱即用的功能，而不是「用个锤子还得自己砍树造木柄」，对于后者来说，那就是不合格的抽象。因为就「是用锤子」这个场景来说，你没必要让用户自己安装木柄，如此复杂的调用是抽象不明确，该隐藏的复杂性没有隐藏的结果。

我们仍然可以继续扩展，假设我进行了一个抽象——继续用锤子吧——用起来很方便，再也不用自己拿石头去敲钉子了。这是一把合格锤子，能砸下钉子。就是稍微有点......太重了。哦，这是一个大铁锤，重达十公斤——等等，你搞毛呢？我敲个钉子而已，你给我这么大个玩意儿？没错，这就是我最后要说到的事儿，也就是「性能」。如果我只是为了解决一个小问题，最终的抽象解决了，却伴随着巨大的性能开支，那就需要权衡这是否值得。前面我们说到了「收益」，本质上后续的内容其实都可以算是对这一项的扩展。性能开支的是否合适显然要结合场景来考察，在高度敏感的场景下，即便你的抽象美观、合理且完全是教科书级别的设计模式运用，但却带来了不可接受的性能损失；那么，这个抽象仍然是一种「坏抽象」。就好像泳泳比赛，你从泳池一端跑到了另一端，哪怕速度突破世界纪录，也只会拿到无效分，还会被请出场外——不合时宜说的就是这种行为。

以上反过来操作就会成为「坏味道」：可重用次数不多、需求还在变化（除非有充分证据，否则不要去预判）、收益不确定、边界和职责不清晰，如此种种，都是「过度抽象」的信号。每次抽象之前都可以问问自己，我的抽象符合上述需要吗？我的场景之下，目前的抽象是收益明确的吗？不说能让自己得到资深工程师级别的优良成功，但至少可以避免塌陷，保证抽象在基本层面上是合格的。对中级工程师来说，不要求做到最好，能够稳定的产出合格成果，才是迈向资深的第一步。这就够了。
