先学会重构一个小函数
运费规则:普通地区满 10000 分免运费,否则 800 分;偏远地区始终加 1200 分。你要简化重复代码,同时保留这些行为。练习不接真实支付或物流。
可在 Claude粘贴代码,或在已经配置好的 Claude Code 中打开空练习目录。Claude 模型与 Claude Code 工具不是一回事;普通聊天给出代码后,仍需要自己保存执行。工具入口可参考Claude Code 使用说明。
先把原函数交给助手
将下面的教学起始代码保存为 shipping.py:
def shipping(subtotal, remote=False):
if subtotal >= 10000:
if remote:
return 1200
return 0
else:
if remote:
return 2000
return 800
先自己算四例:9999/普通为 800,10000/普通为 0,9999/偏远为 2000,10000/偏远为 1200。把这些写下来,再让助手修改,才不容易被新实现带着改变原需求。
第一轮请求:保持行为的重构
请重构 shipping.py 中的 shipping,减少重复分支,但不要改变函数签名或四种已定义行为:
9999,False -> 800;10000,False -> 0;
9999,True -> 2000;10000,True -> 1200。
当前输入约定 subtotal 为非负整数分,remote 为布尔值。
先解释普通运费与偏远附加费的关系,再给出实现和独立断言,不新增依赖。
这里不是让模型“自由优化”。明确样例后,重构是否成功可以用相同输入比较。不要在同一轮增加会员、优惠券和配送时效。
可运行的参考实现
def shipping(subtotal, remote=False):
if type(subtotal) is not int or subtotal < 0:
raise ValueError("subtotal 必须为非负整数分")
if type(remote) is not bool:
raise ValueError("remote 必须为布尔值")
base = 0 if subtotal >= 10000 else 800
surcharge = 1200 if remote else 0
return base + surcharge
cases = [(9999, False, 800), (10000, False, 0),
(9999, True, 2000), (10000, True, 1200), (0, False, 800)]
for subtotal, remote, expected in cases:
assert shipping(subtotal, remote) == expected
for args in [(-1, False), (True, False), (100, "false")]:
try:
shipping(*args)
except ValueError:
pass
else:
raise AssertionError(args)
print("四种运费组合与输入边界通过")
保存后运行 python shipping.py。这里额外把输入约定写成显式校验,属于明确增加的边界处理,不要称作完全没有行为变化的纯重构;与旧函数一致的是约定内的合法输入。
如果模型把满额偏远地区也免运费
用这个修订请求:
新实现对 shipping(10000, True) 返回 0,但期望 1200。满额只免普通运费,偏远附加费一直保留。请分开计算两部分,保留原来的四个用例,新增超出门槛的偏远用例 20000,True -> 1200,再运行全部用例。
只给失败一例还不够,要解释业务含义。否则助手可能增加一个专门处理 10000 的分支,20000 又错了。
第二轮:需求真的变化时怎样说
现在才增加“会员普通运费减半”。先说明它只影响 base,不影响 surcharge;再写例子:9999/会员/偏远应为 400+1200=1600。明确这是新增功能,不能要求模型既完全保留旧接口又凭空知道会员身份。
让助手提出向后兼容的参数方式,再检查旧调用是否仍得到原结果。阅读差异时重点看附加费是否被误减半,别只看代码行数减少。
自测与答案
重构后代码更短就更好吗?只有在行为清楚、合法输入结果保持一致时才有意义。短到混淆普通费与附加费,反而更难改。
作业:为“门槛改为 12000”写出受影响与不受影响的样例。参考思路:11999 与 12000 是新边界,偏远附加费 1200 不变。