优化代码质量:SOLID原则与有效的Code Review实践

文章目录

前言

  代码质量的重要性毋庸置疑,而Code Review是提高代码质量的一种关键实践,它对于保证软件的可靠性、可维护性以及整体性能非常重要,写这篇文章分享一下自己从事开发工作与实习一年多以来对Code Review的认识和经验。

一、Code Review是什么?

Code Review(代码审查)是软件开发过程中的一项重要活动,它的时机一般在个人开发代码被合并到主分支之前,由一位或多位开发者检查代码。

二、Code Review的基本规范

目标:找出代码漏洞,美化和规范代码风格,尽可能避免Bug上线。
细节规范:
2.1代码设计质量:检查代码是否符合良好的设计原则,如模块化、封装性、简洁性,并确保它与项目的整体架构和设计一致。
2.2功能实现:
预期行为:验证代码实现的功能是否符合预期,并且准确无误地满足项目需求。
性能考量:后端代码需特别关注性能问题,比如响应时间、资源消耗、并发处理能力等。
性能考量在代码层面的关注点主要在于审查代码中可能导致延迟的部分,如数据库查询、网络调用、复杂算法等。
具体的措施比如优化数据库查询,使用索引和减少查询的复杂性可以显著提升响应速度以及减少不必要的数据处理和转换。
安全性:特别检查代码是否有潜在的安全风险,如SQL注入、数据泄露、未经授权的访问等。
可扩展性和可维护性:确保代码易于维护和扩展,考虑未来可能的变更和需求增长。
2.3复杂度:能否让代码更简单?如果未来某一天,其他开发者遇到这段代码时,他们能否很容易理解并使用这段代码?
2.4测试:
编写单元测试:
对每个功能模块编写单元测试,确保它们能够独立地工作。
使用断言验证预期结果,确保代码在不同的输入和条件下表现正确。
选择合适的测试框架,如在C++中可以使用Google Test。
集成测试:
一旦单个模块测试通过,进行集成测试以确保模块间的交互按预期工作。
集成测试应覆盖系统的主要工作流程和关键路径。
测试驱动开发(TDD):
在编写实际代码之前先编写测试用例。这种做法可以帮助更清晰地定义功能需求,并确保代码满足这些需求。
不过这点大部分公司做到需求明确,接口定义好,基本不需要返工,实际流程中,基本测试用例和代码并行,或者是代码先差不多写好,测试用例才写起来;
2.5命名:是否为变量,类,方法等选择了清晰的名字?以及命名是否遵守了驼峰命名法。
review注意点:
1.内存泄漏
2.拼写错误
3.添加保护(特别是边界条件)
4.功能逻辑
5.代码复用性

三、SOLID原则

1.S单一职责原则 (Single Responsibility Principle, SRP):

一个类应该只有一个原因导致其变化。

这意味着一个类应该只有一个任务或功能。当一个类具有多个责任时,它变得更加复杂,并且更容易受到多个变更的影响,所以可以通过将代码分解成更小、更简单的部分,再对其进行修改和维护,从而提高代码的可读性和可维护性。
举例

2.O开放封闭原则(Open-Closed Principle, OCP):

软件实体(类、模块、函数等)应该是对扩展开放的,但对修改关闭的。这意味着当我们需要增加新功能时,我们应该尽可能地利用现有的代码,而不是修改它们。这可以通过使用接口和抽象类等OOP技术来实现。

这个原则在C++编码中,主要指以下几个方面:
2.1使用抽象类和接口:定义抽象基类(或接口),通过继承来扩展功能。这允许用户通过创建新的子类来添加新功能,而不是修改现有的类。
2.2利用多态性:通过虚函数和多态性,可以在运行时决定调用哪个函数,从而在不修改原有代码的情况下增加新的行为。
2.3使用模板:C++ 的模板编程可以在编译时增加灵活性,允许编写在编译时就能确定行为的泛型代码。

3.L里氏替换原则(Liskov Substitution Principle, LSP):

替换性:一个程序中的对象应该可以在不改变程序正确性的前提下,被其子类的实例替换。

设计的目的:确保子类的行为与父类的行为一致,保持程序的正确性和可预测性。
所有引用基类的地方必须能够透明地使用其子类的对象。这意味着子类应该能够替换其基类,并且程序的行为不会受到影响。遵循LSP原则可以确保代码的正确性和稳定性。
如何在 C++ 中实践 LSP?
保持接口一致性:子类应该完全实现父类的方法,并且这些方法的行为应该与父类一致。
避免重写非虚函数:子类不应该重写父类中非虚函数的行为。
避免强制类型转换:如果需要频繁地将父类对象转换为子类,可能意味着违反了 LSP。
子类方法的前置条件不能更严格:子类方法接受的参数范围应该与父类方法相同或更广。
子类方法的后置条件不能更宽松:子类方法完成后应保持与父类相同的状态,或者是父类状态的合法子状态。

4.I接口隔离原则(Interface Segregation Principle, ISP):

接口隔离原则的主要目标

减少类的依赖:确保类只依赖于它们需要的方法。
提高模块的内聚性:通过创建专用接口,使得模块更加集中和高内聚。
易于理解和维护:更小的接口更容易理解和维护。
减少影响范围:当接口更改时,只影响实现了该接口的类。
在 C++ 中,接口可以通过纯虚函数类(只包含纯虚函数和虚析构函数的类)来实现。这些接口应该是小的和专用的。

5.D依赖反转原则(Dependency Inversion Principle, DIP):

DIP 的两个基本要素:

1.高层模块不应该依赖低层模块:高层模块定义了系统的策略,它不应该依赖于实现细节。相反,它应该依赖于抽象。
2.抽象不应该依赖细节:抽象定义了一个接口,它不应该受到具体实现的影响。细节应该依赖于抽象。
在 C++ 中实践 DIP
在 C++ 中,实践 DIP 通常意味着使用接口(通常是纯虚函数类)来定义操作的契约,然后通过具体类来实现这些接口。这样做可以使得高层模块和低层模块之间通过抽象层进行通信,而不是直接依赖具体实现。

总结

对于设计原则的使用,重要的是权衡设计原则与实际的开发场景,以及在代码质量上只要满足以下要求的代码就可以被称为高质量的代码:

可读性强:代码结构清晰,命名意义明确,对反直觉或较复杂的代码有适当的注释。
可维护性:模块化设计,易于扩展和修改。
健壮性:添加必要的异常处理和错误检测机制。
避免内存泄漏:确保分配的资源得到释放。
添加保护:空指针检查:在解引用指针之前进行有效性检查,使用断言来检测代码中的逻辑错误。
逻辑清晰:功能逻辑应简洁、高效,并能正确完成预期的功能。
性能优化:确保代码运行高效,避免不必要的计算或资源浪费。
代码复用:避免重复代码,将公用的逻辑或组件进行抽象或模块化。
遵循编码标准和规范:确保代码遵循一致的编码风格和最佳实践。

  • 总之,高质量的代码不仅仅是没有错误的代码,它还应该是清晰、可读、可维护、可扩展和高效的。这就需要开发者在编码时持续地进行反思、学习和改进。
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

算法小学徒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值