说到中台,很多企业尽管都在搭建,但是对它的了解不够深。比如一套系统,为什么不能复用?复用需要一个体系的设计,一个组织的支撑,一个相互信任的团队文化,一个不断完善的过程。本文来自微信公众号:人人都是产品经理(ID:woshipm),作者:菜根老谭,头图来自:视觉中国
最近一个项目汇报的时候,我下面的一个研发负责人被老板“骂”了一顿,原因是老板认为这个功能之前某某项目,某某系统做过了,为啥要重新开发,拿来用就行,结果这位研发负责人讲不清楚,或者技术人员太实在而不知道该如何表达,最后也把我叫过去数落一番。
我不怪老板,她的想法是可以理解的。站在投入和产品角度,不要重复制造轮子是没有错的;我也不能完全怨我的下属,有些东西的复用和集成的确是不像做PPT那样东拼西凑那样容易的。
双方都没错,那问题出在哪呢?我将这个问题发到社群里,大家讨论的也挺热烈,看来这个问题的确也是大家普遍存在的问题。
有人吐槽老板不懂技术,需要上课的;有人建议需要沟通,需要不断磨他,盘他的;还有人还建议让老板参与几个典型项目,让他多体会体会的;最后我们把问题归结到“信任”二字,原来所有的问题都可以通过“信任”来解决的。
的确信任可以解决任何问题,老板如果一点不懂,他可以信任他的CTO能很好的解决这个事情;如果老板很懂,他就会亲自解决这个问题了。
今天我们不讨论老板的问题,他的需求本身没有问题,如果我是老板我也会要求不做重复投入。本文我更多要站在技术领导者的视角去尝试解析这个问题,寻求一定的解决方案。
系统复用为什么难?
还是从事例说起。我们做医疗行业的应用系统,健康档案的管理是一个非常普遍的功能;我们在某系统里已经开发了稍微完整点的模块,于是乎只要其他应用要开发健康档案的功能,老板就会说这个我们都做过了,拿过来用就好了,为什么要重新开发?
我来尝试回答下这个为什么很难复用:
这个系统由于历史原因,是.net开发,而我们团队主流的技术栈是Java,开发语言都不一样,没法复用,只能参考。
虽然都叫健康管理,但是不同的应用系统,他们的差异化还是非常大,慢病管理和专病管理有差异,在基层医疗和等级医疗有差异,即使同构系统,其实也无法直接复用,需要二次改造。
如果这个模块不是以公共组件的方式进行抽象设计的话,它其实和当前系统是紧密耦合的,数据层的耦合,业务逻辑层的耦合,视图层的耦合,特别是代码级的耦合,如果在其他系统复用,首先要去除这种耦合然后在做适应化改造,复用的成本有时候不比重新开发低。
1. 复用是有成本的
DRY原则(Don’t Repeat Yourself)相信每一位程序员都应该知道。其指代的是我们写程序时,不要一遍又一遍地编写相似的代码。当出现某些相似功能的代码时,我们应该将通用部分代码与特异部分代码分离,以达到复用通用代码,降低整体复杂度的目的。
复用这个道理我们都懂,我们也在实际的开发过程中真正去践行的,但复用其实是有成本的,这也是为什么我们知道重复制造轮子不好,但却又不停的的在制造轮子,因为很多时候造一个新轮子比改造一个轮子可能更快,成本更低。
复用有哪些成本呢?
发现可复用组件的成本。很多时候我们并不是不想复用,而是不知道是不是存在我们需要的轮子,从哪里可以找到这个轮子。
正如本文最开始的那位研发负责人,他可能真的不清楚哪个团队有他可复用的轮子,而老板看到的范围更广,所以她更清楚。这个和组织管理和知识管理有关。
学习可复用组件的成本。别人造的轮子有时候很难了解它内部的构造和逻辑,就要去学习别人造轮子的设计和逻辑,这个本身是存在学习成本的,如果对方的设计和实现与自己的思路存在出入的时候,又会非常的别扭。
扩展可复用组件的成本。前人造的轮子都是用在他当时的那个场景或者业务中,当这个轮子切换到新的场景和业务中的时候,你会发现100%的可复用基本上是没有的。
这时候,就牵扯到对于这个轮子的扩展以适用新的业务。先不说这个扩展改造是所有者执行还是使用者执行(后面有一个章节专门讨论组织的逻辑),扩展总是有成本。
修改可复用组件的成本。有时候组件的抽象能力不够,无法扩展,或者扩展的时间成本太高,或者组件所有者不愿意支持,复用者可能采用直接拿过来修改的情况。修改的成本是一个层面,但把时间拉长来看,组件修改后就和原组件分化了,未来双方的新功能也无法相互复用了。
2. 复用是有级别的
一般情况,复用的成本会因为复用的组件的内容不同,所在组织的关系亲密,它的成本是不一样的。比如只是复用一段程序,就相当简单,如果复用一个系统功能就很困难;如果复用同一个团队的组件就相当简单,如果跨团队跨组织的复用就会变得困难,所以复用也是有级别的。
为了更好地理解,我把复用分成了以下5个级别:
级别越低,粒度越小,复用的范围越广,但价值体现较低;级别越高,粒度越大,复用的价值越高,但复用范围也比较局限。
所以站在业务和价值角度上,都是先从最高的层次上去复用。只有上层无法实现复用,我们才会逐步向下层去寻找。但是有时候站在技术角度,我们习惯在低层次上去复用,因为这里最接近自己的工作,粒度越小,技术上越可控。
回到本节开始的问题,B系统的功能要复用A系统的功能,这个复用级别是最高的,如果能复用那会极大减少工作量降低成本,但这个级别的复用难度也是最大的,特别是异构系统,就几乎没有可能了。
3. 复用是有粒度的
影响复用达成时间的因素很多,这些因素叠加起来可能导致复用所消耗的时间更多。因此对于一些时间特别敏感、由其决定生死的业务,在可复用组件未成熟,或者可复用组件支持团队的支持力度不够时,可以不考虑复用。
不复用的情况就是我们通常讲的烟囱系统,现在大环境的论调是烟囱系统不好,其在一个业务成熟的公司里确实不好。
但是烟囱系统在业务早期变化大、快速野蛮生长时,由于不需要考虑复用,没有太多的条条框框限制,提供了高效的开发效率支持,为业务的存活做了重要贡献。
Gartner 在研究报告里提出了宏服务、小服务和微服务的粒度划分:
宏服务:一种传统的 Web 服务,支持将功能封装于单体应用内。宏服务不支持独立部署或扩展, 它们只能部署为单体应用的一部分,而且它们不需要微服务基础架构。
小服务:就服务粒度范围而言,小服务是一种粗粒度、松散耦合、支持独立部署的应用组件。小服务需要微服务基础架构。
微服务:微服务处于粒度范围的远端,是一种可独立部署的组件,能够支持单个应用功能的实施。微服务可直接部署到微服务运行时环境中,也往往具备专用数据存储区。微服务需要微服务基础架构。
如果我们想对已存在系统的能力进行复用,可以采用宏服务模式进行,宏服务的模式适合做系统的集成和治理。
我们对于新的业务和项目,刚开始建议采用小服务的方式进行业务领域的拆分,不建议拆分得过细,这个小服务能满足该需求的基本抽象即可。
从适中的粒度开始,服务的粒度一定是业务推进的过程中不断演化的,创新业务推动服务的粒度向更细的粒度裂变,而业务成熟稳定后,又推动服务向粗粒度方向聚合。站在复用的角度,优先级是宏服务>小服务>微服务,当然难度反之。
所以复用要根据自身团队发展情况,业务实际需要灵活把握,也要根据公司的发展阶段,逐步实现复用。总体来说复用的优先级:技术层面复用优先于业务层面复用,团队内的复用优先于团队间的复用,项目级复用优先于产品级复用。
如何更好地复用
老板要求复用有没有错?没有错!员工说复用太难是不是实情?是实情!作为技术领导者,我们的职责就是解决团队的困难,实现老板的目标。具体如何更好地复用,老谭根据自己的工作经验和对该问题的深度思考,提供一定的思路仅供参考。
1. 不要忽视技术栈的管理
站在复用的角度,不同的开发语言之间是很难复用的,虽然对于互联网或者自运营的信息化而言,还可以通过服务共享的方式实现复用;而对于我们更多以本地化交付的软件产品研发而言,技术体系不统一对于复用和协同简直就是噩梦。
老谭在负责公司研发之前,整个公司没有统一的技术栈,每个部门几乎都有自己的技术栈——当时存在.net,java,php等多种语言开发的系统,主流的Java语言还存在Jfinal、springboot、dubbo等不同的框架。
对于技术团队最容易的代码程序级别的复用因为技术体系的不统一而导致无法复用,团队资源无法流动平衡的问题,这对于我们中小规模的研发团队来说就是灾难。分散的组织必然带来不统一的技术架构,这就是有名的康威定律(后面还会详细介绍)。
结合我自己的工作经历,对于技术栈的管理提供以下思路供参考:
确定团队主流语言,主流开发框架,主流数据库等。我们确定了Java语言为主流语言;springboot为主要开发框架;采用SpringCloud的微服务架构体系;数据库第一选择为MySQL,新项目全部统一到MySQL。
减少非主流技术体系的资源投入,新的业务逐步以主流技术进行。老谭之前团队使用比较小众的JFinal,同样向主流框架springboot切换;减少Dubbo的使用范围;严格控制非Java体系的资源投入,新业务可以采用Java开发的混合体系。
逐步向前后端分离的开发方式转变,大后端体系之后实行大前端。我们做技术的都清楚:后端稳定,前端变化多端,前端的复用的优先级是远弱于后端的;但是对老板们可就不一样——后面的数据库,服务接口啥的他们也看不见,最直观的就是前端,所以不能忽视。
我们最先确定下前端的开发框架VUE,防止前端技术的分化,传统的前端开发根据实际需要有准备实现架构的转变。其实这个转变在前期是需要增加投入的,毕竟两套体系前期要并行,老板质问为何要切换前后端分离,当然她不知道的是,如果我们不转变,我们现在连人(前后通吃)都招不到。
中间件不能滥用,新技术引进需要走技术评审。
技术人员都比较热衷各种中间件的使用,对新技术趋之若鹜,追求新技术没有错,创新也需要鼓励。但这些都需要管理,因为作为技术领导人,我们必须站在团队整体角度平衡成本、效率、效益的关系,所以通过技术评审,我们既能引进新技术,又能管理技术引进带来的学习成本,大面积推广的时机和条件。
通过这一系列的措施,我们至少在技术底层取得了适度的统一,不同团队之间的技术交流就消除了障碍,大家就容易共同积累,促进共享。
2. 统一架构,构建平台级应用
技术栈的统一,只能让我们做到LV1和LV2层级的复用能力,再往上走就涉及到功能层面和业务层面了,而这更接近老板的视角了。所以实现更高层次的复用是每个技术领导人的追求,也是发挥自身专业能力的舞台。
但在这个环节我们往往会出现大问题,就是不能根据实际情况因地制宜,架构体系的弹性很大,没有严格的标准,只有根据实际情况的平衡,平衡是考验技术领导人的架构艺术,不要小瞧了这个能力。很多大厂的牛人去小企业做架构,太多失败的案例,不是架构不好,是没有用对地方。
1)对于小团队而言,统一架构体系,单体应用一样很美
我们一贯的常识就是:越是独立的,没有太多耦合关系的组件越容易复用。过去烟囱似的单体系统难以复用,就是模块和系统本身耦合太深而造成复用改造的成本很大——这个理论是对的,但我认为不全面。
完全去除耦合是不现实的,只是耦合的深浅和范围是需要管理的,如果复用组件的使用者一样耦合在同样一个环境中,其实也是可以复用的。这就像A系统要复用B系统的模块其实是很困难的,因为耦合的环境不一样,依赖的基础不同;但是A系统内要复用自身系统的某模块却非常容易,因为依赖环境是一样的。
所以,小团队如果在代码层级能够统一成一个应用,然后通过插件化、代码级的组件化对业务模块进行抽象和管理,单体系统依然是很美的。
我在七八年前带一个小型互联网团队,自己花了两三个月时间写了一套基于JFinal(当时刚开始推出的小众框架,现在已经非常流行了)插件化的脚手架系统作为我们团队所有业务开发的载体,这么多年过去了,这个系统依然在健壮地运行,业务也在不断持续的开发着。
我们实施的泛微最新一代的OA系统,如此庞大的系统,通过部署结构来看,其实也是一个大单体应用。所以,不是单体系统不好,只是当它太大以后,我们没有能力管理好它而已。
2)有一定规模的技术组织,构建统一平台底座
复用的成本以及难度往往都是组织规模扩大,尤其分化后才迅速提升的。
在一个多组织中实现组件的复用需要建立统一的标准,也不要完全去除依赖,而是尽可能依赖单一;大家都依赖这个单一的东西,这个依赖对复用的影响就会降低;所以一定规模的技术组织,要通过构建统一的平台底座,将共享组件沉淀在平台底座上,让不同的业务共同依赖同一套底层的环境,通过平台底座的共享能力,实现各垂直业务的横向交流和协同。
这种模式特别适合软件产品研发的企业,构建在厚实的平台之上的产品研发,既高效又善于组合和扩展,产品的边界不会因为系统的隔离而变的僵化。而且构建平台底座既适合单体架构的应用也适合分布式的微服务架构,平台底座其实一个组织有规划的复用的体系建设。
下图是笔者团队建设的平台体系,后台引擎由架构团队主要负责建设,业务组件(属于中台范畴)由各研发团队根据业务领域分别负责构建,供作参考:
3)企业级的复用体系——中台架构
中台的广义上的定义:企业级能力复用平台。虽然我们的一体化平台涉及到中台服务部分,但是作为研发企业,我们的中台架构和服务是面向客户去交付的,帮助甲方客户构建中台能力。
一般情况我们所说的中台,不是厂商的中台解决方案,而是一个互联网企业或者一个传统企业为了满足自身数字化转型的需要而构建的中台体系,它是面向企业运营的中台体系而不是面向项目交付的中台服务。
广义上的中台范围是非常大的,涵盖了企业运营的方方面面,而我们更关注的是企业中台的载体,即数字化运营中台。
企业首先通过信息化建设,将企业内在业务从线下搬到了线上,这个阶段我们构建了一个个的单体系统,这些系统集成都不容易,复用几乎就更没可能。最终导致大量的重复开发建设,同时还带了更大的系统治理的成本。
进入数字化时代,甚至是智能化时代,面对激烈的市场竞争,企业降本增效的需求愈发迫切,更好的复用,更敏捷的建设是企业迫切的愿望;中台体系的提出,是顺应这个时代的产物,所以企业关注中台,尝试中台是对的,至于为什么会失败,后面的文章再去探讨。
对于一个有技术开发能力的企业,比如互联网企业,科技企业等,中台的复用能力不要极端追求新建——虽然这样比较简单,但对企业来说着实浪费。如上图所示,首先单体应用架构向业务中台架构演变,能利用则利用,能改造就尽量不要新建,能沉淀就尽量沉淀。
3. 根据康威定律,组织要支撑
被复用的组件需要进行修改定制时,我们需要组件的维护方提供支持,此时就需要相应的沟通协调成本。
若组件提供方与组件使用方没有任何利益关系,甚至于其利益是冲突的,那么组件提供方则缺乏动力为使用者提供支持,甚至于拒绝提供服务。这时候沟通协调成本将会特别大(本文提到的那位研发负责人其实很大程度上也面临这个问题,协调不动组件方修改,自己改又太有难度,与其不如自己造一个轮子了)。
这个问题实际上不是一个软件技术问题,这涉及到组织架构的设计。因此要降低沟通协调成本,则需要更高一级的领导设计调整组件提供方与使用方之间的关系,使其达到利益相关、一致。
如下图所示,每个人在自己管辖的范围之内都相对比较容易复用和协作(对应颜色的横向箭头),而一旦超出了这个范围,复用和协同的难度和成本就会急剧增加:
重温下康威定律:
Conway’s law: Organizations which design systems are constrained to produce designs which are copies of the communication structures of these organizations.
——Melvin Conway(1967)
设计系统的组织,其产生的设计等价于组织间的沟通结构。
已经五十多年的康威定律依然是指导我们做系统设计和企业架构的重要定律,它诠释了系统架构和组织架构的对应关系。其实这非常容易理解:任何事情都是由人去执行的,人的组织结构决定了系统的架构设计,一个分散型的组织很难有高度统一的架构,也注定难以复用。
当然,一个集权化的组织,复用和协作的成本就很低,相反组织的活性会降低,自主性和创新性不足。
老板最重要的任务其实是通过设计组织的结构,来匹配做事情的逻辑,最终实现自己想要的效果,否则在一个人、物、事不匹配的环境里,只有一腔的热血、殷切的希望和愤怒的咆哮也是无济于事,这便是规律的不可违背性。
正如阿里巴巴当年实施中台战略,CTO行癫(张建峰)亲自挂帅负责中台事业群,负责中台战略的推进。同时作为当时整个集团的CTO,在各事业部横向推行中台架构体系又有谁不配合呢?阿里的中台能够成为行业的标杆,这与其组织的设计是分不开的。
最后总结一下:复用是老板的合理需求,是技术领导人的核心职责,是所有技术人的全局意识。但复用的达成,不是老板的念念不忘,不是技术领导人的行政要求,也不是所有技术人的满腹牢骚;它需要一个体系的设计,一个组织的支撑,一个相互信任的团队文化,一个不断完善的过程。
本文来自微信公众号:人人都是产品经理(ID:woshipm),作者:菜根老谭