本文来和大家分享制作 CBB 公共组件的一些心得

在创建 CBB 的时候的两个核心问题是:让开发者开发的开森;让使用方使用的开森。前者就是本文的讨论内容,后者基本都是靠 API 设计

让开发者开发得开森,就涉及到开发策略的不同

在创建 CBB 的时候我尝试有两个不同的策略,本文将和大家讨论使用这两个不同的策略在开发效率以及 CBB 推动上的不同差别

下面先来和大家聊聊这两个不同的策略

第一个策略是在创建的 CBB 独立仓库项目里面进行开发,然后开发完成之后再进行项目的接入

第二个策略是在具体的项目里面开发,在开发完成发布之后,再将逻辑抽取为公共组件,放在公共组件仓库

采用这两个策略不意味着从始至终都需要采用某个策略,可以灵活根据需求在开发过程中进行切换。接下来讨论这两个策略的优缺点

第一个策略在独立的仓库项目开发,此时为了确定功能,大部分都是需要通过额外的 demo 以及单元测试的辅助。因为是放在独立的仓库里面,也就很难会耦合业务,也不会耦合具体某个项目的功能,做出来的功能相对通用。而且调试起来很轻,不需要加载具体的大项目,只需要跑起来 demo 即可。而在此过程,可以愉快添加更多的单元测试,用于多个入口的进入。而这些 demo 和单元测试,在开发完成之后,可以反馈给后续的维护阶段,在维护阶段中,可以用上这些 demo 和单元测试来提升维护的效率。使用策略一可以脱离业务端进行开发,可以编写出覆盖更多的范围的测试用例而不会被限制到具体项目的某些业务上,对于其他项目的接入会更友好

但是也因为第一个策略是在独立的仓库项目开发,因此大部分的我的这些项目都会在经过一段时间开发之后,再接入具体项目时,出现了业务需求的不匹配,或者 API 设计的不合理问题。在进行业务端的对接的时候,也会遇到业务端的开发者为了快速对接,而做出依赖坑的行为,有小部分逻辑是放在业务端编写,这就导致了采用策略一实现的组件其实是有部分逻辑是放在某个具体项目的,这样其实对于其他项目的接入不友好。在进行业务方接入的调试,就需要用上一些辅助工具,才能愉快的调试,而不是和策略二一样,放在具体项目里面,开发调试方便。而且在独立项目里面,使用的是独立仓库自己的 demo 或单元测试,也许在接入复杂业务的时候,会有一些诡异的情况会降低业务方开发者的心情。而在也会因为功能没有在具体项目里面经过充分的测试,此时的公开出去的独立仓库逻辑的质量应该是不如采用第二个策略的,果有其他开发者在其他项目用到这部分新功能,预计他将会踩坑,特别是在沟通不够的情况下,也许就会存在相互的甩锅

第二个策略是在具体项目里面开发,适合于功能有限或者刚起步的功能的开发,在具体项目里面开发,可以更贴切具体项目的业务。也因为是放在具体项目里面开发,几乎没有接入成本。可以在具体项目测试发布之后,再进行抽离,此时可以保底这个 CBB 部分的功能的稳定性。而且基本上此时的抽离都会是独立的 CBB 维护者协助抽离,可以辅助业务端开发者设计的不足。业务端开发者可以使用更少的设计知识而开发出公共组件,由专业的 CBB 团队进行抽离再设计。而在抽离的时候,也因为 CBB 维护者不了解业务,需要和业务端开发者组队抽离,在此过程可以辅助培养业务端开发者的设计能力。一开始就放在独立的仓库里面,对开发者的设计能力要求比较大,也许会出现开发的很开森,但是实际上用不了的情况。先满足业务,然后进行抽离,在抽离的过程可以给自己的设计进行反馈。同时经过我的测试,在全新功能的起步,采用此策略能提升具体项目的开发效率,因此不需要使用额外的辅助工具,也可以没有引入额外的 demo 或单元测试,减少额外的开发内容,也减少额外的知识量和设计工作量

但是也因为第二个策略是放在具体项目里面,也不小心就耦合具体项目的业务逻辑,甚至导致这个功能的抽离几乎就是重写。而且大部分这些功能都会因为放在具体的项目里面,缺乏 demo 或单元测试,因为不需要 demo 或单元测试的辅助开发,因此后续维护的成本会更高。上文说到了开发效率,采用策略二的在具体项目的开发效率更高,但是如果加上了后续抽离 CBB 的开发成本,整体效率大部分情况会更低,除非是专业的 CBB 维护者可以无需和业务端开发者有多的沟通,而且此部分功能在业务端开发者开发的时候没有耦合多少业务。因为具体的项目大部分都比较大,在进行开发调试的编译效率是远远比不上纯 demo 的,因此编译效率上也不如第一个策略。而因为一开始就放在具体项目里面,在出现坑的时候,不如第一个策略好快速定位是业务端的问题还是公共组件部分的问题

