避免掉进“重造轮子”的坑: 从审核系统说起

简介: 别重造轮子了,大把时光可以去快活呀

作者:闲鱼技术——莫癫

前言

在研发团队发展到一定规模,同一领域问题不可避免地会存在多种解决方案。典型的,不同业务线会开发和使用不同的测试框架,很多业务线会重新开发特征中心、配置中心、规则引擎和投放平台。不可否认有业务特殊性或者已有方案无法满足等原因导致合理建设,其中有重造轮子的现象。

作者在半年前开始投身闲鱼会玩社区治理,从用什么方案、是不是会重造轮子的自我怀疑,到后面沉淀会玩社区的通用审核系统高效应对运营需求的豁然开朗,这段经历颇有收益。本文通过还原这段经历和其中的思考,谈谈在解决相同领域的问题如何避免陷入重造轮子的泥潭,达到高效解决业务问题实现最大技术价值的目标。
Hub_(PSF).png

不要重复自己

软件工程中一个基本原则:DRY(不要重复自己),也就是强调抽象和复用,这是避免重造轮子最基础的要求。运用算法、设计模型和框架设计思想,能从不同角度和不同层次避免重复自己,而长期驻扎业务线的同学还需要对业务抽象,从解决一个又一个的业务问题,转变成解决一类又一类问题的工作方式解放生产力。

不像平台型产品经理在前期就会描绘好产品的完整蓝图,业务线产品经理则更多时候是将用户侧的产品形态或者运营的单点工具诉求翻译成源源不断的需求文档,前后需求之间可能有关联也可能没关联。在时间和空间不连续的需求中,识别出通用流程和可复用能力,提前抽象、规划和设计就变得极其重要而有难度。在闲鱼会玩社区业务起步阶段我们对社区治理方面的需求进行了充分调研和提炼:

  • 紧跟业务目标和政策法规:会玩社区定位为一个纯净、有调性和有氛围的社区,需要运营全面洞察和协作把控社区的人、内容和场。同时网信办加大网络信息整治和处罚力度,对自查自纠的完整全面和及时性提出了更高的需求;
  • 调研行业和竞对解决方案:闲鱼会玩是一个同时承载UGC和PGC内容的社区,同所有同类社区一样,内容、话题和创作者等社区各维度元素在安全防控、分类和原创保护等都有着刚性的审核或标注诉求;
  • 与合作方充分交流:团队内外不乏在业务和技术上沉淀深厚的前辈,这是个吸收别人经验和验证自身想法的很好契机;

这些方式帮忙高效定位业务现处阶段和中长期在同领域的诉求,结合当前需求,可以合理看到需要支撑风险决策、治理和打标等审核或类审核需求,具备业务接入、岗位培训、审核、质检和不断优化效能的通用流程,不同的业务关键指标的诉求也基本一致,只是对人效和实时性的敏感程度不同而已。可以沉淀通用且支持扩展的审核系统承载上述业务,避免自我复制轮子快速接入业务。
image.png
审核业务抽象

不要重复别人

另一种更为常见的重造轮子就是重复别人。澳大利亚的JohnKeogh于2001年申请注册“圆形的交通设施”(轮子)为专利,于当年被评为2001年的搞笑诺贝尔奖科技奖。开源社区以及企业内部的软件轮子频出,不乏几种原因:

  1. 闲暇时间个人学习或兴趣驱动
  2. 不知道已有可用解决方案
  3. 别人东西体验太差
  4. 已有方案不能完全满足需求,无法适配、扩展,或成本过高
  5. 已有实现无人维护或者维护成本过高
  6. 战略原因对战略方向用赛马方式进行内部竞争
  7. 组织架构原因导致无法合作或者合作效率低
  8. 纯KPI原因

在以效益为主要目标的生产企业内部,其中3、4、5、6、7是比较合理的内在诉求。而第4点“已有方案能多大程度满足诉求”实际上决定这个方案是否能解决同类问题,这种情况的存在导致重造轮子的界定会存在一定程度的模糊。所以往往会从多个角度评估重建的合理性和必要性。

