什么是优雅的代码设计

news2024/11/24 2:28:13

今天我来解释一下什么样的代码才是优雅的代码设计。当然我们的代码根据实际的应用场景也分了很多维度,有偏向于底层系统的,有偏向于中间件的,也有偏向上层业务的,还有偏向于前端展示的。今天我主要来跟大家分析一下我对于业务代码的理解以及什么样才是我认为的优雅的业务代码设计。

大家吐槽非常多的是,我们这边的业务代码会存在着大量的不断地持续的变化,导致我们的程序员对于业务代码设计得就比较随意。往往为了快速上线随意堆叠,不加深入思考,或者是怕影响到原来的流程,而不断在原来的代码上增加分支流程。

这种思想进一步使得代码腐化,使得大量的程序员更失去了“好代码”的标准。

那么如果代码优雅,那么要有哪些特征呢?或者说我们做哪些事情才会使得代码变得更加优雅呢?

结构化

结构化定义是指对某一概念或事物进行系统化、规范化的分析和定义,包括定义的范围、对象的属性、关系等方面,旨在准确地描述和定义所要表达的概念或事物。

我觉得首要的是代码,要一个骨架。就跟我们所说的思维结构是一样,我们对一个事物的判断,一般都是综合、立体和全面的,否则就会成为了盲人摸象,只见一斑。因此对于一个事物的判断,要综合、结构和全面。对于一段代码来说也是一样的标准,首先就是结构化。结构化是对一段代码最基本的要求,一个有良好结构的代码才可能称得上是好代码,如果只是想到哪里就写到哪里,一定成不了最优质的代码。

代码的结构化,能够让维护的人一眼就能看出主次结构、看出分层结构,能够快速掌握一段代码或者一段模块要完成的核心事情。

精简

代码跟我们抽象现实的物体一样,也要非常地精简。其实精简我觉得不仅在代码,在所有艺术品里面都是一样的,包括电影。电影虽然可能长达一个小时,两个小时,但你会发现优雅的电影它没有一帧是多余的,每出现的一个画面、一个细节,都是电影里要表达的某个情绪有关联。我们所说的文章也是一样,没有任何一个伏笔是多余的。代码也是一样,严格来说代码没有一个字符、函数、变量是多余的,每个代码都有它应该有的用处。就跟“奥卡姆剃刀”原理一样,每块代码都有它存在的价值包括注释。

但正如我们的创作一样,要完成一个功能,我们把代码写得复杂是简单的,但我们把它写得简单是非常难的。代码是思维结构的一种体现,而往往抽象能力是最为关键的,也是最难的。合适的抽象以及合理的抽象才能够让代码浓缩到最少的代码函数。

大部分情况来说,代码行数越少,则运行效率会越高。当然也不要成为极端的反面例子,不要一味追求极度少量的代码。代码的优雅一定是精要的,该有的有,不该有的一定是没有的。所以在完成一个业务逻辑的时候,一定要多问自己这个代码是不是必须有的,能不能以一种简要的方式来表达。

善用最佳实践

俗话说太阳底下没有新鲜事儿,一般来说,没有一个业务场景所需要用到的编码方式是需要你独创发明的。你所写的代码功能大概率都有人遇到过,因此对于大部分常用的编码模式,也都大家被抽象出来了一些最佳实践。那么最经典的就是23种设计模式,基本上可以涵盖90%以上的业务场景了。

以下是23种设计模式的部分简单介绍:

  1. 单例模式(Singleton Pattern):确保类只有一个实例,并提供全局访问点。

  2. 工厂模式(Factory Pattern):定义一个用于创建对象的接口,并让子类决定实例化哪个对象。

  3. 模板方法模式(Template Method Pattern):提供一种动态的创建对象的方法,通过使用不同的模板来创建对象。

  4. 装饰器模式(Decorator Pattern):将对象包装成另一个对象,从而改变原有对象的行为。

  5. 适配器模式(Adapter Pattern):将一个类的接口转换成客户希望的另一个接口,以使其能够与不同的对象交互。

  6. 外观模式(Facade Pattern):将对象的不同方面组合成一个单一的接口,从而使客户端只需访问该接口即可使用整个对象。

