谈谈规范

在多年的开发经历中,我发现不重视编程规范是普遍存在的一个问题。很多开发人员对规范的态度都是很抵触的,认为规范的条条框框是枷锁,会降低开发效率。 不仅仅是普通员工,很多公司的管理人员对于规范的重视程度也是不够的,甚至就没有制定规范的想法。 为什么会出现这种现象呢,我想每个人都会有自己的角度,大多数原因可能是因为项目周期紧张,没有时间制定规范,或是单纯的认为规范会影响开发效率。 上面的原因是客观存在的,所以大家对于不制定规范也没有太大的心智负担。今天我想就这个现象谈谈我对规范的认识。 规范一般有两种,一种是项目规范一种是编程规范。 关于项目规范 我在刚开始入行的时候,公司虽然也没有自己的规范,但是带我的前辈,给了我一份谷歌的开发规范,让我学习,代码的书写格式是怎么样的,什么时候应该换行,应该怎么避免写嵌套 if… 这让我对代码规范有了一个最基本的认识。 代码需要书写的简洁,易读。代码规范有点像写文章时的字体工整程度,越遵守代码规范,字体就越工整。你可以想象就算同样的一篇文章,字体工整和字体潦草给阅读人的感受是完全不同的。 后来我在一家公司做管理,刚到公司时也没有自己的规范,每个人的代码风格,变量命名,项目组织的习惯各有不同,导致项目的风格多样,这给我们带来了一些问题。 维护成本高 当我们维护其他同事写的代码的话,需要从头开始阅读一遍代码,才能了解问题具体出在哪。如果我们有规范就不需要通读所有代码,仅需依据规范出问题代码的大体位置。 代码复用差 当我们有一些通用业务需要封装时,如果没有规范,就需要考虑所有的代码风格,甚至要做一些额外的兼容才能把组件封装完成,有了规范我们完全就可以避免这类问题。 项目对接慢 由于没有规范,每次公司来了新同事,我们并没有很完善的文档给到他。导致新同事上手项目比较困难,中间还要不断地去询问老同事,才能对代码有一个相对比较完善的理解。 这无疑增加了很多的摩擦成本,且团队越大,这种摩擦成本就会越高。就像我们都说中文,又各自有自己的方言,大家需要了解每个人的方言体系,才能更好的深入交流。 我们需要“普通话”这样一个统一的说话规范,来降低我们团队内部的摩擦成本。 建立规范 为了解决上述问题,我们结合自身团队的特点,参考了他人的规范制定出了我们自己规范的初版。 初版规范经过内部评审和修改后,我们形成了自己的规范文档。 后续我们在实践的过程中遇到了一些规范上的不足,也进一步对规范做了补充,使规范在原有的基础上不断的迭代和优化。 这样一套规范建立后,使我们每一步都是在之前的基础之上,而不是每一次都是从 0 开始。这让我们可以不断的阶梯向上。 如何让规范落地 规范的制定后就需要考虑规范落地问题,如何让团队更好的遵守规范。 首先需要让团队认识到规范对我们团队合作是有益的。做好心理建设,消除心理的抵制情绪。 把规范塑造成开发文档,让团队养成经常查阅的习惯,对规范有疑惑就去规范文档找答案。 利用工具降低规范的执行难度,像一些代码风格的问题可以通过 IDE 代码格式化解决,不用团队开发者额外注意。 使用静态代码分析工具检测代码是否符合规范,如果使用 CI/CD 可以把这一步集成到 CI/CD 中,让不符合规范的代码,无法提交到线上环境。 关于编程规范 编程规范包括:设计模式,设计原则,编程范式,最佳实践等等。这类规范一般是行业发展多年,一些经验丰富的前辈总结的一些开发工作的规范。 因为这类规范通常是前辈们在长期实践中总结出来的。遵守这类规范能让我们更容易开发出稳定的程序,少走弯路。 这类规范一般都具有普遍性,对语言没有任何的限制,因此一旦你熟练的掌握,你用任何语言开发的程序都会有更好的稳定性,更少 Bug 、更容易维护和扩展。 我发现有些同学会遇到一些奇奇怪怪的问题,或者一段时间后,程序出现了运行瓶颈。有不少是因为没有遵守某些编程规范引发的问题。 有时他们不遵守编程规范,并非不愿意,而是因为他们不了解某些规范。因此对于编程规范,要像探寻宝藏一般,时常去探索一下。不断地完善和补充自己对编程规范的理解。 总结 规范短期看可能会觉得有点浪费时间,影响开发效率,从长期看,却未必如此,那些减少的 Bug, 复用的代码,以及与同事之间协作效率的提升,足以弥补开发时的损耗。 牛顿说:我之所以比现别人看的远,是因为我站在巨人的肩上。 运用前人的智慧和经验,能让我们做事情更加的顺利。要站在前人的肩膀上,哪怕你觉得这个人不够高,也比自己站在平地上看的更远。

