3.203. 怎样写标准提案
3.203.1. 引言
本文是为一个内部培训写的准备材料,因为以后这个培训迟早要对外的,我写在这里。本文介绍怎么给标准写提案。
我会用一个和技术无关的例子作为类比。这是我在公开的地方写东西惯例。最早的时候是为了保密,避免技术泄露。但渐渐我发现,这不但可以防技术泄露,还有更大的好处,它可以让我们更聚焦Pattern(模式),而不是问题本身。
昨天晚上有一个读者私信和我讨论王守仁的“破山中贼易,破心中贼难”是什么意思,说我也经常谈到这个贼,问我背后有什么深意。我就很好奇,我怎么就喜欢谈“贼”了?然后他给我发了这幅图:
我实在没有想过还可以从这个角度来发现我在“偷”方面这么有心得的。这是一个例子:你要找Pattern,你怎么都能找到Pattern,要想突出你自己的主题,不是容易的事情,越是用大家都熟悉的例子举例子,大家就越是看不到你想突出的Pattern,因为他们看见自己熟悉的东西,总会忍不住想强化自己的熟悉的知识,这样反而离开你本来想强调的东西。比如你用数据库举例说明接口定义的重要性,熟悉数据库的人会不断纠结于这个SQL语句where中使用两个index查找性能不高,这反而影响了表达。
所以,我们还是用一个非技术的例子来说明我们的问题,但在关键的地方补上一两个技术问题作为提示,这样的效果反而更好。
本文用一个连锁加盟奶茶店的认证标准来说明写标准提案的方法,笔者对如何运作奶茶店没有任何认识,我们大家就用一般吃瓜群众的思维,来一起考量这个问题下,怎么看到标准提案写作的问题。
3.203.2. 什么是标准和提案
标准是一套有目的的,明确的要求。比如我们对所有要加盟同一个品牌的奶茶店进行认证,我们就会对它的店面形象,财务方式,原材料获取等等方面,提出要求。这就构成一个标准。我们通常用一个标准委员会去控制这个标准,允许什么规则可以加进来,不允许什么规则加进来。
一般标准委员会都是基于技术的,所以通常就叫Technical Steering Committee,简称TSC。
提案是对标准做出增减的申请文本,用于TSC去决策是否接纳这个修改。在提案通过后,提出者还需要给出明确的修改内容。这个具体的修改,称为一个Patch。提案是Patch的前提。
理论上,我们可以认为标准的定义一开始是空的,第一个修改的人提出了第一个提案,然后提供第一个Patch。但通常TSC是有人写了初稿以后才组建的,所以这里并非那么绝对的。但大部分提案是基于一个已经存在的标准的,这是一个现实。
标准体现出来是一组原则,但背后是有目的的。比如我们在标准中定义一个要求,全部认证的奶茶店都需要用绿色的的店面配色,背后可能就有“形成统一的视觉冲击,从而带来群体效应”这个目的。在标准中不一定会写这个理由,在标准中可能是这样一个定义:
“店面装修必须符合如下配色定义:……”
它不会说明:“这是为了形成统一的视觉冲击”。这一点不写在标准中,但提案中必须呈现这个目标。(部分标准会包含一些commentary的段落,用于增强读者对定义的理解,这是一个好的实践,我们也鼓励,但commentary不是标准定义的主体)
3.203.3. 目标和防线
这样我们就谈到提案最基本的写法了。很多人发提案前,第一件事找我要Template(模板)。Template我有,但我一般不会随便提供Template,因为我担心要Template背后的用心——你必须非常清楚,Template不是我们的重心,我们关注的是你的目标,和你为实现目标采取的方法。如果你保证不了这一点,即使你填满了Template要求你写的每个章节,这个提案都是不及格的。
所以,要写提案,别的先不管,请首先把目标大大地,清楚地,明确地写在整个提案的最前面。TSC没有时间给你猜谜语,TSC成员都很忙,评审你的提案是因为这能增强这个标准,能让所有的参与者收益,所以我们首先需要判断的是,你给出的目标是否符合我们的期望,如果这个目标我们不关心,从一开始这个提案就会被打回,我们互相不要浪费对方的时间。
目标确定以后,后面的所有东西都是证明这个目标。这涉及到我们的第二个要求:请首先保证你的每步证明都是“没有破绽”的,然后才开始进入细节。
所以,不要用写标准的写法来写提案,比如你的目标是解决加盟店互相竞争导致员工都不能放假问题,不要上来就说:“所有加盟店都要星期二放假,如果当周有法定假日,分两种情况,如果法定假日在星期二,则如此如此,如果法定假日不是星期二,则这般这般……”,我们看提案,看到这里逻辑链就已经断开了,根本就没有兴趣去看你的细节。
正确的写法是:为了让加盟店员工都能得到有效放假,我们采取如下策略:
统一开门和关门时间
统一放假时间,避免互相竞争
这是你的第一层逻辑,我们从这一层开始就开始挑你的破绽了。比如说,有人会挑这个刺:如果这样做,我们统一放假的时候,竞争对手正好就在这个阶段填补我们的市场空白怎么办?
那这个策略就没有这么简单了,它需要变成这样:
店面分成A、B、C、D四个时间段类别,覆盖不同客户群的要求
根据地域分配A、B、C、D加盟店的类别,不同类别的加盟费用不同,同一个店面不得属于两个类别
不同类别加盟店必须严格按规定所定义的时间段类别营业,否则将按详细定义的罚则进行处罚
这个定义也有可能有破绽的,而且不一定是暴露在这一层,可能在定义时间段的时候,细节上触犯国家劳动法等等,所以,这是一个经验和权衡的工作,TSC根据自己的专业经验,判断这一层的定义是否还有破绽,才会进入下一层。所以TSC才需要由来自不同背景和利益体的人组成,这最后都是为了保证最后落实为细节的时候,这些原则仍可以成立。
所以,每层的逻辑定义,本质上是围绕目标建立一个防线,防住所有包括TSC成员在内的所有标准成员的攻击,直到没有破绽了,这个提案才会被接纳。
所以提案可以分次提交,第一次提交的提案可以只包含一层逻辑防线,等你防住了第一波攻击了,可以再补充第二层的逻辑防线。直到满足要求。当然,如果你对整个设计有信心,一次完成所有定义再拿出来讨论,这也没有问题。
简单总结:请保证明确定义你的目标和分层定义你的逻辑链,保证每层包含定义全集,不要在某层定义没有覆盖全部可能性的时候,就开始进入细节讨论,因为在高层逻辑还有破绽的时候,底层逻辑定义可能全部都是浪费的。
3.203.4. 概念空间
这个小结我们讨论撰写的具体细节,第一个要求,请确定你使用的概念空间,减少使用你自己专业领域的专用概念。标准本身也是一个逻辑链,只是不一定给理由。所以标准会定义自己的概念空间。比如奶茶店这个问题,什么是店面UI,什么是配方,什么是一级加盟店,什么是二级加盟店,什么是午餐类食物,什么是零食类食物,这都有定义。这些定义在不同的上下文中,会形成非常细致的要求(比如“下午三点后不得在二级加盟店销售午餐类食物”),它们的引入,都是为了解决之前提案中各个目标的问题。
所以,你要加新的提案,要尽量使用已经存在的概念,如果这些概念不够你用,你要加入新的概念,就必须详细定义这个概念的意思。我们这里不是要求无限度去为定义而定义。但如果你用到的概念涉及到和别人的定义相关的部分,你轻易不要引入你的概念,因为这些概念已经和每个具体的要求密切相关了。比如你平常在店面经常把食物分成堂食和Takeaway,这个甚至我们都知道,但如果你定义“堂食的零食不打折”,你这个怎么叫堂食就不能随便用,因为我完全可以打包以后坐下来吃,这都不容易说清楚。但说不清楚就很难确定这个设计到底是否可以接纳了。所以,事实中可以用的概念,不见得在“标准”中可以用。我们不是要求你像老学究那样无限细化去定义所谓“严格”的定义,但你至少要知道,现有的定义已经被很多细节所控制了,它无法允许你随意去发明新的定义,特别是不允许你的定义和已有的定义有半重叠,半区别的含义。
在有了概念以后,请注意描述一套原则或者设计的时候,不要切换主语。这是我经常看到有人犯的错误,他们喜欢说“原料配送车从总部出发,先遍历所有一级加盟店,一级加盟店接收原料后,交给后厨,后厨先加水放冰箱中存储……”,这个设计的主语一直在切换:配送车,一级加盟店,后厨……
这样的写法就会出现前一个小节我们提到的“破绽”问题,因为这样的表述方法下,要求每个对象都是“乖孩子”,随时都准备好了支持你这个规则定义。问题是,每个实体都有其他的规则在左右的,比如加盟店还要遵循放假原则,还是需要遵循清洁规定,不是等在那里等你来送货的。
在真正的技术方案中,每个处理器,每个总线控制器,每个中间件,每个Socket,甚至每个变量都是有自己的设计原则的,你的方案行不行,关键在于这些实体每个的状态机是否仍可以维持自洽,不是单独你这个流程行还是不行。
我们可以看你某个流程,但在挑破绽的时候,我们是看每个实体的独立状态机是否仍能保持原来的切换的。你不对每个实体单独建模,这个工作其实就是抛给读者了。这个提案相当于没有完成,这种提案是无法被接纳的,除非你的提案带来巨大的利益,值得TSC给你投入时间,帮你完成这个建模。
3.203.5. 使用继承和泛化
每个提案,都是一个设计,每个设计,就会破坏一组已经存在的原则。一个相对成熟的方案,里面包含大量的细节,修改这里面的原则其实是非常困难的。
所以轻易不要发明全新的概念和原则,而复制已有的概念去做变更。比如说,我们给出了一级加盟店和二级加盟店的概念,这背后有利益平衡的问题(多给钱多收益,少给钱也能收益),也有法务的定义在里面(多少保证金才不会被认为非法集资),也有财务的定义在里面(如何操作资金才会最少)。所以,如果你想改变利益平衡,你尽量不要再定义新的概念,比如“金牌客户联盟”,然后定义一组新的原则给它,这样你原来定义好的财务和法务策略就全都没法实施了,这个成本非常高。这种定义对架构是毁灭性的,这样的提案很难被接受。
所以,更应该考虑的是增加一种“0级加盟店”,这是一种特殊的“一级加盟店”,这样,就比较容易加入到原来的概念空间,而不会产生巨大的冲击。
用好继承和泛化来在名称空间中增加细节和独立逻辑,这是能正常增加新概念到标准中的基本方法。
3.203.6. 撰写Patch
撰写Patch其实就是写标准本身。我们首先要求写作者先下载最新的的标准版本,因为在你发出提案的时候,其他人也在准备提案和修改标准。所以,保持你在提案的邮件列表中,我们不要求你阅读所有的提案,但请知道谁和你同时在修改相关的部分,请提前和他沟通,保证你们的修改是不会冲突的。
同时,请仔细阅读一次当前的标准描述,保证你知道标准作者所处的立场。你写提案的时候,你是站在你自己(和你的利益相关方)的角度来写你的观点的,但当你开始写标准,你是站在整个领域的领导者的角度来写这个标准的,保证你的修改仍保持这个角度,保证这仍是一个人的文档,而不是一个“七嘴八舌”的大杂烩。
3.203.7. 写在最后的话
最后,欢迎大家都提交提案。但也请大家主意,提案的折损率是非常高的。每个提案提出来,需要面面俱到分析很多很多的场景和细节,到最后写到标准中,很可能仅仅是寥寥几句话。而且也许你的提案做了很多设计,但最后有一个细节过不去,这个提案就会被否决。
但您的工作不会白费,一个成功的标准,就是大量这种“失败”的推演去支撑的,您的工作是支持这个标准成功的一份力量。我们备份每个提案和相关的讨论(所以我们要求所有正规的讨论都必须在邮件列表中),TSC非常不愿意否决一个付出巨大工作量的推演和分析,但TSC为架构成功负责,不敢收入会动摇整个定义逻辑空间的或者限制未来发展的提案,这需要每个提案的作者理解和支持。
Welcome to join the party!