GO 中优雅编码和降低圈复杂度

本次主要是聊聊关于使用接口抽象和降低圈复杂度的方式

工作中,难免会遇到老项目老代码,不仅仅需要我们维护,可能还需要我们在原来的垃圾代码上进行新增功能或者是进行优化调整

例如

现有的老代码中关于用户系统这一块就已经经是摇摇欲坠,牵一发而动全身,并且去弄清其中的业务细节,那可以说是很难拨开迷雾,甚至交接都是一句话的那种,更是难上加难

这种情况,相信每个公司都会存在,毕竟过去的需求,过去的标准,放到现在来看,啥也不是

若是很多代码都是面向过程的,各种业务逻辑,非业务的逻辑都混合在一起,主流程上插入一些乱七八糟的逻辑,上下文并没有啥关系的东西,一个函数上千行的代码也是随处可见,这种情况狗看了都摇头

对业务函数需要做基本的封装

首先咱们编码前一定会去捋清楚基本的需求,设计,以及实现流程,对于需要用到的工具我们会对代码结构进行分层

例如一些与业务主逻辑没有什么关联的功能就可以独立封装,便于维护和使用,例如:

  • 工具包(例如语言中的各种计算,数据处理,加解密等等)
  • 基本的 rpc 通信
  • http 相关的各种通信方式
  • 基本的中间件,拦截器,打点接口延时等等
  • 数据库操作(独立封装 DAO 层提供出来)
  • 缓存操作
  • 消息队列
  • …等等

尽可能的将这些单独的功能模块拆解出去,独立出来,单独维护

对于那种没有必要同步的功能,完全可以通过异步化来进行处理,异步的话相信你会很容易想到消息队列来进行实现

自然实际项目中你能够看到最开始可能也会这样去做,但是随着业务越来越复杂,这些独立的模块被各种包进行使用,甚至有的开始慢慢的弄成定制化的方式

例如

func OpenTenant(){// 校验基本租户信息// 检查租户是否特权,完成权限分配// 检查实际开户的线路,分配各种租户下的必备账号// 完成各种系统的对接交互// 进行数据库操作// 返回结果
}

对于一个基本的开户流程,我们或许可以在代码中看到第一步做什么,第二步又做什么,第三步… ,然而每一个大步骤下面还有各种小步骤,每一个小步骤也会有自己的复杂逻辑

虽然有了基本的封装,但是使用的时候,可能还是会写到哪,需要啥就去按需定义啥

最终就会看到一个函数上千行,让你去阅读和维护,你内心能不拒绝吗吗?

发现对模块进行独立封装还是不太够,代码里面太多的冗余代码,这个时候咱们就可以使用接口来做抽象

用接口来做抽象

使用接口来做抽象的话,相当于是提前考虑好这一类的业务需要去考虑哪些问题,需要注意哪些场景,需要实现哪一些接口

不同的对象各自去实现自己的内容就可以了,单独去维护自己的对象

例如上面的 A 系统的开户流程

// 开户 interface{}
type OpenTenant interface{ValidateTenantInfo(xxx)xxx // 校验基本租户信息CheckPrivilege(xxx) xxx // 检查租户是否特权,完成权限分配CheckLine(xxx) xxx // 检查实际开户的线路ProcessNeccessaryAccount(xxx) xxx //分配各种租户下的必备账号ProcessNoticeMsg(xxx) xxx// 完成各种系统的对接交互AddTenant(xxx) xxx// 进行数据库操作
}

这仅仅是一个 demo,对于一个开户 interface{} 来说,A 系统可以去实现,B 系统仍然也可以去实现,各自完成自己的内容,例如这样

对于优化代码的话,我们就可以将上述的一些实现步骤,放到这个接口中来即可

咱们定义接口,更多的是去规范流程和便于维护,这样还可以让我们的程序往高内聚低耦合方面去靠,不同的对象之间,完全是安全的,自己玩自己的一套,只不过遵循的规范是一样的的

尽可能降低圈复杂度

圈复杂度也可以理解为条件复杂度,是一种用来衡量代码复杂度的标准

例如一些没有判断语句的代码,圈复杂度就是 1

如果是 if…else 那么圈复杂度就是 2 ,简单的就可以理解为涉及到判断条件的数量,那么就 +1

例如有这样的代码

