ITPub博客

首页 > 数据库 > 数据库开发技术 > 如何在团队里写好代码?

如何在团队里写好代码?

原创 数据库开发技术 作者:灸哥漫谈 时间:2023-12-07 20:14:30 0 删除 编辑





关|注|:|灸|哥|漫|谈

00、两段文字欣赏


0

1


即使我们的工作是在维护“屎山(Shit Mountain)”,也请不要忘记时时仰望星空!

—— 2013年“搞笑诺贝尔奖”中提到屎壳郎在迷路时能够利用银河导航

0

2


不管你们有多敬业,加多少班,在面对烂系统时,你仍然会寸步难行,因为你大部分的精力不是在应付开发需求,而是在应对代码的混乱带来的问题。

—— Rober C.Martin

01、团队内为何会出现“烂”代码

团队中出现“烂”代码通常会有多方面的原因:

01

系统复杂性


系统设计方案过于复杂(过度设计),在逐渐迭代的过程中,因为业务的复杂度增加带来系统的复杂度越来越高,代码越写越烂。

《人月神话》:软件的复杂性是一个基本特征,而不是偶然如此!

02

开发者能力不足


写代码是一种技能,但是写好代码确实一件很不容易的事情,需要持续学习和实践,同时在团队内要建立良好的学习氛围,分享最佳实践和经验。

03

开发团队缺少技术文化的氛围


团队缺乏对代码质量的要求,过于专注于完成开发任务,导致“面条”代码泛滥。同时也有可能是团队缺少统一的代码规范要求,代码“千人千面”。

04

各种无休止的妥协


向各方妥协,包括自己、产品经理、工期、技术债等,导致设计的丧失,缺乏对代码质量的关注,过于注重功能的交付。

更有甚者,对如何写好代码完全不管,功能怼上去就行,还会安慰自己:下次我优化下!于是一场没有结局的代码追爱之路就开始了。

02、好代码的“爽”

在技术领域,好的代码不仅仅是一堆能够运行的指令,更是一项技能和艺术的结合。好的代码带来的爽不仅仅局限于程序的执行结果,更体现在开发者个人、团队协作以及项目整体成功的方方面面。

01

开发者的技艺形象和影响力


  1. 好代码是开发者的代言人,通过写出整洁、可读性强的代码,开发者展示了对编码技巧的熟练掌握,提升个人的技术影响力

  2. 代码是最直接的技术交流方式,Talk is cheap,Please show me your code!好的代码反映了开发者的专业水平,为团队成员提供了学习的范本,提升了整体团队的技术影响力

02

统一的代码规范,结构优雅的代码,维护成本低,同时研发效率得到提升


  1. 统一的代码规范会让代码在团队内的更易于阅读和理解,降低维护的成本

  2. 良好设计的代码结构可以使功能的扩展和修改变得更加方便,提升团队整体的研发效率

03

合理的设计和优雅的代码可以让开发者和团队成员赏心悦目


  1. 优雅的代码不仅是机器能够理解的指令,更是一种艺术品,可以让开发者和团队成员在阅读代码的过程中感受到愉悦,代码如诗如画

  2. 通过共同遵守规范、欣赏彼此的代码,团队成员间的默契和协作得到加强,形成强大凝聚力的团队

好的代码不仅仅是实现功能的手段,更是一种技术、文化和团队合作的体现。通过写好代码,不仅提升个人的技术水平,也为团队和项目的成功奠定基础。

新时代的程序员

03、程序员的美德


作为程序员,肩负着创造性和协作性的责任,在这个过程中,培养一些美德和良好的实践是至关重要的,特别是对于协作伙伴和未来接手代码的人。

01、可读性好的设计和代码

  1. 注重编写易于理解、可读性好的代码,让协作者轻松理解设计意图,代码为协作者而写

  2. 适度而清晰的注释为他人提供上下文信息,帮助他人更快地冗余代码中

02、维护性强的设计和代码

  1. 代码设计时要未雨绸缪,需要具有足够弹性以便应对未来的变化,避免硬编码和过度复杂的逻辑结构

  2. 将代码分解成独立的模块,每个模块有清晰的职责,降低耦合提高整体可维护性

03、持续学习和分享

  1. 积极学习新技术,不断提升自己的技术水平,适应行业快速发展的行业变化

  2. 分享经验和知识,将学到的新知识分享给团队,共同成长

04、尊重他人的贡献

  1. 认可协作者的工作,尊重并认可他人的设计和代码,通过积极建设性的反馈帮助对方提高

  2. 为接盘侠考虑,在离开项目或团队时,留下详细的文档和整洁的代码,为接手者提供好的上下文,减少知识的流失

