设计模式:被神化的套路,还是被误解的智慧?

🔑 关键词:设计模式,函数式编程,过度设计,代码洁癖,沟通成本

📖 摘要:从一次真实的重构失败经历出发,批判性审视设计模式的滥用,同时点明其作为沟通语法的价值。

去年我接手了一个支付模块的维护任务,前同事是个设计模式狂热者。整个代码库用到了工厂、策略、模板方法、观察者,甚至还有双亲委派式的责任链。看起来很美,但每改一个需求都要摸清五个类的关系图。后来我删掉了大部分模式,只留下策略加一个简单的map,反而三周就稳定上线。那次经历让我意识到,设计模式本身没有错,错的是我们把它们当成了目的,而不是手段。

图片

模式最大的价值不是复用代码,而是复用语境。你写一个工厂方法,对方不用看你实现就知道这里是“根据条件创建对象”。这种共识能大幅降低沟通成本。但问题在于,很多模式是在用类结构弥补语言表达力的不足。比如Java里的策略模式,换到Python或Go,一个函数变量就能搞定,硬套类反而显得笨拙。我见过有人用访问者模式处理JSON,那感觉就像穿着秋裤洗澡,理论没毛病,现实全是褶皱。

图片

有趣的是,函数式编程社区很少谈设计模式。不是因为没有,而是因为模式被抽象成了高阶函数、monad这些更基本的构件。他们觉得模式是“缺陷的补偿”,而面向对象阵营觉得模式是“经验的结晶”。两边都占理,但我觉得真正的分水岭在于:你是否愿意为了“可能的变化”付出今天的复杂度。设计模式本质上是对未来的一种赌注,赌这里会变化,值得加一层抽象。可惜大多数赌局都是庄家赢——需求根本没变,模式白写了。

图片

我自己现在写代码,只守两条铁律:第一,模式先用来描述,而不是用来实现。跟人讨论设计时,我会说“这里类似一个观察者”,但真写代码时先写最简单的版本,等出现第二次重复再抽象。第二,如果引入一个模式,必须能明确指出它消除了哪种坏味道,或者它让哪个概念变得不可绕过。比如状态模式如果只为了处理一个if else,那还不如写个表驱动。模式不是勋章,而是止痛药——疼了才用,不疼别硬嗑。

图片

说到底,设计模式最大的敌人不是过度设计,而是“没有对比度的知识”。市面上每本书都把模式讲得头头是道,可一旦拿到真实业务里,那些类图和时序图就像健身教练的摆拍——自己从不撸铁。我们需要的不是对模式的忠诚,而是对问题的诚实。如果哪天你能对着一个傻逼需求说“这里不需要模式”,那你才算真正读懂了《设计模式》。

图片