手把手教你,如何先梳理业务逻辑再写代码

news2024/12/29 11:42:29

1.业务逻辑与代码

代码是需求逻辑的一种展现形式

需求文档是业务逻辑的一种展现形式,而代码不过是业务逻辑的另一种表现形式;如果逻辑本身有问题,那么它的各种展示形式自然也是错的,所以写代码前应该先思考清楚业务逻辑。

Review代码很多时候是逻辑问题

在Review代码经验中发现:混乱的代码并不仅仅是代码编写技艺问题,很多时候是因为逻辑没有梳理清楚。逻辑混乱,自然代码也混乱。梳理清楚业务逻辑,就为代码打下了良好的基础。当然业务逻辑梳理清楚后,业务逻辑到代码的映射依然有可能出问题,这是编程技艺要解决的问题。下面通过一个简单的例子来演示这个过程:

2.业务需求示例

我们要做一件事情doSomething:

第一步先做 A,A 过程要先执行 a1, 然后执行 a2, 然后执行 a3 这三个子过程。

第二步再做 B,B 过程需要执行 b1,然后 b2 这两个子过程。

这个示例逻辑的图形表述如下:是一个树,包含树的根,枝干,和叶子。

在这里插入图片描述

例子是有通用性的,现实世界的任何事情或业务都可以用类似的树形结构来表述。

3.正确的代码实现

3.1 和逻辑树映射的代码树

正确的代码结构应该是和逻辑映射的,代码结构如下:
在这里插入图片描述
我们真实写代码的时候,一般并不会直接写出如上结构,而是会先写出「3.2 代码块 + 注释」的结构来。

3.2 代码块 + 合理注释

如下代码通过代码块来映射逻辑,上面图中的子方法对应代码中的注释。

void doSomething(){
    //A
    a1逻辑伪代码.....;//a1
    a2逻辑伪代码.....;//a2
    a3逻辑伪代码.....;//a3

    //B
    b1逻辑伪代码;//b1
    b2逻辑伪代码;//b2
}
3.3 抽取小方法

可以再上面的基础上更优秀些,对代码块进行抽取小方法,更符合业务描述(更符合业务的树形结构)。推荐阅读:看看人家 SpringBoot + vue后台管理系统,多么优雅…

void doSomething(){
    doA();
    doB();
}

void doA(){
    a1逻辑伪代码.....;
    a2逻辑伪代码.....;
    a3逻辑伪代码.....;
}
void doB(){
    b1逻辑伪代码;
    b2逻辑伪代码;
}

当然你也可以继续对 a1,a2,a3,b1,b2 等小逻辑映射为小方法,以上提到几种写法都是正确的,关于小方法是否抽取,后续单独在《代码长度与母语的关系》中讨论。下面我们来看看不正确的写法。

4.不正确的代码实现

当你看到下面的不正确的写法的时候,你也许会觉得不可思议,真的会写出这样的代码?现实是:项目中我见到很多更糟糕的代码,会把下面提到的问题,以及其他编程技艺的问题排列组合出现。

4.1 第一种问题:不对等

第一种常见的问题不太严重,只对部分逻辑进行了抽取,造成方法中执行不对等;比如只对 b() 逻辑进行了抽取,但对等的 a()逻辑并未抽取;
在这里插入图片描述

void doSomething(){
   a1逻辑伪代码.....;
   a2逻辑伪代码.....;
   a3逻辑伪代码.....;
   doB();
}

void doB(){
   b1逻辑伪代码;
   b2逻辑伪代码;
}

改进办法参考上面第 3 部分正确的写法,至少可以在doB();之前加空行,并对 a1,a2,a3 加个注释,也会易读很多(当然这是一种妥协写法)。

void doSomething(){
		//a逻辑
    a1逻辑伪代码.....;
    a2逻辑伪代码.....;
    a3逻辑伪代码.....;
    
    //b逻辑
    doB();
}

void doB(){
    b1逻辑伪代码;
    b2逻辑伪代码;
}
4.2 第二种问题:部分抽取

第二种是对整体的部分逻辑进行了抽取,这种方法很难命名,会给个词不达意的名字,或使用整体的名字,这个就相对严重了,已经影响到了代码阅读和理解。

比如电脑是一个整体,可以命名是电脑;如果只给你一部分(CPU,主板,显卡)怎么命名让人能明白?电脑部分零件?但电脑部分零件并不能让人明白,因为它不是一个逻辑主体。CPU是一个逻辑主体,封装了运算。