在抽象好并确定需要一个通用审核系统后,抉择复用其他团建的基建能力还是从零开始建设,需要花大量精力去调研和评估。在集团内部有迹可循的成熟审核系统有多个。每个审核系统都有清晰的定位,解决垂直领域的问题:

  • 系统A:集团最为普及的工作流系统。有优秀的流程编排能力,但是不支持复杂页面布局、多态审核结果和嵌入各类交互组件,同步不支持处理人效和质量的优化;
  • 系统B:封闭的内容审核平台,只支持接入该生态的帖子审核;
  • 系统C:安全中心的审核系统,定位如其名,主要针对内容安全进行抓黑放白;
  • 系统D:用于知识标注,不具备审核流的协作能力;

可以看到每个系统都能满足业务的部分诉求,却无法通过迭代升级扩展边界和改变其定位,那么重建是不可避免的。

怎么设计和演进是可承受的

论证清楚新建系统的必要性,系统建设成本控制在可承受范围内也同样重要。可承受,不仅包括人力和时间资源投入是否团队可以承受,更重要的是迭代周期是否是业务可承受。以系统建设为理由给业务画饼的方式逼迫业务妥协,即使达成目的,却间接导致业务受损,就丢了西瓜拣芝麻。
在落地审核系统的过程,主要通过系统设计和演进策略的反复优化来降本提效,最大程度按时、保质、保量支持业务发展,同时避免系统腐化、提高迭代速度。

系统设计

在规划初期,只要时间允许,可以尽可能花较多时间在中长期系统规划,保持架构合理。架构确定后最理想需要贯穿很长一段时间的版本迭代,坚持一些原则帮忙审核系统架构在未发生大变化的前提仍在正确的方向迭代发展:

  • 微核心和插件化设计:保持核心组件层足够简洁,支持核心流程和搭建基础的插件容器。扩展功能进行插件实现;
  • 借鉴和遵循成熟模式:剖析和借鉴同类系统经验,成熟的系统沉淀了成熟的方法论,甚至如集团BPMS实现很大程度是工业标准BPMS的一个典型成功案件,XAP是对业内内容审核流程的极大总结和实践,在理论和功能完善性都有很大都体现;
  • 对可扩展和灵活性保持克制:不为不确定的灵活扩展做过度设计,如BPMS使用的流程引擎灵活强大且支持可视化的编排能力,在社区审核仅需线性和有限节点的审核流中则显得鸡肋,反而大大增加系统内核的复杂程度;
  • 重点突破同类系统缺陷:某系统配置不统一、送审强依赖定时圈选无法保证流程实时等,这些已知问题在初期得到重视是可以很好得到解决的;
  • 能力融合:前面提到的垂类审核系统已经在支持闲鱼会玩社区的部分审核业务,通过将其抽象为流程的节点类型之一进行对接,新建系统专注于目前短板能力建设,极大节省能力补全的投入;

image.png
社区审核系统

社区审核系统在经历三个版本的迭代后,目前整体架构并未发生变更和重构,只是对各模块的插件进行补充以支持更多业务场景。

MVP和演进策略

MVP(最简化可实行产品)只需要完成主链路的流转,从数据接入、工单流转并完成简单派单和人工审核功能,这已经可以满足简单标注和初期的业务审核需求,每个模块也只实现百分百必要的能力:

  • 接入侧规约数据协议规范,支持消息输入输出,具备较好的容错性;
  • 基本完备的流程流转内核:即上述抽象的微内核,需要在一期基本完成并保证在后期不会发生较大变化;
  • 派单只需要实现拉单模式,且不需要支持规则化分派;
  • 根据业务诉求,实现最简化的定制化审核工作台;

image.png
社区审核系统MVP版本

演进策略跟MVP遵循的原则无差,都是围绕每期需要支撑的业务,并抽象为规划图的具体位置逐步迭代填充,以完成大图的完整拼图。
审核系统的MVP版本在两周完成开发上线,快速支撑了闲鱼社区圈子的审核,并在后续的迭代中完成安全中心的对接,避免业务侧直接对接安全中心长达一个月的排期和等待更长时间实施上线。后续基本保持每个版本两周的迭代周期,快速支持了后续的需求。

避免被重复