func testDemo() {var op OpenTenantswitch TenantType {case A:op = a.New()case B:op = b.New()case C:op = c.New()default:...}op.ValidateTenantInfo()....
}

那么就如上demo ,来看,圈复杂度就是 4 ,其中有 3 个判断条件和一个默认的正常顺序,因此是 3 +1 = 4

这个时候,我们可以如何降低圈复杂度呢?

我们完全就可以使用表格的方式,访问数据直接访问表格就可以了,尽可能的减少这些判断条件,例如我们就可以这样来写

var openTenantMap = map[string]openTenantObject{A: a.New(),B: b.New(),C: c.New(),
}
func testDemo(){op := openTenantMap[TenantType ]...op.ValidateTenantInfo()...
}

这种方式,是不是就可以将圈复杂度降低到 1 了呢?而且看起来也优雅了很多

总结

主要叮嘱了我们维护和开发的时候,要重视封装,重视抽象,重视降低圈复杂度

只要你用心去打磨,自然会变得越来越好

但是可别生搬硬套,毕竟一些定制化的需求,定制化的代码你去做接口抽象是没有啥意义的,一起加油吧,xdm

至此,本次就是这样,希望能够给你带来一丁点帮助

欢迎点赞,关注,收藏

朋友们,你的支持和鼓励,是我坚持分享,提高质量的动力

技术是开放的,我们的心态,更应是开放的。拥抱变化,向阳而生,努力向前行。

我是阿兵云原生,欢迎点赞关注收藏,下次见~

文中提到的技术点,感兴趣的可以查看这些文章:

  • 关于 interface{} 会有啥注意事项?下
  • 关于 interface{} 会有啥注意事项?上
  • 设计模式之单例、工厂、发布订阅者模式
    可以进入地址进行体验和学习:https://xxetb.xet.tech/s/3lucCI

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/149461.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

python修改unittestreport中的用例条数

背景: 自动化框架中使用yaml文件作为数据配置,使用ddt作为数据驱动来运行测试用例,由于测试用例都是基于场景去编写,目前都是一个测试类算是一条测试用例,但基于测试报告里面一个类运行的测试方法有多个,因此统计的测试…

MATLAB 函数签名器

文章目录 MATLAB 函数签名器注释规范模板参数类型 kind数据格式 type选项的支持 使用可执行程序封装为m函数程序输出 编译待办事项推荐阅读附录 MATLAB 函数签名器 MATLAB 函数签名器 (FUNCSIGN) ,在规范注释格式的基础上为函数文件或类文件自动生成函数签名&#…

专题一:双指针【优选算法】