September 20, 2024 · 1 min · 云溪

go 语言实现轻量级队列事件

最近再开展整合系统的工作,将原有系统中的共用逻辑抽离出来形成一个中台系统,根据业务开展形式的不同,划分出各个子系统。 在开展的过程中,遇到一种情况,在一些场景下子系统需要根据中台系统的一些操作去初始化自身的业务数据。 我们准备用事件( Event ) 的形式来解决这个问题,子系统监听中台系统发布的一些事件,当中台系统进行相关操作时,触发事件通知监听中的子系统。 我们的中台系统 ( main system ) 是用 go 语言开发的,事件的触发是通过队列的形式发送给 event hadle 然后由它去发送事件通知到各个子系统。 在一些其他语言中,队列的消费一般都是启动一个进程来监听处理。而 go 有协程,可以用更轻量的协程来处理队列消费,这样以来有一个直接的好处就是服务启动了,队列的消费者就跟着启动了,不需要单独维护一个进程的启停。 当然要实现上述能力,有几个问题需要解决: 协程消费者如果崩溃了,不能影响主进程的运行 协程异常要能重新拉起一个新的消费者,保证协程消费者能一直运行。 崩溃隔离 消费者有自己的逻辑,在逻辑处理中有可能会出现 panic,我们需要消费者的 panic 限制在协程里,以避免协程崩溃影响主进程。 Go 有 recover 机制,可以让你捕获 panic 并且限制 panic 不在向上蔓延。代码如下: go (func() { defer func() { if err := recover(); err != nil { fmt.Println("捕获到 panic:", err) return } }() err := EventHandle() if err != nil { Logger.Error("event 处理监听失败", err) } })() 消费者协程保活 消费者业务逻辑在协程里,可能在一些场景(panic 或其他不可知情况)下意外退出,我们需要保证能够重新拉起消费者协程,从而保证整个事件逻辑的闭环。...

January 31, 2024 · 1 min · 云溪

从面向接口编程看标准化问题