我们所说的设计模式就是一种对常用代码结构的一种抽象或者说套路。并不是说我们一定要用设计模式来实现功能,而是说我们要有一种最高效,最通常的方式去实现。这种方式带来了好处就是高效,而且别人理解起来也相对来说比较容易。

我们也不大推荐对于一些常见功能用一些花里胡哨的方式来实现,这样往往可能导致过度设计,但实际用处可能反而会带来其他问题。我觉得要用一些新型的代码,新型的思维方式应该是在一些比较新的场景里面去使用,去验证,而不应该在我们已有最佳实践的方式上去造额外的轮子。

这个就比如我们如果要设计一辆汽车,我们应该采用当前最新最成熟的发动机方案,而不应该从零开始自己再造一套新的发动机。但是如果这个发动机是在土星使用,要面对极端的环境,可能就需要基于当前的方案研制一套全新的发动机系统,但是大部分人是没有机会碰到土星这种业务环境的。所以通常情况下,还是不要在不需要创新的地方去创新。

除了善用最佳实践模式之快,我们还应该采用更高层的一些最佳实践框架的解决方案。比如我们在面对非常抽象,非常灵活变动的一些规则的管理上,我们可以使用大量的规则引擎工具。比如针对于流程式的业务模型上面,我们可以引入一些工作流的引擎。在需要RPC框架的时候,我们可以根据业务情况去调研使用HTTP还是DUBBO,可以集百家之所长。

持续重构

好代码往往不是一蹴而就的,而是需要我们持续打磨。有很多时候由于业务的变化以及我们思维的局限性,我们没有办法一次性就能够设计出最优的代码质量,往往需要我们后续持续的优化。所以除了初始化的设计以外,我们还应该在业务持续的发展过程中动态地去对代码进行重构。

但是往往程序员由于业务繁忙或者自身的懒惰,在业务代码上线正常运行后,就打死不愿意再动原来的代码。第一个是觉得跑得没有问题了何必去改,第二个就是改动了反而可能引起故障。这就是一种完全错误的思维,一来是给自己写不好的线上代码的一个借口,二来是没有让自己持续进步的机会。

代码重构的原则有很多,这里我就不再细讲。但是始终我觉得对线上第一个要敬畏,第二个也要花时间持续续治理。往往我们在很多时候初始化的架构是比较优雅的,是经过充分设计的,但是也是由于业务发展的迭代的原因,我们持续在存量代码上添加新功能。

有时候有一些不同的同学水平不一样,能力也不一样,所以导致后面写上的代码会非常地随意,导致整个系统就会变得越来越累赘,到了最后就不敢有新同学上去改,或者是稍微一改可能就引起未知的故障。

所以在这种情况下,如果还在追求优质的代码,就需要持续不断地重构。重构需要持续改善,并且最好每次借业务变更时,做小幅度的修改以降低风险。长此以往,整体的代码结构就得以大幅度的修改,真正达到集腋成裘的目的。下面是一些常见的重构原则:

  1. 单一职责原则:每个类或模块应该只负责一个单一的任务。这有助于降低代码的复杂度和维护成本。

  2. 开闭原则:软件实体(类、模块等)应该对扩展开放,对修改关闭。这样可以保证代码的灵活性和可维护性。

  3. 里氏替换原则:任何基类都可以被其子类替换。这可以减少代码的耦合度,提高代码的可扩展性。

  4. 接口隔离原则:不同的接口应该是相互独立的,它们只依赖于自己需要的实现,而不是其他接口。

  5. 依赖倒置原则:高层模块不应该依赖低层模块,而是依赖应用程序的功能。这可以降低代码的复杂度和耦合度。

  6. 高内聚低耦合原则:尽可能使模块内部的耦合度低,而模块之间的耦合度高。这可以提高代码的可维护性和可扩展性。

  7. 抽象工厂原则:使用抽象工厂来创建对象,这样可以减少代码的复杂度和耦合度。

  8. 单一视图原则:每个页面只应该有一个视图,这可以提高代码的可读性和可维护性。

  9. 依赖追踪原则:对代码中的所有依赖关系进行跟踪,并在必要时进行修复或重构。

  10. 测试驱动开发原则:在编写代码之前编写测试用例,并在开发过程中持续编写和运行测试用例,以确保代码的质量和稳定性。

