百工屋:裁缝的新口袋,为什么要等钟表师?
百工屋里,裁缝做衣服,面包师烤面包,钟表师修钟。大家共用一个仓库、一间账房,也共用一本每次改动都要重新核对的《百工册》。
平时,这种安排很省事。客人只要在柜台说一声,订单就会沿着屋里的走廊传到该去的地方。
直到裁缝做了一个新口袋。
第一幕:一只口袋卡在一本册子里
那天下午,裁缝把样衣拍在柜台上。
"这种口袋装得更多,明早就能交货。仓库给我一块厚布,验货时按这个尺寸看。"
松鼠翻开《百工册》,先看了看订单,又看了看账房和仓库的登记。
"你这个改动,今天还不能做。"
裁缝皱起眉:"只是多缝一层布,怎么还要等?"
松鼠没有回答,只把订单推到她面前。客人订的是一件旧样式的外衣,账房按旧样式报了价,仓库也已经留好了旧布。
"如果现在只改你的这一张,"松鼠说,"柜台答应的是一种衣服,仓库发出去的是另一种料,验货的人还会按旧尺寸检查。到明早,谁都能说自己没做错。"
裁缝看向楼梯:"那就把账房、仓库和验货的都叫来,改完再做。"
松鼠点头,转身去找人。可就在这时,楼上的钟表师也送来一张纸。
他要更换一组齿轮,旧齿轮已经磨损,明天一早必须装回钟里。
"这又和我的口袋有什么关系?"裁缝问。
"按屋里的规矩,"松鼠说,"今天只换一次《百工册》。既然要改,就得把今天所有改动一起核对。"
大家只好围到长桌边。裁缝重新量口袋,仓库核对布料,账房重算价格,验货的人补上新尺寸;楼上的钟表师则在另一头确认齿轮的编号。
口袋很快谈妥了。齿轮却卡住了。
天色一点点暗下来。裁缝拆了又缝,钟表师找了又找。客人第三次派人来问,样衣还没有离开柜台。
水獭忍不住问:"能不能先把口袋这一项换上,齿轮明天再说?"
松鼠摇头。
"那仓库看哪一版?账房收多少钱?验货照哪个尺寸?册子只换一半,屋里就会有两套规矩。"
最后,他们撤下钟表师那张纸,先恢复旧齿轮的记录,再重新核对口袋涉及的布料、价格和验货标准。夜深了,裁缝才剪下第一块厚布。
第二天,衣服总算按时交了出去。
水獭困得睁不开眼。他在门口遇到老河狸------这位建筑师平时负责修屋顶、画工坊的图纸。
"明明只是一个口袋,"水獭问,"为什么整座屋子都要跟着等?"
老河狸正要回答,仓库里先传来吵声。
兔子抱走了明早宴席要用的面粉,獾追出来说,那袋面粉早已留给另一张订单。昨晚为了赶口袋,水獭临时改过一张领料单;今天兔子又照老习惯自己进仓库拿货,两笔订单撞在了一起。
水獭看着满地的面粉,又看了看挤在一条走廊里的几个工坊。
"是不是这座屋子太挤了?"他问,"要不把仓库和其他工坊分开,各自住一座屋子?"
老河狸把《百工册》合上。
"先别急着拆屋。我们先把几件事问清楚:谁能进仓库,谁能改领料单,谁来确认一张单子已经交给了下一个人。"
第二幕:先给每个工坊装一扇门
老河狸没有拿锤子。他把所有工匠叫到长桌边,让他们一间间说清楚自己的工作。
仓库由獾负责,领料从窗口提出;订单由松鼠核实,改单先经过松鼠,别人不能随手涂改账目;裁缝决定自己的做法,同时把需要的材料和验货要求交代清楚。
"以前伸手就能拿,"兔子抱怨,"现在还要登记、排队、走指定的门。"
獾把面粉放到窗口。
"这袋是你的。旁边那袋已经留给明早的订单。你不用知道它在哪个架子上,只要知道我已经替你留好了。"
几天后,货架重新编号。兔子仍从同一个窗口领到面粉,却不必知道仓库怎样摆放;松鼠整理账本,也不要求裁缝跟着重学制作单。
再换《百工册》时,各工坊先检查自己的部分,再核对交接处。册子依旧整套更新,需要所有人同时猜测的事情却少了。
水獭这才明白,墙和窗口不是为了把大家隔开,而是为了让每个人知道:什么由谁负责,什么事情必须经过哪一扇门。
百工屋没有变小,却比从前安静了。
第三幕:山羊想要一座自己的货站
过了几个月,水獭看着清楚了许多的交接单,又想起那晚的等待。
"现在每间工坊都知道该交给别人什么了,"他问老河狸,"是不是可以各住一座屋子,连册子也各换各的?"
"可以考虑。"老河狸说,"但搬出去以后,各家要有自己的炉火、账簿和守夜。隔着走廊就能问清的事情,也得沿着路送消息。"
这时,负责送货的山羊赶来报信。他的远途订单越来越多,货车常在深夜抵达。百工屋的后门连着仓库和厨房,每次装卸,都要请守夜人叫醒獾,再腾出走廊。
昨夜,一辆车在雨里等了半个时辰。山羊把车赶走时,后面的两辆车也堵在泥路上。
"我不是想离开大家。"山羊说,"我只是需要一座不用等整座屋子醒来,自己就能开门的货站。"
山羊带着装卸记录,和大家算过新场地与夜间值班的费用。这一次,大家同意另建货站,请老河狸帮忙画图。
货站建在河边,有自己的炉火、账簿和守门人。山羊可以独自安排夜间车辆,也不必等百工屋换完整本《百工册》才调整货架。
可搬出去以后,山羊和百工屋之间多了一条路。
水獭负责替两边送交接单和收货凭据。第一场大雨里,他带回的两张凭据湿得看不清了。松鼠不知道货站究竟收下了哪些包裹,只好请他再跑一趟。山羊翻出登记册,两人才逐件核对清楚。
从那以后,双方约定了固定的包裹号码、收货凭据和重复交接时的核对办法。
那晚,水獭誊写凭据到很晚。窗外,山羊独自开门接进一辆货车,百工屋那边早已熄灯。水獭看见了货站的好处,也摸到了自己袖口还没干透的雨水。
百工屋的其他工坊暂时留了下来。兔子每天要与松鼠确认订单,缺面粉时也能直接请獾补货,眼下同住一座屋子仍然方便。以后谁需要独立的场地和安排,大家再一起商量。
水獭把百工屋和货站的图纸并排挂好,请老河狸最后看一遍。
老河狸指着两张图说:
"别先数屋子有几间。先问三件事:每间屋子到底负责什么,彼此只能通过什么方式交接,以及其中一间出了问题,会不会把其他屋子也拖住。"
故事之外:三种房子是什么