无论如何,在使用策略二在抽离完成之后,后续维护开发都会和策略一相同,也就是说后续维护都会踩到策略一的坑。但如果是一些比较封闭功能的模块,或者说功能是很有限的,那么后续维护次数可以预期会比较少,需求也几乎不变动,那也不算会踩到策略一的坑

我认为采用策略二在团队刚开始玩 CBB 建设的时候,以及在团队已完成 CBB 建设但是有新人加入的时候,就会相对比较适合。原因是在刚开始玩 CBB 建设的时候,一定缺乏足够的经验,而这部分经验是难以复用到不同的团队的,不同团队的开发成员不相同,历史文化也不相同,不一定适合推动。因此采用策略二的方法可以减少对团队成员的干扰,能减少一些阻力,因为一切的开发几乎和之前一样,只是多了一步就是有工具人协助抽离成为公共组件。在有新人加入的时候也是一样,因为一开始如果新人是不了解这一套是如何玩的,甚至没有制作过库,那么立刻使用策略一其实对新人不友好,同时对组件的设计也缺乏经验。不如使用策略二的方式,在新人开发完成之后,和他组队抽离作为公共组件,这个过程也是对新人培养的过程,可以让他了解到公共组件建设的玩法,以及组件的设计,之前自己的设计和组件的设计有什么不同

策略一适合在团队成员对设计有足够的了解,功能模块可以预期后续维护工作时间长的情况。团队成员对设计有足够的了解情况下,能很大减少开发得很开森,但是实际上用不了的情况;也能更好支持多个不同的项目,和保证设计质量。因为对于已发布的公共组件,其实咱是不期望 API 频繁变更的,如果有 API 频繁变更,就意味着每次升级库也许都需要变更逻辑代码来解决构建问题,而变更逻辑代码又会降低软件的稳定性和提升开发成本,因此就需要使用策略一的库开发者对设计有足够的了解,设计出来的 API 尽可能好用和减少变更。如果功能模块可以预期后续维护工作时间长的情况,那么单元测试或 demo 是必不可少,此时咱也期望库的逻辑在修改的时候,能够有经过充分的测试。而如果是采用策略二的从业务端抽离的,很多时候都会有部分逻辑是只有在业务端才能有,而在库里面的单元测试和 demo 里面是缺失的,这是因为在抽离的时候,很多时候都不会完全模拟业务端的逻辑,这样的问题就是在库里面的变更需要在某个业务项目里面才能进行足够的测试,如果换一个库的开发者不一定了解到足够的坑,不利于维护。因此一开始就在独立的仓库里面进行开发,可以保证自身的单元测试或 demo 有足够的覆盖,可以脱离具体业务项目进行足够的测试。当然这也不是绝对的,如果在独立的仓库进行开发,但实际上调试等都是放在某个业务项目里面,那么这个坑还是挖了

我现在所在的团队比较成熟,默认都是优先使用策略一进行开发。除非是业务需求不够明确或者需求比较紧急的时候,才会使用策略二,因为策略二可以将开发拆分两个阶段,让第一阶段的开发成本降低,但相信我,如果拆分为两个阶段,经常第二个阶段是没有资源可以投入的。但也有一些例外是,我所在的团队也有维护对质量要求有不同等级的库,对于质量要求特别高的库,合入的逻辑都期望经过充分的测试,而充分的测试包含了在足够数量的用户端运行多个版本。此时的开发策略就偏向于策略二,先不将逻辑放在底层的库而是放在具体项目里面,或者底层的库切换到开发分支,等待项目发布多个版本运行稳定才合入库的主分支

我认为每个团队都是不同的,以上仅仅是我的心得,不见得适合你的团队


本文会经常更新,请阅读原文: https://blog.lindexi.com/post/%E5%88%9B%E5%BB%BACBB%E5%BF%83%E5%BE%97.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。

如果你想持续阅读我的最新博客,请点击 RSS 订阅,推荐使用RSS Stalker订阅博客,或者收藏我的博客导航

知识共享许可协议 本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名林德熙(包含链接: https://blog.lindexi.com ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系

微软最具价值专家


无盈利,不卖课,做纯粹的技术博客

以下是广告时间

推荐关注 Edi.Wang 的公众号

欢迎进入 Eleven 老师组建的 .NET 社区

以上广告全是友情推广,无盈利