综合

综上所述,代码要有结构化、可扩展、用最佳实践和持续重构。追求卓越的优质代码应该是每一位工程师的基本追求和基本要求,只有这样,才能不断地使得自己成为一名卓越的工程师。

更多精彩原创内容,请关注公众号:ali老蒋,或访问我的原创博客:java开发者

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

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

相关文章

电子科技大学计算机系统结构:课后作业

计算机体系结构作业答案 第一二章作业 1.试述Flynn 分类的4 种计算机系统结构有何特点。 参考答案: Flynn按照指令流和数据流两种不同的组合,把计算机系统的结构分为以下4 类: (1)单指令流单数据流SISD&#xff0…

这款AI绘画工具也太太太赞了!模型丰富,轻松绘画,赶快收藏起来!

现今科技发展迅速,让人工智能(AI)成为了我们日常生活中的必备之物。在艺术领域,AI技术也开始广泛应用。特别是AI绘画软件,以其高效、精准的绘画方式,已成为越来越多艺术家、设计师和普通用户绘画的首选工具…

HUSTOJ使用指南

如何快速上手(了解系统的功能)? admin管理员用户登录,点击右上角管理,仔细阅读管理首页的说明。 切记:题目导入后一次只能删一题,不要导入过多你暂时用不上的题目,正确的方式是每次…

Cron在前端的使用,vue与element ui的vue-cron插件的使用及将定时任务cron表达式解析成中文

文章目录 vue-cron插件的使用安装依赖引用Vue页面去掉秒和年定时任务cron解析成中文该插件存在的一个缺陷 vue-cron插件的使用 安装依赖 执行下面npm命令: npm install vue-cron --save 引用 在想使用cron的vue页面引入以下: import VueCron from ‘vue-cron’ …

node版本管理工具nvm安装和使用

公司的前端项目使用的node版本是10.11.1比较老的版本,但是新开发的项目需要使用vue3viteelectron,需要使用较新的node版本 。综上决定研究研究nvm对node进行切换管理。有相同需求的朋友希望下面的文章可以帮助到你们。借鉴了一些博主的文章,在文章里也总…

重磅!Cloud Ace 在班加罗尔和孟买成立新的据点

Cloud Ace Cooperation(总部位于东京千代田区; Makoto Aoki,总裁)很高兴地宣布,我们已经在班加罗尔建立了新的开发中心,并在孟买建立了新的销售办事处,作为 Cloud Ace 进一步扩大公司在印度业务…

docker-compose通过volume恢复mysql数据

概述 docker rm是docker删除容器的命令。 会清空容器内的所有数据和配置,即真正的将容器清空并删除。 但是之前通过volume挂载到宿主机上是不受影响的。 docker rm -v如果是-v的命令那么会同时删除通过volume映射到宿主机上的文件 通过volume恢复数据 使用docke…

第六十六天学习记录:《高质量C/C++编程指南》中附录的考试试卷(含答案)

该试卷转载自林锐《高质量C/C编程指南》,先贴下原作者的版权声明。 版权声明:本书的大部分内容取材于作者一年前的书籍手稿(尚未出版),现整理汇编成为上海贝尔网络应用事业部的一个规范化文件,同时作为培训…

chatgpt赋能python:Python如何分配内存

Python如何分配内存 Python是一种动态解释型语言,它在运行时分配内存用于存储变量和对象。Python提供了一种内存管理机制,它能够动态地分配和管理内存。本文将介绍Python如何分配内存并讨论与之相关的一些最佳实践。 Python内存管理机制 Python中的所…