双指针应用场景: 数组划分、数组分块 目录 一、移动0 二、复写0 从后向前 三、快乐数 链表带环 四、盛水最多的容器 单调性双指针 五、有效三角形个数 单调性双指针 六、和为s的两个数字 七、三数之和 细节多 需再练 一、移动0 class Solution { public:void move…

使用Jest测试Cesium源码

使用Jest测试Cesium源码 介绍环境Cesium安装Jest安装Jest模块包安装babel安装Jest的VSC插件 测试例子小结 介绍 在使用Cesium时,我们常常需要编写自己的业务代码,其中需要引用Cesium的源码,这样方便调试。此外,目前代码中直接使用…

ChatGPT付费创作系统V2.3.4独立版 +WEB端+ H5端 + 小程序最新前端

人类小徐提供的GPT付费体验系统最新版系统是一款基于ThinkPHP框架开发的AI问答小程序,是基于国外很火的ChatGPT进行开发的Ai智能问答小程序。当前全民热议ChatGPT,流量超级大,引流不要太简单!一键下单即可拥有自己的GPT&#xff0…

C++——list(2)

作者:几冬雪来 时间:2023年9月28日 内容:C——list内容讲解 目录 前言: list的const迭代器: const的iterator: const迭代器: operator->: 拷贝构造: 迭代器接口补充&…

通过融合UGV的地图信息和IMU的惯性测量数据,实现对车辆精确位置和运动状态的估计和跟踪研究(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

六、互联网技术——数据存储

文章目录 一、存储系统层次结构二、按照重要性分类三、磁盘阵列RAID三、RAID基础四、磁盘阵列分级五、数据备份与恢复六、容灾与灾难恢复 一、存储系统层次结构 常见的三层存储体系结构如下图所示,分为高速缓冲存储器、主存储器和外存储器。 二、按照重要性分类 …

VBA技术资料MF66:使用代码插入行或列

我给VBA的定义:VBA是个人小型自动化处理的有效工具。利用好了,可以大大提高自己的工作效率,而且可以提高数据的准确度。我的教程一共九套,分为初级、中级、高级三大部分。是对VBA的系统讲解,从简单的入门,到…

十二、同步互斥与通信

1、概述 (1)可以把多任务系统当做一个团队,里面的每一个任务就相当于团队中的一个人。团队成员之间要协调工作进度(同步)、争用会议室(互斥)、沟通(通信)。多任务系统中所涉及的概念,都可以在现实生活中找到例子。 (2)各类RTOS都会涉及这些概念&#x…

小程序入门笔记(一) 黑马程序员前端微信小程序开发教程

微信小程序基本介绍 小程序和普通网页有以下几点区别: 运行环境:小程序可以在手机的操作系统上直接运行,如微信、支付宝等;而普通网页需要在浏览器中打开才能运行。 开发技术:小程序采用前端技术进行开发,…

XC5013 马达驱动和充电集成一体的控制芯片 一档输出芯片

XC5013 是一款应用于马达驱动或 LED 驱动的控制芯片,集成了锂电池充电管理系统,设定一档高电平输 出,并带有对不同状态的 LED 指示功能。 XC5013 集成了涓流充电、恒流充电和恒压充电全过程的充电方式,浮充电压精度在全温度范…

正点原子嵌入式linux驱动开发——TF-A初探

上一篇笔记中,正点原子的文档简单讲解了一下什么是TF-A,并且也学习了如何编译TF-A。但是TF-A是如何运行的,它的一个运行流程并未涉及。TF-A的详细运行过程是很复杂的,涉及到很多ARM处理器底层知识,所以这一篇笔记的内容…

大促节奏:速卖通黑五接力双十一,如何打造产品权重瓜分活动流量

双十一和黑五作为一种独特的消费文化现象,已经逐渐成为了消费领域中的一块“金字招牌”。无论是消费者还是商家,都非常期待这一天的到来,因为它不仅代表着购物的欲望和刺激,更重要的是,双十一和黑五已经成为了一种全新…

全排列[中等]

优质博文:IT-BLOG-CN 一、题目 给定一个不含重复数字的数组nums,返回其所有可能的全排列。你可以按任意顺序返回答案。 示例 1: 输入:nums [1,2,3] 输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]] 示例…

不做静态化,当部署到服务器上的项目刷新出现404【已解决】

当线上项目刷新出现404页面解决方法: 在nginx配置里加入这样一段代码 try_files $uri $uri/ /index.html; 它的作用是尝试按照给定的顺序访问文件 变量解释 try_files 固定语法 $uri 指代home文件(ip地址后面的路径,假如是127.0.0.1/index/a.png&…

二项分布以及实现

文章目录 前言所谓二项分布就是只会产生两种结果的概率 1.概念 前言 所谓二项分布就是只会产生两种结果的概率 1.概念 下面是一个二项分布的的theano实现 import numpy as np import theano import theano.tensor as T from theano.tensor.nnet import conv from theano.ten…

只需5秒视频就能生成3D模型的AI工具——Luma AI

HI,同学们,我是赤辰,本期是第13篇AI工具类教程,文章底部准备了粉丝福利,看完后可领取! 今天给大家介绍一款用视频生成3D模型内容的AI工具——Luma AI,基于神经渲染技术,只需拍摄照片…

计算机竞赛 题目:基于FP-Growth的新闻挖掘算法系统的设计与实现

文章目录 0 前言1 项目背景2 算法架构3 FP-Growth算法原理3.1 FP树3.2 算法过程3.3 算法实现3.3.1 构建FP树 3.4 从FP树中挖掘频繁项集 4 系统设计展示5 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 基于FP-Growth的新闻挖掘算法系统的设计与实现…

Linux:TCP三握四挥简析

文章目录 1. 前言2. 背景3. TCP连接的建立和断开3.1 TCP协议状态机3.2 TCP的三握四挥3.2.1 TCP 连接建立的三次握手过程分析3.2.1.1 服务端和客户端套接字的创建3.2.1.2 服务端进入 LISTEN 状态3.2.1.3 服务端在 LISTEN 状态等待客户端的 SYN 请求3.2.1.4 客户端向服务端发送 S…