面向接口编程: 当一个实体依赖另一个实体时,不依赖实体而是依赖实体的抽象。 比如说生产一个电灯,电灯需要一个开关来控制电灯的点亮和关闭,如果电灯依赖某个具体的开关,,比如电灯出场内置开关依赖了 A 品牌,当有一天买电灯的客户家里是 B 品牌的开关,那么电灯就没办法使用了。但是如果我依赖的是开关的抽象接口,它提供打开和关闭两个行为给电灯,电灯根据打开和关闭的行为去控制电灯的点亮和关闭。 这种设计可以让生产的电灯适应市面上的所有开关,那怕未来实现了脑机接口的开关,只要这个它遵循开关的抽象提供打开和关闭两种行为,这款电灯就能受这种新开关的控制。 从上面例子上可以看出,所谓的接口是依赖双方提前的一种约定,依赖方按照这种约定去调用,被依赖方按照这种约定去实现,这种约定其实就是标准化,调用方按照约定去实现功能,使用方按照约定去使用功能。 标准化的好处 从上面的例子中可以看出,标准化带来最大的好处就是复用,你可以任意的生产各种各样的开关,只要是按照标准制定的,我的电灯都是可以使用的。 其次标准化会带来效率的提升,现实中交通规则就是一个很好的例子,交规就是一个标准, 只要是在路上的走的,都受到交规的约束,而正是有了这种约束我们才有了更高效的通勤,绿灯了可以走,红灯了,就停下来等待,我们对路上所有的车辆和行人的轨迹都有预期,从而提升通行效率。 可以设想一下没有交规,是一个什么样的场景,大概率会出现所有车辆堵在了路口,整个路口堵的水泄不通,最后整体通行效率变得无比低下。 标准化还会带来工具化,再拿生活中常见的交通为例,有了完善的交通规则,后续就可以生产适用这种规则的自动驾驶车辆,这将大大改善人们的出行效率。 标准化在工作中的用处 标准化在工作中也有着十分重要的作用,如今的工作大多都会有工种之间的划分,工种和工种之间就存在着依赖关系,上一个工种的工作要到什么程度,下一个工种应该怎么衔接,这就是一个依赖,而在这两个工种之间就需要一个明确的约定。 有了这种约定,可以减少很多不必要的沟通,不需要去关心上个工种的实现细节,只需要双方按照约定各自生产,在产品成型阶段把各个工种生产出的设备进行组装即可。 当公司来了新人的时候,他也不需要重新去每个环节去了解其他工种的产品特性,只需要去了解约定的标准化制度即可投入到生产中。 标准化的问题 标准化也并非都是好处,它在设计阶段需要投入相当的人力去设计,并且需要在后续的生产阶段通过实践中得到的反馈,去不断的完善标准。 如果标准设计的不好,频繁的变更标准,将会导致所有依赖的标准方都要进行变动,这种变动的成本是相当高的。 因此在标准设计的时候要进行必要的论证和演练,确保标准没有明显的问题,最大限度的减少标准化带来的成本。 总结 标准化相当于在一个有限范围内设计了一个小型的生态系统,标准化制定了基本的流程和规则,生态系统的其他元素按照这种流程和规则去演化出标准化所期望达成的效果。 标准化的制定是有难度的,有些时候仅从设计阶段,无法看到最终的结果,这时可以通过抓大放小的形式去解决。刨除细节,去设计整体框架,保证大方向的正确,在标准化实践的过程中去不断的丰富细节,完善标准,从而让标准化实现最终的落地。 可能某些情况下理想下的标准化永远也无法达成,但这不能成为放弃标准化的理由,不能因为我们理想是得到 100 分的好处,因为我们拿不到 100 分就放弃。拿不到 100 分,能拿 60 分也比一分都没有要好一些,你觉得呢?

August 7, 2023 · 1 min · 云溪

为什么我们需要一个知识库

