个人思考 2026-10-11

iOS开发中影响我最深的3个设计模式

禾

禾安

独立开发者 · 专注移动端iOS开发

设计模式不是背出来的,是被问题逼出来的。这一篇讲在 iOS 开发里真正改变我写法习惯的三个模式:委托、观察者,以及「组合优于继承」这件事,以及它们各自最容易用错的地方。

我不打算把这篇写成「23 个设计模式速查」。真正影响我的只有三个,而且它们的影响方式都是「让我少写了一些错代码」。

第一个:委托 —— 把「通知别人」这件事解耦

委托的本质是一个很朴素的想法:**我做不了决定的事,交给别人来决定。**

比如一个列表要问:「这一行显示成什么样?」「这一行被点了,你打算怎么处理?」这些问题的答案不在列表里,而在使用列表的那一层。

它为什么好用:

  • 把一个组件从「必须知道外部是谁」变成「只要求外部能满足一个约定」;

  • 同一个组件可以被不同场景复用,因为行为由外部决定;

  • 责任边界很清楚:谁发起、谁响应,一眼看得明白。

它最容易用错的地方是:把委托当成「随手传值」的通道。当一个东西需要同时通知好几个对象时,委托就不合适了 —— 那是下一个模式的领域。

第二个:观察者 —— 一处变化,多处响应

当「一个状态变了,好几个地方都要跟着变」时,硬编码的连环调用很快会变成一团乱麻。观察者模式解决的就是这件事:发布者只管说「我变了」,不关心谁在听。

这套思路在 iOS 里有很多形态,我后来用得更顺手的是响应式那一套:把「数据流」当成一等公民,变化是流动的,而不是被一次次手动推送的。

但它有个非常现实的风险:

  • 监听关系变成隐式的 —— 出了问题很难看出「这个界面为什么刷新了」;

  • 如果不注意生命周期,很容易出现「对象该释放了却还被监听链持有」;

  • 一旦滥用,整个数据流向会变得难以追踪。

我的经验是:局部用观察者(同一个界面内),跨模块尽量用显式的职责划分。省下的那点代码量,不值得拿可维护性去换。

第三个:组合优于继承 —— 这条影响最大

这一条不是某个具体模式,而是一个原则,但它是三个里影响我最深的。

继承的问题在于它把「是什么」和「能做什么」绑在了一起:你今天为了复用一段逻辑让 A 继承 B,明天会发现你其实只需要那段逻辑,却被迫背上了 B 的全部行为。

换成组合之后,思路变成:我需要什么能力,就拼装什么能力。能力和对象之间是「拥有」而不是「是」的关系,改动范围就小得多。

在 iOS 里这件事还有一层特殊意义:因为语言本身对值类型和协议的支持很好,「用协议描述能力,用组合拼装」几乎是顺手就能做到的事。

这三个模式教我的是同一件事

表面看是三个技巧,本质是同一个判断:**这段关系是「一次性的」还是「长期的」。**

  • 一次性的、明确的请求响应 —— 用委托;

  • 一对多、且未来会变 -- 用观察者;

  • 想复用「能力」而不是「身份」—— 用组合与协议。

我踩过的几类反模式

这几条都是我真实写坏过的:

  1. 为了「看起来解耦」,把简单逻辑也套上多层抽象,结果读代码的人要跳五个文件;

  2. 用通知满天飞,最后没人说得清一个界面的数据从哪来;

  3. 为了让子类复用一段逻辑,硬造了一层父类,后来这个父类变成了「什么都往里塞」的抽屉。

给正在学这块的人的建议

  1. 不要先背模式,先记住「它解决什么问题」;

  2. 遇到「两个模块互相知道太多」的时候,再回头看这些模式;

  3. 判断一个设计好不好,最简单的标准是:出问题时你能不能在五分钟内定位到「谁的锅」。

设计模式最终服务的不是「优雅」,而是「你敢改」。一个你不敢动的代码结构,无论多「标准」,都是失败的。