如下图,只对 a1,a2 进行了抽取,然后名字依然称为 a,看到代码会很疑惑,a3 明显也属于 a。
在这里插入图片描述

void doSomething(){
    doA();
    a3逻辑伪代码.....;
    doB();
}
void doA(){
    a1逻辑伪代码.....;
    a2逻辑伪代码.....;
}

void doB(){
    b1逻辑伪代码;
    b2逻辑伪代码;
}
4.3 第三种问题:抽取错误

第三种是最严重的问题,抽取错误,和逻辑不匹配。

如下:把 A 的部分逻辑和 B 的部分逻辑一起抽取。

如果在这个基础上再对抽取的部分起个晦涩的名字(其实这种抽取也起不到好名字),然后应用一些设计模式来把代码更分散(缺点隐藏起来),就成功的完成了只有自己可以看懂的代码(可能表面看起来还很高大上)。
在这里插入图片描述

由此得出结论,先别想着抽取小方法或应用设计模式。先能平铺直叙的写出符合逻辑的代码吧。

小方法抽取和设计模式不一定能解决问题,也能隐藏问题。

很多难以读懂的代码都是受《重构》和《设计模式》的包装,质量差的代码不可怕,如果再抽取和包装,可以想想是多恐怖。

5.补丁和模式思考

补丁代码思考,代码的腐烂

很多人看到这里,会觉得自己绝对不会写出这么烂的代码;确实一开始也许不会,但伴随新需求,不同人不断打补丁(为了不影响线上,老代码不让动),最后就会演进未这几个问题综合展现的代码。阅读这样的代码不看到最底层代码,根本不知道代码在做什么,因为方法名已经不可信。

不要急于使用设计模式,写好基础代码

写出一个好的基础代码的过程:

先梳理清楚逻辑树(树形结构,同层对等),然后做到代码符合逻辑树(代码树自然也符合树形结构,同层的方法对等)。

打好基础后,可以再针对基础代码的痛点,应用复杂手段(比如设计模式)来解决

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

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

相关文章

【校招VIP】专业课考点之网络存储

考点介绍: cookie、session和localstorage 是目前常用的存储机制,不管是大厂还是中小公司,都会对这个问题有比较高的考察频度,而且有一定的深度和对比分析 专业课考点之网络存储-相关题目及解析内容可点击文章末尾链接查看&#…

为什么C ++在嵌入式系统设计中是C的可行替代品

你是一名。你知道C是适合该工作的语言,尽管有时维护周期可以重复很长时间。有时你会感到that琐,就像在编码自动机一样,反复在结构上创建基本迭代,这些结构与上周或上个月的结构非常相似。 你已经听说过C 作为一种功能强大的语言的…

【AI绘画接口】Midjourney是什么?Midjourney有官方接口吗?

什么是 Midjourney? 随着AI技术的发展,AI聊天、AI绘画都从小众尝鲜逐渐应用到了生产当中。现在市面上的绘画AI并不少,而 Midjourney 是其中最好用的之一。我们只需要输入一些提示词,Midjourney 就能根据输入的提示词自动生成符合…

怎么找回回收站删除的文件?轻松恢复数据,就看这3个方法!

“求助求助!回收站删除的文件还有找回来的机会吗?一不小心就把回收站中的文件删除了,现在不知道该如何是好了,希望热心的网友们可以帮帮我!” 大家都知道,电脑有一个功能叫回收站,系统会将我们删…

代码随想录 -- day49 -- 121. 买卖股票的最佳时机 、122.买卖股票的最佳时机II

121. 买卖股票的最佳时机 动态规划: dp[i][0] 表示第i天持有股票所得最多现金,dp[i][0] 表示第i天持有股票所得最多现金。 第i-1天就持有股票,那么就保持现状,所得现金就是昨天持有股票的所得现金 即:dp[i - 1][0]第…

echarts折线图每段显示不同的颜色

