没有 OOP 的日子:“牵一发而动全身” 的噩梦
奶茶制作间的 “连锁乱局”:改一个配方,全流程跟着错
小林的奶茶店刚开业时,仗着自己做过两年奶茶师,觉得 “流程不用太细”,就把所有饮品的制作要点都汇总在一块 1.2 米宽的黑板上 —— 左边写配料,中间写步骤,右边写注意事项,密密麻麻挤得满满当当。一开始只卖珍珠奶茶、原味奶茶、柠檬茶三种,员工记熟了倒也顺畅;可等旺季来临,他一口气加了杨枝甘露、芋圆奶茶、焦糖奶茶、抹茶奶绿四种新品,这黑板就成了 “麻烦制造机”。
先说第一次大混乱:有位老顾客连续三天来买珍珠奶茶,每次都抱怨 “珍珠嚼着像石头”。小林尝了尝,发现确实煮得不够透,当即决定把珍珠的煮制时间从 15 分钟延长到 20 分钟,还特意在 “煮制时间” 那栏用红粉笔改。可黑板上 “珍珠煮制时间” 旁边紧挨着 “芋圆煮制时间”,红粉笔划过的时候没控制好范围,把 “芋圆 12 分钟” 的 “12” 也描成了 “20”。当天早高峰,员工按黑板上的时间煮了两锅芋圆,捞出来一看全成了糊糊,根本没法加进奶茶里。没办法,小林只能临时下架芋圆奶茶,可已经有 18 位顾客点了这一款,只能挨个道歉、换品,光赔偿的饮品就损失了近 200 元。更糟的是,那锅煮烂的芋圆和浪费的奶茶原料,加起来又是 100 多块,第一天改流程就亏了小 300。
没过多久,第二次混乱又找上门。有顾客反馈 “原味奶茶甜得齁嗓子”,小林统计了一下,一周内有 7 位顾客提了相同意见,于是决定把原味奶茶的正常糖量从 50g 减到 40g。这次他特意用尺子在黑板上划了线,把 “原味奶茶” 和旁边的 “珍珠奶茶” 隔开,可员工操作时还是出了错 —— 负责配糖的小吴那天感冒,眼神有点模糊,没看清划线,直接把珍珠奶茶的糖量也按 40g 加了。结果当天卖出去的 40 杯珍珠奶茶里,有 18 位老顾客喝了一口就问:“今天的珍珠奶茶怎么没甜味了?是不是忘加糖了?” 还有 5 位顾客直接说 “没味道,退了”。小林后来查监控才发现问题,可已经晚了,当天的回头客流失了近一半,接下来几天珍珠奶茶的销量直接跌了三分之一。
最让小林崩溃的是新增 “焦糖珍珠奶茶” 那次。这款奶茶需要在珍珠煮好后,加 20g 焦糖酱翻炒 1 分钟,让珍珠裹上焦糖味,而且要用焦香红茶代替普通红茶。可黑板上 “珍珠奶茶” 的步骤区域已经满了,小林只能在 “珍珠奶茶” 步骤下面空出的小角落,用小字写了两行:“焦糖款:珍珠煮好后加焦糖翻炒 1 分钟,用焦香红茶”。结果员工忙起来根本没注意到这两行小字 —— 有 10 次顾客点焦糖珍珠奶茶,员工直接按普通珍珠奶茶的流程做,没加焦糖也没换红茶,顾客拿到手发现不对,要么退单要么要求重做;还有 3 次,员工给普通珍珠奶茶也加了焦糖,顾客喝着一股焦苦味,直接差评投诉。更麻烦的是红茶的问题,焦香红茶和普通红茶的茶叶罐长得像,又放在同一个货架上,员工经常拿错,导致焦糖珍珠奶茶有时是焦香味,有时是普通红茶味,味道不稳定,老顾客越来越少。
更别说日常的小混乱:比如想调整杨枝甘露的芒果用量,改的时候不小心蹭到了旁边柠檬茶的柠檬汁用量;想给抹茶奶绿加 “少冰减 2 元” 的规则,结果把芋圆奶茶的价格也改了 —— 这些小错每天都在发生,小林每天都要花两三个小时处理投诉、赔偿,精力全耗在收拾烂摊子上。
代码里的 “制作同款噩梦”:改一段逻辑,全功能跟着崩
小林在奶茶制作间遇到的 “牵一发而动全身”,其实就是没有 OOP 时,程序员写代码的日常。就拿开发 “奶茶制作指导程序” 来说,没有 OOP 的话,程序员会把所有功能的代码都堆在一个叫 “milk_tea_program.py” 的文件里,既没有分类,也没有隔离,就像小林那块混乱的黑板。
一开始程序只需要指导制作珍珠奶茶,代码量少,逻辑简单,大概长这样:
# 没有OOP的珍珠奶茶制作代码
def make_milk_tea():
# 煮珍珠
pearl_time = 15 # 珍珠煮制时间15分钟
print(f"煮珍珠,时间:{pearl_time}分钟")
# 泡红茶
tea_type = "普通红茶"
tea_time = 3 # 泡3分钟
print(f"泡{tea_type},时间:{tea_time}分钟")
# 加奶加糖
sugar = 50 # 50g糖
milk = 200 # 200ml牛奶
print(f"加{sugar}g糖,{milk}ml牛奶,混合均匀")
print("珍珠奶茶制作完成")
# 调用函数制作珍珠奶茶
make_milk_tea()
这时候代码还能看,修改起来也方便。可等加上杨枝甘露、芋圆奶茶后,代码就开始 “膨胀” 了 —— 程序员会在原来的文件里继续加函数,把所有逻辑堆在一起:
# 堆在一起的代码:珍珠奶茶+杨枝甘露+芋圆奶茶
def make_milk_tea():
# 珍珠奶茶制作逻辑(略,和上面一样)
pass
def make_mango_sago():
# 杨枝甘露制作逻辑
sago_time = 10 # 西米煮10分钟
mango_amount = 150 # 150g芒果
print(f"煮西米,时间:{sago_time}分钟,加{mango_amount}g芒果")
pass
def make_taro_milk_tea():
# 芋圆奶茶制作逻辑
taro_time = 12 # 芋圆煮12分钟
sugar = 50 # 50g糖
print(f"煮芋圆,时间:{taro_time}分钟,加{sugar}g糖")
pass
# 调用各种函数
make_milk_tea()
make_mango_sago()
make_taro_milk_tea()
这时候问题就来了。有天运营反馈 “杨枝甘露的西米太硬,要煮 12 分钟”,程序员找到make_mango_sago()
函数,把sago_time = 10
改成 sago_time = 12
。可改完后没仔细检查,不小心把旁边make_milk_tea()
函数里的pearl_time = 15
也改成了12
—— 结果程序指导员工煮珍珠时只煮 12 分钟,珍珠没煮透,和小林奶茶店的 “珍珠硬如石头” 问题一模一样,当天靠程序制作的珍珠奶茶全出了问题。
后来要加 “热饮奶茶” 功能,程序员只能在make_milk_tea()
函数里加一段判断逻辑:
def make_milk_tea(is_hot=False):
# 原有逻辑(煮珍珠、泡红茶)
# 新增热饮判断
if is_hot:
milk_temp = 65 # 热饮牛奶加热到65℃
print(f"牛奶加热至{milk_temp}℃")
else:
milk_temp = "常温"
print(f"用{milk_temp}牛奶")
# 加奶加糖逻辑(略)
pass
可这段判断没和其他逻辑隔离开,有次调用函数时,不小心把is_hot
参数传错了 —— 给点 “常温珍珠奶茶” 的顾客传了is_hot=True
,程序指导员工加热了牛奶,顾客嫌烫退单;还有次给 “热饮” 传了is_hot=False
,做成了常温款,又引发投诉。
更头疼的是排查错误。有天程序突然出 bug:调用make_taro_milk_tea()
时,总是打印 “加珍珠” 而不是 “加芋圆”。程序员只能从头翻代码,从 make_milk_tea()
看到make_mango_sago()
,再到make_taro_milk_tea()
,查了 2 个多小时才发现,之前改make_milk_tea()
函数时,不小心把make_taro_milk_tea()
里的 “加芋圆” 写成了 “加珍珠”—— 就像小林改黑板时蹭到其他内容一样,因为代码没分类,一个小失误就导致整个功能出错。
还有更麻烦的情况:如果要给所有奶茶加 “少糖减 1 元” 的规则,程序员得在make_milk_tea()
、make_taro_milk_tea()
甚至 make_mango_sago()
(如果杨枝甘露也有糖度选项)里逐个加判断逻辑;要是漏改了其中一个,就会出现 “有的奶茶少糖减 1 元,有的不减” 的情况,用户投诉不断。这种 “改一个需求,要动 N 处代码” 的日子,没有 OOP 的程序员每天都在经历。
根源:缺了 “制作分类隔离”,自然 “牵一发而动全身”
不管是小林奶茶店的黑板,还是堆在一起的代码,本质上都犯了同一个错:**没有建立 “分类隔离” 的机制,也没有明确 “每个主体的专属责任” **。
在奶茶制作里,“珍珠奶茶”“杨枝甘露”“芋圆奶茶” 是不同的 “主体”,每个主体都有自己专属的配料、步骤、注意事项 —— 就像每个人都有自己的身份证、银行卡,不能混在一起用。可小林把所有主体的信息都堆在黑板上,相当于把所有人的证件都塞在一个抽屉里,找的时候容易拿错,改的时候容易蹭到,自然会 “牵一发而动全身”。
代码里也是一样。“珍珠奶茶制作”“杨枝甘露制作” 是不同的功能主体,每个主体都有自己的变量(比如煮制时间、配料用量)和逻辑(制作步骤)。没有 OOP 时,这些主体的代码混在一个文件里,变量和逻辑没有隔离 —— 改一个主体的变量,可能会误改另一个主体的;加一个主体的逻辑,可能会影响其他主体的执行。就像把不同品种的花种在一个花盆里,根须缠在一起,浇水时要么有的浇多了,要么有的浇少了,很难养好。
更关键的是 “责任不明确”。小林的黑板没有说 “珍珠的煮制时间只归珍珠奶茶管”,代码里也没有说 “sago_time 变量只属于杨枝甘露制作”—— 这种 “谁都能改,改了谁都可能受影响” 的状态,就是混乱的根源。比如小林改珍珠煮制时间时,不用对芋圆奶茶负责;程序员改西米煮制时间时,不用对珍珠奶茶负责,最后出了问题,都不知道该找谁,只能自己收拾烂摊子。
小结:不是做不出奶茶,是做对太费劲
没有 OOP,小林照样能做奶茶,程序员照样能写代码 —— 但代价是 “低效率” 和 “高风险”。小林改一个珍珠煮制时间,要反复核对黑板上的其他内容,生怕蹭到芋圆、西米的信息;程序员改一个西米煮制时间,要通读整个代码文件,生怕改到珍珠、芋圆的逻辑。哪怕再小心,也难免出错,而每次出错,都要花大量时间道歉、赔偿、修 bug,精力全耗在补救上,根本没心思做新品、优化体验。
其实解决这个问题的思路很简单:给每个 “主体” 建一个 “专属档案”—— 奶茶店里,给珍珠奶茶、杨枝甘露各自做一张 “制作卡”,卡上只写自己的配料、步骤;代码里,给每个制作功能建一个 “对象”,对象里只装自己的变量和逻辑。这样改的时候只动自己的 “档案”,不会影响别人,自然就不会 “牵一发而动全身”。
而这个 “建专属档案” 的思路,就是 OOP 的核心。下一章我们就详细拆解,OOP 是怎么给奶茶制作、代码功能 “建专属档案” 的,以及有了这些 “档案” 后,工作效率能提升多少。