Vue.js 中的性能优化是什么?如何进行性能优化?

Vue.js 中的性能优化是什么?如何进行性能优化? Vue.js 是一款流行的前端框架,它具有响应式数据绑定、组件化开发、虚拟 DOM 等特性,使得开发者可以更加高效地构建交互式的用户界面。然而,在实际开发中,由于…

LeetCode 2352. 相等行列对:手动哈希

【LetMeFly】2352.相等行列对:手动哈希 力扣题目链接:https://leetcode.cn/problems/equal-row-and-column-pairs/ 给你一个下标从 0 开始、大小为 n x n 的整数矩阵 grid ,返回满足 Ri 行和 Cj 列相等的行列对 (Ri, Cj) 的数目。 如果行和…

ArduPilot之H743遗留配置问题解决

ArduPilot之H743遗留配置问题解决 1. 源由2. 资源3 遗留问题汇总3.1 问题一:无法设置VTX 600m3.2 问题二:双向Dshot未显示RMP转速3.3 问题三:mavlink esp32 2.4G WiFi电传 4. 参考资料 1. 源由 在ArduPilot开源代码之H743BMI270x2ChibiOS配置…

步进电机相数、细分、步距角、接线方法

1、旋转步进电机 旋转步进电机就是电机是一步一步转动的,故叫旋转步进电动机。每输入一个脉冲冲信号,该电动机就转过一定的角度,因此旋转步进电机是一种把脉冲变为角度位移的执行元件。 可通过脉冲频率控制步进电机的旋转速度,通…

ChatGPT中文版提示词学习手册, 学完工作效率提升百倍!

既然你对ChatGPT及其功能有了⼀些了解,让我们更深入地了解⼀下ChatGPT是什么以及它是如何工作的。 那么ChatGPT是如何工作的呢?在高层次上,这个过程可以分解为以下步骤: 1. 用户将文本输入ChatGPT界面。这可能是一个问题&#xf…

Android AIDL的使用(配源码)

零、完整源代码 链接: https://github.com/jx0260/TestGradle 一、创建AIDL文件 // IShopAidlInterface.aidl package com.example.testgradle;// Declare any non-default types here with import statementsinterface IShopAidlInterface {String getProductInfo(int prod…

speedtest-cli 源码集成

speedtest-cli 是一个开源的测速sdk,可以下载源码集成到自己的项目中,源码是C代码,所以可以集成到linux终端程序中,如果在Android APP中需要通过NDK开发集成,下面是在linux设备中集成过程。 1、首先在github中下载源码…

代码随想录算法训练营第四十九天|121. 买卖股票的最佳时机|122.买卖股票的最佳时机II

LeetCode121. 买卖股票的最佳时机 动态规划五部曲: 1,确定dp数组(dp table)以及下标的含义:dp[i][0] 表示第i天持有股票所得最多现金,其实一开始现金是0,那么加入第i天买入股票现金就是 -pric…

界面组件DevExpress Reporting v22.2亮点 - 添加更多自定义支持

DevExpress Reporting是.NET Framework下功能完善的报表平台,它附带了易于使用的Visual Studio报表设计器和丰富的报表控件集,包括数据透视表、图表,因此您可以构建无与伦比、信息清晰的报表 界面组件DevExpress Reporting v22.2已正式发布一…

CDN如何帮助我们的网站实现安全?

各类网络攻击正在变得越来越复杂,它们有可能导致服务可用性的严重中断和企业的财务损失。根据Gartner的数据,IT行业平均停机每分钟就将为企业带来超过3万元的损失。 对于每个具有在线相关业务的企业,如何能以安全、可靠和快速的方式服务于用…

MySQL(进阶篇2.0)

SQL优化 插入数据 insert 如果需要一次性往数据库表中插入多条记录,可以从以下三个方面进行优化 1、优化方案一 批量插入数据 insert into tb_test values(1, Tom),(2,Cat),(3,Jerry);2、优化方案二 手动控制事务 start transaction; insert into tb_test v…