周末读了阮一峰老师的文章: (www.ruanyifeng.com/blog/2025/0… 工程师谈系统设计], 有感在 iOS 开发中, 其实也涉及到系统设计的相关问题,写点我的想法。
如今,各种 AI 编程助手已经能帮我们搞定大段的代码、修复恼人的 Bug,甚至搭建基础框架。这让我们从繁琐的“敲代码”中解放了出来,有了更多的时间和精力去思考那些真正重要的事情——我们到底在构建一个什么样的产品?
当 AI 负责了越来越多具体的“怎么做”之后,我们程序员的价值就更多地体现在了“做什么”和“为什么这么做”上。这正是系统设计的核心。与其说我们是“编码员”,不如说我们更像是“产品工程师”。我们不仅要打磨功能,更要关注 App 的长期健康和用户价值。
所以,好的系统设计不再是架构师的专利,而是我们每个 iOS 开发者的基本功。下面这几个原则,就是帮我们从“码农”进阶到“工程师”的内功心法。
1. 别急着写代码,先搞清楚问题本身
咱们最容易犯的错,就是拿到需求文档,二话不说就开始建文件、敲代码。结果辛辛苦苦做出来的功能,酷炫是酷炫,用户却根本不用,或者完全没解决用户的痛点。这就是巨大的浪费。
所以在动手之前,先让自己成为“问题专家”。
- 多和产品、设计聊聊: 别只当一个需求的“接收器”。主动去问:“这个功能要是没网了,应该怎么显示?”“用户要是疯狂点击这个按钮,会不会把服务器搞崩?”把这些模糊地带都聊清楚了,后面的活儿才好干。
- 想想用户怎么用: 你的用户可能是在摇晃的地铁上单手操作,也可能在地下车库里信号差得可怜。考虑到这些场景,你自然就知道缓存该怎么做、界面该如何适应不同尺寸了。
- 明确功能的边界: 一开始就想清楚这个功能“做什么”,以及同样重要的,“不做什么”。这样可以帮你创建一个职责清晰、简单好懂的组件,而不是一个什么都干的大杂烩。
2. 像搭乐高一样,让你的 App 能随时变形
App 开发没有一成不变的需求。今天加个新功能,明天改个旧逻辑,是家常便饭。如果你的代码都搅在一起,那每次修改都像是在拆除承重墙,心惊胆战。好的架构,应该像乐高一样,可以轻松地插拔、替换和扩展。
- 给代码分分层: 找个顺手的架构模式(比如大家常用的 MVVM),把代码拆成几层。界面(View) 就老老实实负责展示和响应用户点击;业务逻辑(ViewModel) 负责处理数据和状态;数据层(Model) 负责跟服务器或者本地数据库打交道。各司其职,互不干扰。
- 把 App 拆成小模块: 别把所有东西都塞在一个工程里。可以按功能把 App 拆成一个个独立的小模块(用 Swift Package Manager 就很方便)。比如,网络请求、UI 控件库、用户中心……每个都是一个独立的小积木。这样做,不仅代码复用方便,编译速度也能快不少,团队分工也更清晰。
- 多用协议,少用继承: 让模块之间通过一套约定好的“接口”(也就是协议)来对话,而不是直接依赖某个具体的实现。这就像两台设备通过标准的 USB 接口连接,你不用关心里面具体是什么牌子的。这样做的好处是解耦,想换掉某个实现,或者写单元测试的时候,会变得异常轻松。
- 别自己造轮子,让别人“递”给你: 一个类需要用到别的对象时,不要在内部自己去创建它,而是通过构造函数之类的入口,让外面把这个对象“注入”进来。这就是“依赖注入”。测试的时候,你就可以轻松地“递”给它一个假的测试对象,非常方便。
3. 保持简单,不“炫技”
我们程序员总有种秀操作的冲动,喜欢用一些时髦的技术或者复杂的设计模式,结果把代码搞得像迷宫一样,只有自己能看懂(可能过两个月自己也看不懂了)。记住,代码首先是写给人读的,其次才是给机器执行的。
- 用不上的功能,坚决不写: 别总想着“万一以后需要呢?”。只为当前实实在在的需求写代码。未来的需求,未来再说。
- 可读性是第一要务: 用心起好变量名和函数名,让代码像一篇文章一样流畅。一个函数只干一件事,而且要干好。如果一段逻辑太复杂,就把它拆成几个更小的、更容易理解的函数。
- 谨慎地进行抽象: 抽象的目的是为了隐藏复杂性,而不是创造复杂性。在引入一个新的协议、基类之前,先问问自己:“这玩意儿真的让我的代码更简单了吗?”
4. 没有“最优解”,只有最合适的“取舍”
工程师的日常,就是在做各种各样的选择题,不存在什么“银弹”。每一个技术决策,都是在特定条件下的权衡和取舍。关键在于,你要清醒地知道自己选了什么、放弃了什么。
- 开发效率 vs. 性能: 用 Kingfisher 这种第三方库,几行代码就能搞定图片加载,但会增加 App 体积;自己从头写一个,虽然轻量可控,但费时费力。怎么选?看项目时间和需求。
- 拥抱新技术 vs. 兼容老设备: 为了用上酷炫的 SwiftUI 和 Async/Await,你可能就得放弃 iOS 14 以下的用户。这个决策需要你根据用户数据来判断,是追求开发效率,还是保住用户基本盘。
- 包大小 vs. 功能丰富度: 集成一个功能强大的 SDK 可能会让你的 App 一下子“胖”好几兆。这个功能带来的价值,真的值得牺牲用户的下载意愿和存储空间吗?
- 把你的选择记下来: 当你做了一个重要的决定(比如,为什么最终选了 Core Data 而不是 Realm 做本地存储),最好在文档或者代码注释里写下选择理由。这在未来,对你自己和接手的同事来说,都是一笔宝贵的财富。
5. 眼光放长远,别给未来挖坑
今天为了赶进度走的一条捷径,很可能就是明天让你通宵加班的“技术债”。一个成功的 App 要持续迭代好几年,从一开始就要为它未来的健康和可维护性考虑。
- 给你的代码买份“保险”: 自动化测试(单元测试、UI 测试)就是你代码的“安全网”。有了它,你将来做重构或者加新功能的时候,才敢放开手脚,不用怕一不小心改出新 Bug。
- 技术选型要稳健: 在选择数据库、网络库、状态管理框架这些核心依赖时,别光追新潮。多看看它的社区活跃度、文档质量和背后有没有大公司支持,确保它不会过两年就没人维护了。
- 给你的 App 装上“监控”: App 上线后就像一辆跑在路上的车,你需要知道它的运行状况。崩溃报告能让你知道车在哪里抛锚了;性能监控告诉你车的油耗和速度;日志系统则像行车记录仪,能在出问题时帮你快速定位原因。
总结
总而言之,在 AI 辅助开发的今天,我们 iOS 开发者的角色正在悄然改变。AI 可以帮我们更快地实现功能,而这恰恰给了我们更多时间去进行产品思考、打磨用户体验,甚至重新审视原生开发的独特优势和价值。
将上面这些系统设计原则融入日常工作,会帮我们完成从一个仅仅实现功能的“编码者”,到能够构建一个健壮、可维护、并能持续创造价值的产品的“工程师”的转变。