|
| 1 | ++++ |
| 2 | +title = "从在加拿大退货失败的一件小事思考系统设计" |
| 3 | +date = 2025-05-31T11:00:00-07:00 |
| 4 | +lastmod = 2025-05-31T14:32:21-07:00 |
| 5 | +tags = ["design", "software", "program"] |
| 6 | +draft = false |
| 7 | +toc = true |
| 8 | ++++ |
| 9 | + |
| 10 | +## <span class="section-num">1</span> 前言 {#前言} |
| 11 | + |
| 12 | +前天刚写完《[软件设计的哲学](https://ramsayleung.github.io/zh/post/2025/a_philosophy_of_software_design/)》,满脑子还萦绕着模块耦合和接口抽象, |
| 13 | +结果昨天就撞上一个现实中的“设计陷阱”——一次耗时数小时却无解的「退货」噩梦。 |
| 14 | + |
| 15 | +今天趁着周末,决定把这场荒诞遭遇拆解出来,既当吐槽,也当案例分析. |
| 16 | + |
| 17 | + |
| 18 | +## <span class="section-num">2</span> 来龙去脉 {#来龙去脉} |
| 19 | + |
| 20 | +前段时间搬了家,自然就需要重新办理宽带,一直用的是 [Telus](https://www.telus.com/) 家的家庭宽带服务,他们家的宽带服务也支持从一个住址迁移到另外一个住址, 就预约了 Telus 技术人员上门安装。 |
| 21 | + |
| 22 | +技术人员上门安装完宽带之后,就需要测试一下 WI-FI 能否正常使用,就问我们的路由器在哪,他接上处理一下。 |
| 23 | + |
| 24 | +问题就来了: |
| 25 | + |
| 26 | +我们的路由器之前是舍友设置的,还不是常见的一体路由器,而是分体式路由器,有三个不同的组件。 |
| 27 | + |
| 28 | +而舍友在搬完家后就回国休假了,我还真不知道怎么搞这路由器,各个接口尝试了小半个小时也没反应,师傅也没见识过,自然也不晓得弄。 |
| 29 | + |
| 30 | +这个又是一个非常经典的软件开发问题: |
| 31 | + |
| 32 | +「在我的机器上能跑阿,换个环境就挂了」 |
| 33 | + |
| 34 | +但是一直没网也不是办法阿,然后师傅建议我可以把他随身带的 Telus 路由器买下来,等我舍友回来后把网络设置好,再把路由器还回来,Telus支持30天无理由退货。 |
| 35 | + |
| 36 | +听起来也只能这么搞了。 |
| 37 | + |
| 38 | +舍友休了几周假回来之后,几分钟不到,很快就把这个路由器就设置起来了: |
| 39 | + |
| 40 | +{{< figure src="/ox-hugo/mesh_router.jpg" >}} |
| 41 | + |
| 42 | +剩下的就是把路由器还给 Telus, 已经过了几周,30天的免责退货时间所剩不多了。 |
| 43 | + |
| 44 | + |
| 45 | +## <span class="section-num">3</span> 退货流程 {#退货流程} |
| 46 | + |
| 47 | +因为设备不是通过网购买的,没法直接在网上退单,也不是门店买的,无法直接拿去门店退,退货的流程是打电话给 Telus 的客服,问他们要退货指引。 |
| 48 | + |
| 49 | +我就给 Telus 的客服打电话,解释清楚情况后,客服说给我账户对应的邮箱发个邮件,里面有指引和退货码,我需要去 Canada Post(加拿大邮政)把路由器寄回去。 |
| 50 | + |
| 51 | +电话里客服说已经给我发邮件了,但是我说没有收到(此处为后面埋下伏笔),于是我提供另外一个邮箱,成功收到了。 |
| 52 | + |
| 53 | +{{< figure src="/ox-hugo/telus_return_equipment_instruction.jpg" >}} |
| 54 | + |
| 55 | +因为 Canada Post 最近在为涨薪闹罢工,客服提到我需要去另外一家快递公司 Purolator 寄快递。 |
| 56 | + |
| 57 | +剩下要做就是把路由器打包,然后寄出来(这么容易就好了), 再把快递单号告知 Telus, 退货流程就算结束了。 |
| 58 | + |
| 59 | + |
| 60 | +## <span class="section-num">4</span> 坑来了 {#坑来了} |
| 61 | + |
| 62 | + |
| 63 | +### <span class="section-num">4.1</span> 邮政罢工 {#邮政罢工} |
| 64 | + |
| 65 | +因为加拿大邮政罢工,所以只能去 Purolator 寄,但是去到 Purolator后,人家反馈: |
| 66 | + |
| 67 | +> 你这个退货码是给加拿大邮政的,我们不认哦,你要给个我们家的退货码。 |
| 68 | +
|
| 69 | +我只能去再打电话给 Telus 客服要退货码,花费了15分钟,终于打通了,解释完一番之后,他们说给我的邮箱发了新的 Puralator 退货码,我等了一分钟,说没有收到,然后让给我另外的一个邮箱也发一次指引,还是没有收到,然后客服说邮件会在24-48小时内到达.. |
| 70 | + |
| 71 | +但挂电话后再等了一个小时还是没有收到. |
| 72 | + |
| 73 | + |
| 74 | +### <span class="section-num">4.2</span> 邮箱收不到email {#邮箱收不到email} |
| 75 | + |
| 76 | +只能再打电话给 Telus 的客服,又等了10几分钟终于接通了,这次换了个客服,这位客服说我们不支持 Purolator,你可以等加拿大邮政罢工结束之后再寄。 |
| 77 | + |
| 78 | +我也很无语,怎么你们的回复还不一致的,就和客服说,我怎么知道罢工什么时候结束呢,30天马上就要到了嘛。 |
| 79 | + |
| 80 | +客服说,的确很有道理,这样吧,你可以去尝试使用用加拿大邮政寄下,然后我把情况记录一下,到时超过30天也可以免责退款。 |
| 81 | + |
| 82 | +然后我追问到,那罢工结束时退货也是用相同的退货码么?这个退货码有过期时间么?邮件没写哦。 |
| 83 | + |
| 84 | +客服说,那以防万一,我再给你邮箱发个新的退货码吧。 |
| 85 | + |
| 86 | +我着实是怕了,不知道为什么一直没有收到邮件,就让客服把我账号对应的邮箱地址读出来, 客服就把我邮箱的逐个地址读出来。 |
| 87 | + |
| 88 | +前面部分听着没问题嘛,我还在寻思是什么问题,只是听着听着,怎么我邮箱还有我不认识的部分,就打开 Telus 的APP 修改, 然后被气得差点要吐血了: |
| 89 | + |
| 90 | +{{< figure src="/ox-hugo/telus_email_address.jpg" >}} |
| 91 | + |
| 92 | +我的邮箱地址是 `[email protected]`, 然后为了标记不同的公司,我用了 [《两个鲜为人知的Gmail地址技巧》 ](https://ramsayleung.github.io/zh/post/2023/gmail%E5%9C%B0%E5%9D%80%E7%9A%84%E9%9A%90%E8%97%8F%E6%8A%80%E5%B7%A7/) 提到的加号技巧来注册 Telus 账号: |
| 93 | + |
| 94 | + |
| 95 | + |
| 96 | +之前用了一年多还是好好的,不然我也无法注册和验证邮箱成功。 |
| 97 | + |
| 98 | +但是现在 Telus 作了变更,直接把邮箱地址中的加号去掉了,变成了 `[email protected]`, 变成一个完全不同的邮箱, 肯定是不可能收到邮件的。 |
| 99 | + |
| 100 | +花费了近一下午,打了5-6次电话,和不同的客服沟通和练习口语,最后的结果就是隔天再去加拿大邮政试试,不行就等他们罢工结束再寄。 |
| 101 | + |
| 102 | + |
| 103 | +## <span class="section-num">5</span> 糟糕设计的代价 {#糟糕设计的代价} |
| 104 | + |
| 105 | +这次经历虽然令人沮丧,但也印证了软件工程的一条铁律: |
| 106 | + |
| 107 | +****糟糕的设计最终会让所有人付出代价——无论是用户还是开发者。**** |
| 108 | + |
| 109 | +讽刺的是,人们总希望通过「学习别人的错误」来避免踩坑,但现实中,我们往往被迫为别人的设计缺陷买单。 |
| 110 | + |
| 111 | + |
| 112 | +### <span class="section-num">5.1</span> 单点故障与「Happy Path」陷阱 {#单点故障与-happy-path-陷阱} |
| 113 | + |
| 114 | +电话退货这个操作虽然看似落后,但是总体来说还是可以用的,在不出问题的前提下。 |
| 115 | + |
| 116 | +Telus 的退货流程设计暴露了一个典型的系统脆弱性: |
| 117 | + |
| 118 | +****强依赖单一服务提供商(Canada Post)**** ,且未设计降级方案(如备用物流或线下门店退货)。 |
| 119 | + |
| 120 | +这种「Happy Path Only」的思维,本质上是对分布式系统设计原则的违背: |
| 121 | + |
| 122 | +****任何外部服务都可能失败,而系统必须对此容错。**** |
| 123 | + |
| 124 | +让快递直接成为业务系统的「单点」故障,只考虑 Happy Path, 没有考虑异常场景,甚至发过来的退货邮件指引,都可以看出他们是把 ****Canada Post**** 写死在邮件。 |
| 125 | + |
| 126 | + |
| 127 | +### <span class="section-num">5.2</span> 向后兼容性:一个被忽视的底线 {#向后兼容性-一个被忽视的底线} |
| 128 | + |
| 129 | +退货强依赖加拿大邮政这个还可以说成是产品设计的问题,但是直接把我邮箱地址给改掉这个,就一定是程序员的锅了。 |
| 130 | + |
| 131 | +此外,我的邮箱地址在 APP 中显示的是 `[email protected]`, 只有在修改邮箱地址的时候,才会显示出 `[email protected]` 这也是我一直没有发现的原因。 |
| 132 | + |
| 133 | +但最令人匪夷所思的是邮箱地址的非兼容性变更:系统直接静默移除了存量用户邮箱中的加号: |
| 134 | + |
| 135 | + |
| 136 | + |
| 137 | +这种粗暴的修改方式违反了最基本的向后兼容性原则,而问题的暴露方式(APP显示与修改界面不一致)进一步说明: |
| 138 | + |
| 139 | +其系统内部还存在的数据状态不一致性问题 |
| 140 | + |
| 141 | +合理的变更方式应该是: |
| 142 | + |
| 143 | +1. 增量控制: |
| 144 | + - 禁止新用户注册或修改时使用特殊符号,但保留存量数据, 保证增量用户地址正确 |
| 145 | + - 存量用户修改邮箱地址时,禁止使用带特殊符号的邮箱地址 |
| 146 | +2. 存量迁移: |
| 147 | + - 通过离线数仓,查询出所有带特殊符号的邮箱地址,通过异步任务批量通知受影响用户(避免阻塞主流程) |
| 148 | + - 提供自动清理特殊符号的“一键修复”功能(需用户确认)。 |
| 149 | +3. 监控兜底: |
| 150 | + - 建立异常邮箱地址的监控或者报表,直到存量问题归零。 |
| 151 | + |
| 152 | +虽然这做法非常繁琐,但是却可以保证系统升级绝对不影响用户。 |
| 153 | + |
| 154 | +系统设计与维护就是如此:开始做的时候成本很低,越到后期成本越高。 |
| 155 | + |
| 156 | + |
| 157 | +## <span class="section-num">6</span> 个人感悟 {#个人感悟} |
| 158 | + |
| 159 | +除去别人的设计错误之外,我还有些额外的个人感悟: |
| 160 | + |
| 161 | +虽然 Gmail 支持邮箱地址中增加一个 `+` 这样的功能,但是并不是所有的公司都支持这特性的,重要的邮件还是不能使用这个「奇技淫巧」。 |
| 162 | + |
| 163 | +此外,我另外提供的邮箱也无法收到邮件,可能是我的邮箱太长了,导致客服没有拼对我的邮箱,所以最好还是准备一个短的,包含数字的备用邮箱地址,方便电话沟通时提供给对方。 |
| 164 | + |
| 165 | +整个故事再次印证了《[软件设计的哲学](https://ramsayleung.github.io/zh/post/2025/a_philosophy_of_software_design/)》中的道理: |
| 166 | + |
| 167 | +****所有偷懒的设计,终将以更高的成本偿还**** |
| 168 | + |
| 169 | +当然, 谁来还就是后话了 |
0 commit comments