php怎么做网站程序,做平面设计素材的哪个网站好,网络工程技术,永久免费制作网页溪源 | 长沙.NET技术社区开篇我们总是很容易就能写出满足某个特定功能的代码#xff0c;却很难写出优雅代码。又最欣赏那些优雅的代码#xff0c;因为优雅代码更能体现一个开发者的积累。就像写一篇散文#xff0c;有的就像初学者不得其门而入#xff0c;遣词造句都非常困难… 溪源 | 长沙.NET技术社区开篇我们总是很容易就能写出满足某个特定功能的代码却很难写出优雅代码。又最欣赏那些优雅的代码因为优雅代码更能体现一个开发者的积累。就像写一篇散文有的就像初学者不得其门而入遣词造句都非常困难然后纠纠结结最终不了了之。或者啰哩吧嗦看起来说了一堆其实就像是村妇闲聊毫无重点不过是口水文而已。好代码应该是这样的如涓涓细流、如同一首诗一篇优美的故事将作者编写代码时的情感慢慢铺垫开来或是高潮迭起此起彼伏或是平铺直述却蕴含道理。我始终相信优秀的代码是有灵魂的代码的灵魂就是作者的逻辑思维。编写整洁代码 or 非整洁代码就像平时生活中是否注意爱护环境的一点点小习惯一旦坏味道代码没有及时处理就会成为破窗效应然后逐渐的代码越写越烂最终这些代码要么以重构收场要么就被抛弃。我们见过太多没有毫无质量可言的代码许多时候开发者们由于能力原因、或者时间有限写了许多能够满足当前工作的代码然后就弃置高阁不再理会。于是代码写之前的只有自己和上帝能理解代码的意思而写完了之后只有上帝能懂了还有一些开发者说我只会写代码不会优化代码他们仿佛特别勤奋每天都会比其他人都热衷于熬工时但是写出的代码实际上是一个个难以维护的技术债。而且许多代码的作者总喜欢找各种借口来抵赖例如喜欢说代码出了问题都是底层框架太垃圾了、或者别人的代码封装得太差。他们总是抱怨这抱怨那但是即便有优秀的框架、技术就一定能写出优秀的代码么在这里笔者列举了平时看到过一些自认为不太整洁的代码以及与《代码整洁之道》Clean Code · A Handbook of Agile Software Craftsmanship一书中相对应的范例欢迎大家一起来拍砖。经验有限时间仓促请轻喷。一些栗子1、命名规则1.1 变量命名和方法命名在我们刚刚开始学习写代码的古老时代或许会有下面这种习惯。这是一个喜欢用自己的姓名来命名类和方法的作者在他的代码中经常可以看到这样奇怪的对象定义而且他还喜欢用a,b,c,d,e,f或者s1,s2这样的命名仿佛他的代码自带混淆特效。这样的代码嗅起来会不会觉得充斥着奇怪的味道另外有没有发现有许多开发者喜欢用 GetData() 来定义获取数据的方法然后这个方法就成为一个万金油的方法不管是爬虫采集、或者数据绑定无论是 C# 写的后端或者 Java 写的后端代码或者用 vue 写的前端代码仿佛在任何场景、任何数据应用都可以看到这样的方法。如果一个项目中有十几个地方都出现了这个 GetData() 方法那种感觉一定非常难受。1.2 Model、Dto 傻傻分不清楚随着技能的增长或许我们会学到一些新的代码概念例如Model、DTO 是经常容易弄混淆的一种概念但是在某些代码中出现了下面的命名方式就有点令人窒息了。这位大概是一位对概念严重消化不良的资深开发者居然同时把 Model 和 DTO 复用在一个对象上当然一个开发者定义变量的背后一定有他的动机。他到底是想要的是用来在 MVC 模式解决数据传输和对象绑定的模型对象还是用于传输数据的 DTO 呢--其实他定义这个对象是为了定义存储数据对象的实体 Entity 。1.3特殊情况术语和字段对照表非常重要近年来开发者素质越来越高所以许多优秀开发者会倾向于使用翻译软件来翻译变量名然后用英语来命名但是即便如此许多政务项目总是能嗅出一些奇怪的味道。例如前不久看到一条这样的短信原图已经消失xxx公积金中心提醒您您于{TQSJ}日进行了{TQCZ}操作账上剩余金额为{SYJE}元。这是个bug将xxx公积金中心的某些秘密透露在大家面前。作为一个严谨的项目居然使用中文首字母大写命名法这让习惯于大驼峰、小驼峰的我看了之后尴尬癌犯了很不舒服。但是这也是许多政务信息化项目的中字段命名的规范而且在这种情况下往往会输出一份非常规范的数据库字段对照表确保中文和首字母的语义不让人产生歧义。所以特定语境下变量和方法本身没有严格的规定但是一定要使用恰当的语境概念对于这样的特定场景尽量维护一份实时更新的术语表吧。2、状态码返回值2.1业务逻辑状态码似乎在对外提供接口时使用下列接口状态码是一种比较常见的惯例。提供统一格式的 code 状态码以及返回的消息和成功返回结果时的填充数据能够让开发者高效的完成接口对接无需关心http状态码背后的含义。2.2用 http 状态码为什么不够上面这是一种经典的流派还有一种流派则会使用http状态码来返回指定的数据事实上 http 协议本身已经提供了许多状态码例如下面的这些大家都非常熟悉的状态码。但是这些状态码为啥不够主要是为了减少前后端、服务上下游之间接口对接的难度也是一种提高效率的方式。但是 http 状态码是一种通用的格式应尽量使用这种方式而不应该通过解析正常响应后的 json 来判断是否正确操作。 3、switch 语句与判断语句3.1 面向过程式或面向对象式我曾经跟小组中一位大佬交流他的一段代码他的这段代码大概是这样的。且不说这位大佬的代码是写得好或者不好仅仅就这200多行代码的4个大switch读起来大概会让人便秘难受吧。于是在我读完这段代码之后我冒死向他请教这么写代码的原因他说我这个流程处理就是一个简单的用例场景哪里还有什么可以优化的余地我跟他介绍了20分钟代码封装的必要性于是他把代码写成了这样。这酸爽令人简直难以置信。事实上这个新鲜出炉的遗留应用正是这样一点点堆积了许多总代码行超过千行的类文件《代码整洁之道》书上有一个类似的例子大概与上文类似Robert 大叔给出了这样的建议对于switch 语句我的规矩是如果只出现一次用于创建多态对象而且隐藏在某个集成关系中在系统中其他部分看不到就还能容忍。当然也要就事论事有时我也会部分或全部违反这条规矩。上文我给出的示例有点像面向过程的代码风格而 Robert 大叔在他的书中写下的示例是这样的抽象工厂模式的示例。 这清爽的感觉让人很舒服啊。3.2 孰优孰劣当然原示例是一个流程处理的例子似乎大家的流程处理代码都习惯于使用这种面向过程风格的写法反正要加判定条件就加一个 case 就可以了。而在某些特定情况下甚至用 if / else 来写逻辑判断更简单于是我们经常在某些销量很好的快速开发平台中看到这样的例子。 这些典型的面向过程风格的代码确实读起来似乎更加简单、而且也易于实现。Robert 大叔是这样说的过程式代码使用数据结构的代码便于在不改动既有数据结构的前提下添加新函数面向对象代码便于在不改动既有函数的前提下添加新类。反过来讲也说得通过程式代码难以添加新数据结构因为必须修改所有函数面向对象代码难以添加新函数因为必须修改所有类。所以究竟是使用面向过程式代码还是面向对象式代码没有万试万灵的灵丹妙药。4、奥卡姆剃刀定律、得墨忒耳律4.1“如非必要勿增实体”一旦开始初步掌握面向对象开发的基本原则于是我们就会新建许多各种不同的模型对象。尤其是在webapi接口开发过程中更是如此。 切勿浪费较多东西去做用较少的东西同样可以做好的事情。4.2 得墨忒耳律假设有一段代码是这样的。会不会为了获得某些数据而写出这样的代码呢这样就是典型的对得墨忒耳律的违背。这个原则指出模块不应了解它所操作对象的内部情形。更准确的说得墨忒耳律认为类C的方法f只应该调用以下对象的方法C本身由方法f创建的对象。作为参数传递给f的对象由C的实体变量持有的对象。对象不应调用由任何函数返回的对象的方法。换言之只跟朋友说话不与陌生人说话。在上文中我举的例子祖父只跟自己的亲儿子Father说话而不跟孙子(Me)说话。5、圈复杂度在软件测试的概念里圈复杂度用来衡量一个模块判定结构的复杂程度数量上表现为线性无关的路径条数即合理的预防错误所需测试的最少路径条数。圈复杂度大说明程序代码可能质量低且难于测试和维护根据经验程序的可能错误和高的圈复杂度有着很大关系。据说在Oracle数据库中有一些屎山代码是通过一堆标识量来判断某些特定逻辑的大概是这样的。示例仅供参考由于资源限制未能考证还请大佬指正一二。这是一个圈复杂度非常复杂的方法我想任何一个读到这样代码的开发者都会对自己的人生充满了积极而乐观的判断那就是“活着比一切都好”。对于这样的代码我们应该尽可能的降低代码的圈复杂度让程序满足基本可读的需求。6、注释我曾经参加过一个使用objectc编写的应用的其中有一段代码是这样的这个flag大概是魔法值作者未经考证直接就在代码中使用了。然后一直流传下来成为一段佳gui话hua。还有这样的注释。傻傻分不清楚。还有这样的。Robert大叔如是说什么也比不上放置良好的注释来得有用。什么也比不会乱七八糟的注释更有本事搞乱一个模块。什么也不会比陈旧、提供错误信息的注释更有破坏性。当然很多中国程序员自称其变量命名是自注释的例如大概是这样的。万能的 Is 命名法只要是判断状态皆可用。每个程序员能够成功的生存下来都不容易他一定有异于常人的本事。)7、霰xian 第四声弹式修改CRUD开发者或许经常会看到这样的代码例如如果我要对某一个对象的状态 Status进行更改可能会这么做这种霰弹式代码中一处代码规则的变化可能会需要对许多处代码进行同步修改使得我们的代码异常的难以维护。8、异常有时候可能会遇到这样的代码在方法中定义一些文本的状态码然后调用方法时再去判断这个状态码的内容当返回错误码时要求调用者立即处理错误。不如直接抛出异常让异常处理机制进行处理吧。9、边界9.1 模块间的边界即便是简单的CRUD应用系统优秀的开发者也能更好的处理应用程序模块间的边界。某种意义上讲应用程序内部的边界看起来或许没有明确的界限之分但是稍不留心就可能导致应用程序间关系过于紊乱让其他开发者捉摸不透。例如假设有一段代码是这样的在用户操作类中加入了一个获取应用数据的方法确实会让人很费解吧。9.2应用间的边界相对而言或许应用间的边界似乎能相对清晰的分析出来并非如此。在当今时代我们很少开发完全与其他应用系统没有任何关联的独立软件这意味着我们或许无时无刻都得与其他第三方应用进行接口行为或数据的交换。这让我们必须确保采取措施让外来代码干净利落地整合进自己的代码中。假设有一段代码是这样的在《代码整洁之道》书中Robert大叔推荐应该第三方接口进行隔离通过Map那样包装或者使用适配器模式将我们的接口转换成第三方提供的接口。让代码更好地与我们沟通在边界两边推动内部一致的用法当第三方代码有改动时修改点也会更少。总结写代码是开发者的基础技能无论你是.NET 开发者或者 Java 开发者你都在努力用代码实现自己的梦想。如同韩磊老师在译作《代码整理之道》封面上总结全书写下的那句诗“细节之中自有天地整洁成就卓越代码”。卓越代码从来不仅仅只是功能完善、代码齐全做好细节每个细节就是一方小天地。优雅的代码不仅仅只是开发者的个人能力的体现更是开发者的立足之本。努力改善坏习惯提高代码质量时刻消除异味时刻提高自己更是个人技能的全面发展的必然要求。