【设计模式 08】装饰器:加钱加服务
这一课讲装饰器模式。什么在变功能组合的需求频繁变化排列组合爆炸。怎么挡每个功能是一层皮按需套叠不搞排列组合。产品经理李婷拍在少主桌上的不是报告是一份型号清单。四十七个。“基础款加上各种功能组合已经排出四十七个型号了。上周赵闯又接了个客户要高端木材加环保认证加进口五金加刻字服务。这是一个新的排列组合。”少主看着那份清单上面密密麻麻写满了编号BF-001基础款、BF-001-E基础环保、BF-001-H基础进口五金、BF-001-EH基础环保进口五金、BF-001-EL基础环保加急……以此类推四十七个。这些型号之间有什么区别少主问。核心产品一样就是往上叠功能。李婷翻到最后一页“但现在每加一个新功能我要跟所有排列组合做交叉生成新型号。加一个功能不是加一个是加一排。”少主算了一下基础功能加三个可选项排列组合是七个型号。加第四个可选项变成十五个。第五个三十一个。你现在是四十七个少主说“如果赵闯再卖进来两个新需求——”就是一百多个。我知道。李婷的语气说明她已经算过了。少主没马上答复李婷。他去翻了翻近半年的销售数据。四十七个型号里真正有销量的只有十二个。其余三十五个型号要么只卖过一两单要么根本没卖过。有些型号的差别就是高端木材加进口五金和进口五金加高端木材——功能完全一样只是组合编号不同。更麻烦的是售后。客服部拿着客户的订单来问技术参数如果型号是 BF-001-EHL客服得查对应表才知道这个型号包含哪些功能。四十七个型号的对应表客服已经背不下来了。少主把李婷叫回来。“如果我说基础款就只有一个。每个功能是一层皮客户要什么往上套。不管套几层底层都是同一个基础款。你觉得可行吗”李婷想了一会儿“那型号怎么编”“不编。基础款有一个编号。每个功能有自己的编号。客户的订单上写基础款 环保认证 进口五金 刻字。不是 BF-001-EHL。是 BF-001 E H L。”“客服不用背四十七个型号了。”“生产也不用备四十七个版本的料了。基础款备一批每个功能组件备一批。要什么组合最后一步套上去。”李婷盯着少主看了一会儿“那加新功能呢”“加新功能就写一个新的功能组件。不用管已有多少个组合新组件跟基础款对接就行。”“一百个组合也不用管”“不管。因为组合根本不存在。组合是套的时候临时生成的不是提前定义的。”少主跟李婷说的那个方案——基础款只有一个每个功能是一层皮——在程序设计里有一个名字装饰器模式。每个功能是同接口的装饰器按需叠加。想加功能套一层想减功能去掉那层不存在排列组合。wrapped«interface»FurnituregetDescription() : stringgetPrice() : floatBaseProductgetDescription() : stringgetPrice() : float«abstract»Decorator#wrapped: FurnituregetDescription() : stringgetPrice() : floatEcoCertDecoratorgetDescription() : stringgetPrice() : floatImportHardwareDecoratorgetDescription() : stringgetPrice() : floatEngraveDecoratorgetDescription() : stringgetPrice() : float客户最终拿到的产品其实就是一个俄罗斯套娃刻字( 进口五金( 环保认证( 基础款BF-001 ) ) )。最里面那层始终是同一个东西。孙子说水因地而制流兵因敌而制胜。故兵无常势水无常形。“装饰器做的就是这种无常形”——基础款是水源功能叠加是因地制宜的流向。不需要穷举所有的河道遇到了什么需求就顺势加上哪一层包装。本文所有人物、情节、公司名均为虚构如有雷同纯属巧合。