知识库是什么?简单来说知识库是一系列文档的集合。文档是沉淀知识的载体,而存放知识的地方,就叫做知识库。 我想大多数程序员都和我一样是不爱写文档的,在这些年的开发过程中,我逐渐认识到写文档的重要性。因此才有了这篇文章,向你介绍一下为什么我们需要一个知识库。 知识库的作用 不知道你有没有这种困扰: 场景一: 某天你需要在某个同事开发的功能基础上拓展一些新的功能,但是你不清楚这位同事开发的功 能是怎么运行的。你想要了解程序的具体内容,于是你找同事咨询,恰巧这位同事有事请假了,于是你只能硬着头皮从代码层面去阅读理解,去梳理原有程序的实现逻辑,遇到某些复杂部分,你可能需要格外的小心,重读多遍,以便于能正确理解实现思想… 如果在你看代码前,你突然得到一个消息,这位同事之前写过关于这部分功能的实现文档,你心头会不会突然涌现出一丝暖意,嘴角不自觉的上扬呢? 场景二: 你实现了一个核心业务,它被很多的其他的业务方关联,这些业务方在实现自己的业务之前都会跑来找你了解你这部分业务的实现情况。你每次都能耐心详细的把自己的业务讲明白,也很好的帮助了业务方调用你的业务。 随着业务的发展,会有新的业务实现人员发现自己的业务依赖你所实现的业务,于是他再一次找 到了你说:我需要你的帮助… 以上种种让你觉得深陷泥沼,无法自拔。这时如果你有一份文档详细的介绍了你所实现业务的逻辑,它去帮你解答他人的困惑,你是否觉得它就像天使一样,拯救你于水火呢? 正如上述场景所描述的那样,知识库能够解决团队内的信息同步问题,当有需要的时候知识库能够帮助团队的成员更快的了解相关信息。 对于一些高频出现的问题,知识库可以作为你的助手一样,帮助你向有需要的人进行解答,解放出你的时间和精力,专注更重要的事情。 同时知识库还能作为你的外脑,帮你去记忆某些重要的事情。人的记忆是不稳定的,而计算机却十分擅长记忆,把需要长期记忆的通过知识库交予计算机,让大脑去做它擅长的事情。 如何选择知识库 知识库作为一个文档存储载体,它的选择是多种多样的,可以根据不同的需求做出不同的选择。 个人知识库 如果个人使用,你可以用笔记软件去组织自己的知识。它最好要有一下特性: 多端支持(IOS,Android, Windows, Linux) 多端之间要有相互同步的能力 支持 Mrkdown 支持双链 上述特性中,多端支持和多端同步是我认为必须要有的,它可以让你随时随地记录,并且随时随地调取你的文档。 Markdown 和双链 是选用功能,Markdown 是一个通用语法,如果你用 Markdown 写的文档可以很平滑的迁移到其他平台。双链可以帮你更好的组织文档之间的关系,可以让知识系统由一个个独立的点串联成知识网络。 团队知识库 团队知识库的选择,最重要的一个原则是:如何让团队以最小的成本接入。可以考虑从团队现有工具中找到相关的知识库进行使用。 所选知识库要有能对外分享的能力,有时候有些文档是需要让客户开放的。 推荐两个知识库软件:飞书,语雀。两款软件使用感受都不错,语雀的使用体验要更好一些,不过有些功能需要开通会员才能使用,比如把文档分享到互联网的功能。 飞书的使用体验比语雀稍差一些,最大的优势是它免费的功能能满足一般的使用需求。 如何使用知识库 知识库根据使用用途一般分为对内和对外两部分。对内可以根据知识库的敏感程度设置为:是整企业可见/部门可见/指定人可见。对外可以完全是对互联网开放,做开放平台开放的文档,或者产品使用手册等都可以设置为对互联网开放。 如何写一份功能文档 以功能文档为例,我认为文档应该在实现功能之前就要写了,这么做的目的是在开发功能之前梳理开发思路,形成一个框架。这个阶段主要是考虑全局,不需要深入细节。 如果梳理过程中有需要讨论的地方,也可以用文档来作为基础和参与讨论人员做思想对齐,使接下来的讨论更加的聚焦在问题本身。 框架梳理完成后,就可以进入功能开发了,功能开发阶段可以对关键业务部分做一些流程梳理,也不需要过分追求细节,能够明确的表达思想即可。有了这份文档在方向上的指引,也有助于在开发阶段少走弯路。 在功能开发完成后对文档进行补充,补充一些细节的说明,让整个文档更加的丰富,表达更为通畅和清晰。 什么情况下需要写文档 写文档也是需要付出成本的,因此在写文档之前需要考虑这个文档它的使用收益是否大于成本。因此写文档可以由一下两种策略:降低写作成本 和 提高写作收益。 降低写作成本:可以不用在意文档的完整程度,可以把这类文档作为一个提示文档,它只需要能够辅助我们想起来如何去找到答案即可,不追求写作的表达和完整性。 提高写作收益:对于一个问题多次被提及到,我们可以认为此问题形成文档的收益在提升,可以考虑输出文档去解决此类问题。 定期维护文档 文档也有生命周期,随着业务的发展,文档也需要进行相应的调整。这个维护工作应该是文档作者和所有使用的人,也就是说不仅仅写文档的人要维护文档,阅读文档的人也可以维护文档。 阅读人可以为文档补充案例。或者对于一些有疑问的地方得到解答后,可以细化到文档中,帮助后面的阅读者更好的理解文档。 总结 本文大概讲解了一些知识库的价值和使用方式,目的是在你的心中埋下一颗种子,它需要时间去发芽和成长。 知识库的使用并不是那么容易,肯定会遇到各种各样的问题,要有直面并解决的勇气。千里之台始于垒土。 如果你认为这是一件正确的事情,就坚持下去,潜心耕耘,静待花开。 扩展阅读 双链笔记是伪概念?聊聊双链的核心优势——知识管理 - 少数派 (sspai.com)