通过培养这些美德,不仅为自己创造了愉悦的开发环境,也可以为整个团队的协作和项目的持续健康贡献力量,责任心和协作意识共同工程程序员的美德。

04、写好代码的指导原则

在编写高质量代码时,需要也应该要遵循的一些指导原则,确保代码可维护性、可读性和可扩展性。

01

代码的目的是维护而非实现功能


认识代码的生命周期,平时大部分的研发时间会花在阅读、理解和维护代码上,因此编写易于维护的代码比仅仅实现功能更加重要。

02

优秀的代码应该自描述优于文档和注释


Scrum 中也倡导代码自描述,代码中避免过多的注释,清晰的代码本身就是最好的文档

03

设计模式是手段而非目的


设计模式的使用是为了解决特定的问题,而不是为了增加复杂度,设计模式是写好代码的手段,不应该成为编码的目的,清洗简洁的代码才是编码的最终目标。

官

方

要

求

  1. 架构设计三原则:合适、简单、演化

  2. 软件设计七原则:SOLID、CARP、LoD


ENJOY Coding

民

间

要

求

  1. 运行速度快

  2. BUG 数量少且易于发现

  3. 可扩展且维护迭代成本小

  4. 易读性且团队协作效率高


ENJOY Coding

05、代码“坏”味道

整理日常代码中的“坏”味道,帮助大家在日常编码过程中避免,可以多看看《代码整洁之道》

01

代码重复


大量重复代码增加维护成本 -> 提取重复代码,封装为可复用的方法或模块

02

方法太长


难以阅读和理解 -> 拆分为更小易于管理的方法

03

类太长


类过于庞大难以维护 -> 拆分更小功能单一的类提高代码灵活性

04

数据浆糊


相同代码重复出现导致不必要的冗余 -> 清理冗余代码确保相同逻辑不散落在不同的方法和类

05

参数列表太长


过长的参数列表方法对可读性和可维护性有极大伤害 -> 长参数列表封装成对象提高代码清晰度

06

命名不清晰


使用有意义的命名可以让代码更可读

07

if/else 过多

大量嵌套的 if/else 语句,影响代码的可维护性 -> 考虑设计模式简化逻辑

08

循环里资源浪费

循环内部放置大对象 -> 大对象不在循环里提供资源利用率

09

全程一个 try

降低代码健壮性 -> 合理使用 try-catch 在合适的位置

10

资源未及时清理

未及时清理资源易导致内存泄漏问题 -> 使用过的资源及时释放

11

循环里字符串拼接使用“+”

效率低 -> 使用 SB 等高效手段拼接

12

散落各处的错误码

难维护统一错误码 -> 使用统一错误码定义

13

同质常量定义不用枚举

使用枚举管理同质常量提高清晰度

14

代码风格不统一

千人千面的代码风格可读性极低 -> 统一规范要求

15

缺乏统一的日志打印规范

无法对日志集中管理亦无法进行日志搜集分析 -> 统一规范、统一处理框架

06、如何写好代码

程序员代码大作战

我们从三个阶段来看具体如何写好代码:


01

码前阶段



  1. 清晰理解需求场景,设计合理的架构方案,在合理的架构方案基础上,进行技术方案的设计,技术方案设计过程中要善用图的方式去设计,流程图、用例图、架构图、时序图、状态图、 ER 图、......

  2. 团队内要有统一标准的规范要求、流程制度、常用高效工具等

  3. 营造合理的技术文化氛围,比如技术方案脑暴、Review 等

02

码中阶段



  1. 遵守基本编码原则和要求(上述已讲)

  2. 持续重构改进和性能优化

  3. TDD 驱动的研发方式

03

码后阶段



  1. 定期代码 CR,确保代码质量,同时确保代码符合团队规范和标准,同时传递知识和分享,提高团队整体技术水平

    1. 时机:正常 CR 的时机是第一波冒烟测试之后,千万别上线前夜做 CR

    2. 方式:300/500 行标准,区分线上/线下CR(团队具体情况自定)

    3. 前提:编译通过,插件检测通过;基于 CheckList 自检通过

    4. 内容:对照技术方案是如何编码落地的;总体代码流程、关键设计、重点功能、基本规范

    5. 措施:CR 过程中如有严重风险问题的上线前必须完成修改,然后进行二次CR;其他问题尽量上线前完成修改,如果未修改要加TODO,指定人和时间来修改,同时项目管理空间,添加技术优化需求

    6. 事后:定期回顾和总结CR结果;CheckList 和代码规范的持续更新完善;发现好的代码和设计,同时 Diss 坏的代码和设计

  2. 持续进行自动化测试,确保质量和稳定性。性能测试持续进行,确保高负载下的稳定性

  3. 补充好详细的技术文档,通过知识库的方式记录和分享技术经验和问题解决方案

  4. 个人/团队事后复盘,提升个人解决问题能力的同时,更新团队 CheckList 和规范要求