效果图 配置项: zqChartFour: {title: {text: "一天用电量分布",subtext: "纯属虚构",},tooltip: {trigger: "axis",axisPointer: {type: "cross",},},toolbox: {show: true,feature: {saveAsImage: {},},},xAxis: {type:…

Linux 中nc指令的使用总结

nc指令概述用法一:端口扫描用法二:命令行中发送和接收数据用法三:建立双方通信 nc指令概述 nc 是 Linux 系统中的 netcat 命令之简称,它是一个强大的网络工具,可以用于创建 TCP/UDP 套接字连接。常见的其用法模板可定…

目标检测中生成锚框函数详解

将设一张图片,宽和高为2,2 X torch.rand(size(1,3,2,2)) Y generate_anchors(X,sizes[0.75,0.5,0.25],ratios[1,2,0.5])锚框中心点的设置 # 为每个像素可以生成 nm-1个锚框,整个图像生成 wh(nm-1) def generate_anchors(data,sizes,ratios): # 书上的…

重磅预告 |第十二届中国智能产业高峰论坛9月16日在昌开幕,集团董事长李火亮任专题联席主席,出席本次活动

在这个数字化、智能化社会经济高速迭代的时代,每一次技术的进步都预示着一个全新的未来。在此背景下第十二届中国智能产业高峰论坛即将拉开帷幕。9月16日-9月18日高峰论坛在中国南昌举行,拓世科技集团董事长李火亮将亲身出席本次活动,与众多领…

解决:AD装配输出拾放文件出现闪退问题

PCB在装配输出过程中,需要导出拾放文件,但是今天每次执行这个过程,AD软件就会直接闪退。 重启AD把项目管理器中没有关掉的一系列乱七八糟文件手动关闭关闭AD软件再次重启AD,打开项目重新导出。

YOLOv5 加入SE注意力机制

步骤1:在common.py中添加SE模块 class SE(nn.Module): def __init__(self, c1, c2, r16): super(SE, self).__init__() self.avgpool nn.AdaptiveAvgPool2d(1) self.l1 nn.Linear(c1, c1 // r, biasFalse) self.relu nn.ReL…

付费咨询擅长领域

曾获中国电机工程学报优秀审稿专家,控制与决策审稿专家,系统工程与电子技术审稿专家,计算机科学审稿专家,Mechanical System and Signal Processing审稿专家。 擅长现代信号处理(小波分析类,模态分解类&…

SAP 自定义权限对象开发与使用

如何自定义一个权限对象,然后分配到对应的权限角色中,进行用户权限的控制? 具体实现步骤如下: 1. 创建数据元素 进入事务码: SE11 2. 创建权限字段 进入事务码SU20 3. 创建权限对象类以及权限对象 事务码&#xf…

redis集群的维护(redis-cli --cluster 命令用法)

目录 前言 1、 --cluster create 创建集群 2、--cluster check 检查集群 3、--cluster info 查看集群 4、--cluster fix 修复集群 5、--cluster rehard 迁移槽位 6、 --cluster rebalance 平衡集群 7、 --cluster add-node 集群扩容 8、--cluster del-node …

实现读写分离(MySQL主从数据库)

读写别离(Read/Write Splitting)。 1.原理: 让主数据库(master)处理事务性增、改、删操作(INSERT、UPDATE、DELETE),而从数据库(slave)处理SELECT查询操作。 …

论文复制ChatGPT按钮被发表,撤回后再曝多个类似案例;Midjourney 生成大师级的人像

🦉 AI新闻 🚀 论文复制ChatGPT按钮被发表,撤回后再曝多个类似案例 摘要:一篇物理论文复制了ChatGPT按钮内容,经过两个月同行评审并在杂志上发表。这一现象被知名打假人发现后,发表商决定撤回该论文。此外…

doccano 文本标注工具使用

最近在做面向大模型的文本标注工作,涉及到多人协同的问题,因此用到了doccano工具。 这个工具可以使用docker进行安装,安装之后的启动也都比较简单。 关于基础使用(例如管理员登录、新建任务、上传数据集等)&#xff…

推荐 4 个本周 火火火火 的开源项目

本期推荐开源项目目录: 1. 一个集成了主流 AI 大模型的 APP 2. 模拟人类行为的小镇 3. 离线 OCR 软件 4. 流程图编辑框架 01 一个集成了主流 AI 大模型的 APP 该开源项目集成了主流的大语言模型、绘图模型,基于Flutter开发,支持问答聊天、文生…

10个值得收藏的3D任务角色下载网站

每个人都喜欢免费的东西。 无论是免费的 3D 角色还是游戏资产,我们都喜欢它们。 以下是可以为你的游戏获取免费 3D 角色的前 10 个网站的列表。 你可以将它们用于多种用途,例如 3D 打印或动画剪辑。 如果需要将下载的3D模型转换为其他格式,可…

科技资讯|苹果虚拟纸可在Vision Pro中为广告、书籍等提供MR内容和动画

近日,美国专利商标局正式授予苹果一项与虚拟纸张相关的专利。这是与虚拟纸张这项发明相关的第二项专利,鉴于苹果 Vision Pro 将于明年上市,那么我们离苹果实现虚拟纸张的发明又近了一步。 虚拟纸张将能够包含 2D、3D 和动画等 MR内容&#…