June 20, 2023 · 1 min · 云溪

简单的艺术

最近读《微信背后的产品观》很受启发,张小龙在文中阐述了他的产品哲学,以及微信产品的发展过程中的一些思考与体会。对于好的产品,共性之一就是他们都足够的简单。 微信发展了这么多年,他已经成为一个非常重的应用,里面的功能也是非常的复杂,但是这些复杂没有暴露给用户,对于大多数人,常用的功能占 1% 都不到,从此也能看出,微信的克制。 微信不会在你使用产品的时候打扰你。比如它不会在更新后,给你弹个操作引导,告诉你它更新了什么东西。当你在使用微信的时候,觉得这个地方应该可以进行某个操作,当你按照自己的想法去操作的时候,你会发现你想要的功能就在哪里。微信通过符合直觉的方式去展示他的功能,而不是去教育用户让用户去适应它。 像上述例子比比皆是,它贯彻微信的整个生命周期。如何能像微信一样,做一个简单且有用的产品呢? 你有没有做伟大产品的决心 你是想做一个伟大的产品,还是想当一天和尚撞一天钟。是能否做出伟大产品的关键。心态在其中是起到无可比拟的作用的。 心态是决定你能把事情做到什么程度,它会潜移默化的影响着你。也时刻影响着你的产出质量。 你可以因为没有那么热爱而离开,但最好不要敷衍。你的时间不会重来,把时间浪费在低质量的产出是相当不明智的。 所以去全力以赴把产品做到当下的最好,不辜负团队,也不辜负自己的生命。这是你对自己生命最好的交代。 别用战术上的勤奋掩盖战略上的懒惰 做产品的时候,我们可能会从用户或者运营那里得到很多的想法,更有甚者会直接告诉你我需要一个什么样的功能,你帮我做出来就好。 如果面对这种情况,我们努力去完成每一个人的需求,勤奋的让自己都心生怜悯,这种做法也是十分不可取的。 做产品要解决的东西是本质,而非现象。现象是千变万化的,今天可能是 A 明天可能是 B,但是他们可能都是基于某个基础需求所衍生出来的。如果只是去解决现象,那不仅会辛苦而且收获甚微。思考和找到其本质,才是一劳永逸的解决之道。 沉浸其中 深入到产品中, 了解你产品是什么?解决了什么问题?解决了谁的问题? 你得清楚的了解它,才能在新需求来时知道如何安置。才能找到一个支点,用最小的代价撬起万钧之力。 所以深入到你的产品中,深入到你的客户中,去感受他们给出的回应。 总结 做产品也是一定程度上反人性的,有些时候我们凭借直觉给出方案,但这种方案仅仅是满足需求而已,它既不好用,也不简单。这样的事情做的多了,产品就会膨胀和混乱,最终导致复杂且晦涩,用户更没办法理解和使用。 所以我们需要适时的提醒自己,这样做对吗?它足够简单吗?它能使我的客户更方便吗? 去让客户自然的使用你的产品,而不是教他如何使用你的产品。

June 8, 2023 · 1 min · 云溪