在日常工作中避免因为各种原因重造轮子的同时,也有义务尽可能地去避免内部在相同领域出现重造轮子的行为。抛开为了造轮子而造轮子的行为之外,很多轮子的产生原因更多是客观因素导致,在一定程度上是可以尽可能去规避:
 • 合理的架构和实现:相信很多大部分系统设计初衷都是为了解决一类问题,而不是解决一个问题。往往会因为各种原因达不到理想的状态,需要花足够多的经历进行前期设计,保持内核的开闭、插件功能的单一职责等,遵循良好的设计模式,并定期回顾优化;
 • 打破信息烟囱: 在合适的阶段进行总结和思考,用分享或文章的方式传播给大家,与外界发生互动。也就尽可能避免了其他团队不知道轮子的存在而选择另起炉灶;
 • 避免烟囱式系统:不具备足够的开放能力,除了完成已有的能力和支撑已有业务,不再探索可能的业务融合,逐渐会成为烟囱系统。很多时候具备保持大门敞开这样的开放性并不够,还需要主动挖掘需求,用各种方式降级业务接入门槛,接入更多业务,达到业务支撑和迭代的良性循环;

举两个例子。一是审核在社区内部业务的支持上,一开始只支持RPC和消息按标准消息格式接入方式,这对业务方有一定的理解和接入成本。在数据对接上实现插件化的数据适配方案,并实现核心业务领域的搜索数据源对接完成插件沉淀,并针对常见主体类型搭建了可插拔组件的审核页面,各域在需求对接只需要进行数据的圈选,免去复杂数据格格式的对接;另外,针对用户认证业务在展现形式和标注能力上适配异构的信息,并对公用的数据源进行对接沉淀为复用组件,不同认证业务关注于对接差异的数据即可。

总结

重复是枯燥无聊的,避免重复和被重复是每个开发者解放生产力和成长的必经阶段。从业务、功能和流程各个维度抽象,并充分调研和论证新建系统的必要性,在前期的设计上做好通用性、可扩展性和功能的平衡,以业务诉求可满足、资源投入和业务节奏可承受为准则制定MVP版本和迭代版本。同时提高系统的开放性,主动拥抱业务和发挥技术最大价值。

相关文章
|
1月前
|
消息中间件 缓存 中间件
缓存一致性问题,这么回答肯定没毛病!
缓存一致性问题,这么回答肯定没毛病!
|
6月前
|
算法 程序员
为何程序员在编写程序时难以一次性将所有代码完美无瑕地完成,而是需要经历反复修改Bug的过程?
为何程序员在编写程序时难以一次性将所有代码完美无瑕地完成,而是需要经历反复修改Bug的过程?
65 7
|
设计模式 消息中间件 JavaScript
干掉 “重复代码”,这三种方式绝了!
干掉 “重复代码”,这三种方式绝了!
36961 2
干掉 “重复代码”,这三种方式绝了!
|
前端开发 JavaScript 开发工具
🎖️我只会使用前端框架开发不行吗?
我们经常看到一个现象:一些前端开发人员可能会在使用最新框架创建漂亮的网站的同时,却在编写基本的CSS样式或创建简单的JavaScript函数方面感到困难。
108 0
|
网络协议 NoSQL Java
稳定运行了多年的网关,偏偏让我掉进了坑
稳定运行了多年的网关,偏偏让我掉进了坑
100 0
|
数据可视化 Oracle 搜索推荐
程序员最终会被自己开发的轮子所淘汰吗?
程序员最终会被自己开发的轮子所淘汰吗?
117 0
代码优雅之道——如何干掉过多的if else
代码优雅之道——如何干掉过多的if else
124 0
|
Android开发 UED iOS开发
一个淘宝的bug,让我弄懂了它的底层逻辑和顶层设计
一个淘宝的bug,让我弄懂了它的底层逻辑和顶层设计
一个淘宝的bug,让我弄懂了它的底层逻辑和顶层设计
|
存储 缓存 数据库
相亲软件开发,引入缓存后常见的问题及解决办法
相亲软件开发,引入缓存后常见的问题及解决办法
|
存储 NoSQL 算法
Redis集群详述(从服务内部讲解,这次看完真的懂了,面试官再怎么问也能轻轻松松!)
Redis集群详述(从服务内部讲解,这次看完真的懂了,面试官再怎么问也能轻轻松松!)
230 0
Redis集群详述(从服务内部讲解,这次看完真的懂了,面试官再怎么问也能轻轻松松!)