07、最佳实践

01、命名规范

命名很难,总体原则是见名知义

  1. 变量名:

    1. 名词,正确描述业务场景,有表达含义

    2. 理论上是不需要注释说明的,比如 id 和 userId,id 是需要注释用户 ID 的

    3. 魔法值禁止

  2. 函数名:

    1. 具体说明做什么,千万不要命名成怎么做

    2. 不用泛称,比如 processData,所有的方法都是做数据处理的,这样一个方法名没有一定意义,尽量用完整的单词描述清楚做什么,不用怕字多,比如 checkUserLoginRequestParams

  3. 类名:

    1. 实体类承载核心业务数据和核心业务逻辑,命名要充分体现业务语义,并团队内达成共识

    2. 辅助类辅助实体类完成业务逻辑,命名要能通过后缀来体现功能,比如 UserController、UserService、UserRepository

    3. 后缀清晰:XO 对象定义要明确,数据库DO,数据传输对象(服务之间传输)DTO,页面对象VO,还可以有其他,但是务必团队内统一

02、代码结构和组织

  1. 包的组织结构,优雅的分层结构

  2. 类和方法的组织结构

  3. 避免过度嵌套

  4. 合理的空行使用

03、代码注释

  1. 合理的注释位置和格式

  2. 注释的目的和内容

    1. 别给糟糕的代码加注释 —— 与其加注释,不如重新写代码

    2. 注释一般说明为什么这么做(真实的意图),做什么不强求,有更好

04、异常处理

  1. 系统自定义两类异常(BizException & SystemException),自有服务针对异常做统一处理,常用AOP方式处理,避免使用 catch 所有异常的方式

  2. 错误码:外部服务使用 Code,但需要统一指导文档输出;内部服务使用 Msg,但要见名知义,风格P_XXX_XXX(参数异常)、B_XXX_XXX(业务异常)、S_XXX_XXX(系统异常)

05、设计模式的使用

不详细讲解,就谨记一句话:一句话:设计模式不是目的只是手段,用的不好还不如不用。

06、日志规范

正常关注ERROR、WARN、INFO、DEBUG:

  1. ERROR:打印线程堆栈、一定的上下文,比如 traceId、关键性参数,便于排查问题;一定要有监控和报警的配置 → 需要及时排查防止故障发生 → 不能滥用,狼来了

  2. WARN:可预知的业务问题:参数校验不通过、鉴权失败等;配置时间段、一定阈值范围的监控和报警

  3. INFO:定位是用来初步定位问题的,记录简单状态变更、核心处理流程等变化信息,不能滥用,处处 INFO

  4. DEBUG:开发同学自己玩的日志,更进一步协助排查问题使用,线上不打印,但对于核心服务流程,可以设置开关来决定线上是否开启DEBUG日志的打印

08、Java 高级特性实践

  1. Lambda 表达式与函数式编程

    1. 适当使用,不能滥用

    2. Lambda 表达式可简化代码

  2. Stream API

  3. Optional 的合理使用

    1. 避免空指针异常

09、代码性能和相关安全

  1. 数据库性能以及优化:合理的索引、合理的缓存策略使用

  2. 多线程优化:规避线程安全问题;合理使用锁机制

  3. 安全考虑:SQL 注入防止;脚本攻击防止

  4. 资金安全:资损评估;资金流程强监控;资金对账回补

  5. 易恢复:重大功能的灰度/AB 能力;CI/CD 流程支持快速回滚

  6. 可监控/可发现/可报警:性能监控、异常监控、关键指标监控;报警发现和处理机制

  7. 可限流/可降级:识别强弱依赖,保证可降级;识别可限流场景,做好监控和限流配合

思考:

  1. 如何进行有效的 CR

  2. 何时以及如何进行代码重构

  3. 你和你现在的团队在实际项目中遇到的阻止你写好代码的问题?你是怎么解决的?

以上思考问题,欢迎大家留言评论交流!

推荐书籍

  1. 提供实际编程技巧和架构原则帮助开发者编写清晰可维护的代码:《代码整洁之道》、《架构整洁之道》、《匠艺整洁之道》

  2. 针对 Java 提供了一系列有效的编程实践让代码更加健壮高效:《Effective Java》

  3. 提供重构技术让代码更加易读:《重构:改善既有代码的设计》

  4. 阿里巴巴团队在 Java 开发方面的经验总结:《阿里巴巴 Java 开发手册》

原文作者:灸哥漫谈;如有侵权,请联系管理员删除。

请登录后发表评论 登录
全部评论

注册时间:2023-11-26

  • 博文量
    368
  • 访问量
    173270