百工屋里的三种状态,对应三种常见的架构形态:
| 故事里的状态 | 架构概念 | 关键特征 |
|---|---|---|
| 所有工坊共用一座大屋 | 单体应用 | 多个业务模块作为一个应用整体构建和部署,通常在同一个应用进程内协作 |
| 仍在一座大屋里,但墙、门和账簿清楚 | 模块化单体 | 仍然整体部署,但模块有明确职责,通过约定的接口合作 |
| 工坊搬到不同房子,通过道路协作 | 微服务系统 | 服务可以独立部署、扩容和运行,但需要处理跨服务通信与数据一致性 |
第一幕里的《百工册》代表共同的应用版本。订单、库存、报价和验货虽然分属不同模块,却要随同一个版本一起构建、验证和发布。裁缝改口袋时,真正需要协作的是领料、报价和验货;钟表师的齿轮没有业务上的关系,却因为同在一次发布里而被迫一起核对。
这就是单体应用常见的边界:模块之间调用方便,开发和部署相对简单;但当改动变多、团队变大,任何一次发布都可能牵动整座屋子。
第二幕展示的是模块化单体。系统仍然整体部署,但模块有清楚的职责、入口和交接规则。它保留了单体应用的简单性,也减少了内部随意穿透造成的牵连。
第三幕展示的是微服务。货站拥有自己的运行和发布边界,可以独立安排夜间工作;代价是原本在屋内完成的交接变成跨网络协作,需要处理超时、重复请求、消息丢失和数据暂时不一致。
因此,问题不在于屋子大还是小,而在于边界是否清楚、协作是否可控。早期系统通常可以先住在一座屋子里;当某个工坊确实需要独立发布、独立扩容或故障隔离时,再考虑把它搬出去。