源码怎么用,有了源码该如何使用

简介:和大家一起探讨一下优雅代码一、好代码的定义谈到好代码,我的第一想法就是优雅,那我们如何该写出好的代码,让阅读的人感受到优雅呢?首先简单探讨一下优雅代码的定义关于好代码的定义,各路大神都给出了自己

简介: 和大家一起探讨一下优雅代码

一、好代码的定义

谈到好代码,我的第一想法就是优雅,那我们如何该写出好的代码,让阅读的人感受到优雅呢?首先简单探讨一下优雅代码的定义

关于好代码的定义,各路大神都给出了自己的定义和见解

整洁的代码如同优美的散文。—— Grady Booch

任何一个傻瓜都能写出计算机可以理解的代码。唯有写出人类容易理解的代码,才是优秀的程序员。—— Martin Fowler

首先要达成一致,我们写的代码,除了用于机器执行产生我们预期的效果之外,更多的时候是给人读的,可能是后续的维护人员,更多时候是一段时间后的作者本人,因此优雅面向不同的用户有两层含义的解读

对人而言,代码的整洁,清晰的逻辑

对机器而言,准确性、执行性能、异常处理机制等

这次,我们就来聊一聊,什么代码是优雅的代码,怎样写出优雅的代码

二、代码整洁

1. 有意义的命名

简单说就是类、方法、变量的命名要名副其实,要能描述清晰自己的职责。一个好的命名能输出更多的信息,它会告诉你,它为什么存在,它是做什么事的,应该怎么使用。一个简单的衡量标准是,如果命名完仍需要注释来补充语义,那就不是名副其实;

选个好名字要花时间,但省下的时间的时间比花掉的多,一旦发现有更好的名称,就换掉旧的。

举个栗子

public List<int[]> getItem() {List<int[]> list1 = new ArrayList<int[]>();for (int[] x: theList)if (x[0] == 4)list1.add(x);return list1;}

整体逻辑没啥问题,读完之后,就有很多问题在脑海中产生

1. theList中是存储什么东西的数组?

2. theList第一个值是做什么的?

3. 值4的意义又是什么?

4. 返回的列表该怎么使用?

代码应该体现所处的情景,比方说上述的代码所处情景是我们正在开发一种扫雷游戏,盘面是名为theList的单元格列表,那就将其名称改为gameBoard。

盘面上每个单元格都用一个简单数组表示。零下标条目是一种状态值,而这种状态值为4代表“已标记”。只要改为有意义的名称,代码就得到了改进。

更进一步,不用int数组来表示单元格,而是另写一个类。该类包括一个名副其实的函数(称为isFlagged),从而掩盖住哪个魔术数4,得到新的函数版本。

public List<Cell> getFlaggedCells() {List<Cell> flaggedCells = new ArrayList<Cell>();for (Cell cell : gameBoard)if (cell.isFlagged())flaggedCells.add(cell);return flaggedCells;}

买了个网站源码后的使用方法如下:1、申请域名要访问一个网站,必须要输入域名,域名相当于这个网站的门牌号,没有域名是无法找到和访问网站的,因此必须找域名提供商家,购买域名。2、购买网站空间有了域名,还要有网站空间用。

2. 优雅的注释

实际上,有了源码该如何使用,只要我们的代码有足够的表达力,能清晰的通过命名来做到名副其实,就不太需要注释,或者根本不需要;注释的存在往往是弥补我们无法用代码清晰表达意图的情况。可以想象一下,每次自己发现需要写注释的时候,是什么心态,担心此处代码明天自己看不懂或者别人看不懂,那有没有考虑用更好的语义的代码来替代。

但尽管有注释,也有好有坏,有时候注释也会撒谎,通常注释存在的越久,就离其描述的代码越远,变得越来越离谱;因为代码在变动在迭代,在注释和代码间可能会插入新的代码,旧代码我们通常copy来copy去,分离又重组,但注释一般不会修改,就会造成注释和描述的代码分离,对阅读者造成更大的迷惑。

我们在需要写注释的时候就要告诉自己,能不能用代码来进行描述。以下是一些坏代码的注释bad case

1. 一些被注释掉的代码//something code//something code2. 位置标记//beginsometing code;//end3. 签名标记/** add by xiaoli*/4. 非公用方法的javadoc/*** doSomething*/private void doSomething(){}5. 日志式注释/** add xx* update sometimes* update sometimes* update sometimes*/6. 误导性注释//此处怎样xx

3. 优雅的函数

3.1 务必要短小

方法应该有多短小?没有明确约束,idea也不会限制你,但通常我们的方法不该长于一屏,至少多于一屏或者横向外溢到屏幕以外最直观的就会造成可读性体验差,读了下面忘记上面,新手,左右拖拽等。对大多数笔记本来说一屏大概就30行左右。短小精简的方法要比30行短很多,比如

public String renderPageWithSetupAndTeardowns(Page page,boolean isSuite) throws Exception{if(isTestPage(page)){includeSetupAndTeardownPages(page,isSuite);}return page.getHtml();}

if语句、else语句、while语句等,其中的代码应该只有一行。

改行通常是一个调用语句,这样不但能保持短小,还可以给调用方法命名一个有说明性的名字,进一步增加代码的可读性

3.2 只做一件事

另外,多个职责耦合在一起,会影响复用性。针对方法而言更是如此。方法作为程序的原子单元,保持单一会有效提升复用性。 那怎么判断一个方法是否只做了一件事。最简单的规则就是看看该方法是否能在拆出一个方法,且拆出去的方法是不同于该方法的诠释和实现。但是要注意同一方法的逻辑层级务必要一致。

3.3 抽象层级一致

抽象层级一致也是对方法只做一件事的更高要求,抽象层级不一致的代码一定是做了多件事。

我们读代码通常是自顶向下阅读,我们想让每个方法后面都跟着位于下一层级的方法,这样我们可以依着抽象层级向下阅读了。我们也需要这样阅读代码,先有整体在展示细节,这种叫向下规则。这也是保持方法短小,确保只做一件事的诀窍。一旦方法中混杂不同的抽象层级,会让人很迷惑,因为没办法这个方法中判断某个表达式是基础概念还是细节,更恶劣的是,一旦细节与基础概念混杂,更多的细节就会纠缠不清,举例子我们想写一个冰冻大象的需求

1:如果是php源码,在本地电脑使用时。要先安装phpnow环境套件包(下附),里面包含 了php+mysql等,也是用迅雷搜索下载。那个套件安装很傻瓜化,不用我说了。2:把所有的源码复制到套件安装目录下的htdocs文件夹里,使用。

/把大象装进冰箱public void frozenElephant(){//1. 捕捉大象//2. 运输大象//3. 打开冰箱//4. 放入大象//5. 关闭冰箱}

这个例子的1.2两步就不是一个层级的逻辑,是属于更高层级的抽象。3.4.5都是将大象放入冰箱的步骤,属于低层级的抽象。可以将代码拆分为如下实现,将高抽象层级的代码聚合提取出来,细节在分别单独实现,如下

public void frozenElephant(){//1. 捕捉大象catchElephant();//2. 运输大象transportElephant();//将大象放入冰箱putElephantInRefrigerator();}public void catchElephant(){}public void transportElephant(){}public void putElephantInRefrigerator(){//打开冰箱//放入大象//关闭冰箱}

3.4 使用异常替代返回错误码

针对错误码的判断会导致更深层次的嵌套结构,返回错误码就意味着要求调用者跟着处理错误,如下

if(deletePage() == OK){if(registry.deleteReference(page.name) == OK){if(configKeys.deleteKey(page.name.makeKey) == OK){logger.log(&34;)}else{logger.log(&34;)}}else{logger.log(&34;)}}else{logger.log(&34;)return Error;}

一般我们还需要将try/Catch代码块给抽离出去,另外形成方法。防止代码块过多搞乱代码结构,分不清错误处理还是正常流程。同时因为方法只做一件事,错误处理就是一件事,因此错误处理的方法不应该在做其他事,也就是如果一个方法中有try关键字,那try就是方法的开头。catch/finally代码块后面也不应该再有内容,如下

try{deletePage(page);registry.deleteReference(page.name);configKeys.deleteKey(page.name.makeKey);}catch(Exception e){logger.log(e.getMessage());}

3.5 使用第三方库

比如Lombok组件通过注解的方式,在编译时自动为属性生成构造器、getter/setter、equals、hashcode、toString方法 举例如下:

beanUtils

JavaBean进行各种操作,克隆对象、属性等等

codec

处理常用的编码方法的工具类包,例如DES、SHA1、MD5、Base64等.

collections

java集合框架操作

configuration

java应用程序的配置管理类库

io

io工具的封装

源码怎么用

lang

Java基本对象方法的工具类包 如StringUtils、ArrayUtils等等.

logging

提供的日志接口

net

提供了客户端和服务器端的数据验证框架

三、代码重构

重构是对软件内部结构的一种调整,目的是在不改变软件可观察行为的前提下,提高其可理解性,降低其修改成本。

在重构之前一定要知道,一旦开始对类和方法进行重构,就需要事前有完备的单元测试用例来保障重构的准确性,每次重构之后都要去执行对应的单元测试用例,验证重构的正确性!

1. 识别代码的坏味道

1.1 重复的代码

如果在一个以上的地点看到相同的代码结构,可以肯定的是,想办法抽线出来合而为一,代码会变得更好。一般包含几个点的重复

最单纯的重复代码就是“同一个类的两个函数含有相同的表达式”。这时候需要做的就是采用提炼函数提炼出重复的代码,然后让这两个地点都调用被提炼出来的那一段代码

如果重复代码只是相似而不是完全相同,需要先尝试用移动语句重组代码顺序,把相似的部分放在一起以便提炼。

如果重复的代码段位于同一个超类的不同子类中,可以使用函数上移来避免在两个子类之间互相调用。

1.2 过长的函数

百分之九十九的场合里,要把函数变短,只需使用提炼函数。找到函数中适合集中在一起的部分,将它们提炼出来形成一个新函数。

如果函数内有大量的参数和临时变量,最终就会把许多参数传递给被提炼出来的新函数,导致可读性几乎没有任何提升。此时可以经常运用以查询取代临时变量来消除这些临时元素。引入参数对象和保持对象完整则可以将过长的参数列表变得更简洁一些。

如果有多个switch语句基于同一个条件 进行分支选择,就应该使用以多态取代条件表达式。

1.3 数据的可变性

可以用记事本打开的好多行英文的,用编程语言写好的软件源程序经过编译成目标程序,才能运行。一般目标程序不能再修改了。电脑上安装的软件都是目标程序。源程序不可能直接运行的。提倡软件开源的人士认为应该提供源程序给用户。

对数据的修改经常导致出乎意料的结果和难以发现的bug。在一处更新数据,却没有意识到软件中的另一处期望着完全不同的数据,于是出现难以预料的bug,往往比较难排查(需要排查数据流转的整体链路),这就需要一些方法用于约束对数据的更新,降低数据可变性的风险。

可以用封装变量来确保所有数据更新操作都通过很少几个函数来进行,使其更容易统一监控和演进

在“本地站点”窗口中,定位到网站源码所在的上传目录,选中所有待上传的文件,右击从弹出的右键菜单中选择“上传”项; 此时所有的网站源码文件将排队上传至远程服务器“Public-html”目录下,且可以在状态窗口中查看当前文件传输情况; 当。

如果一个变量在不同时候被用于存储不同的东西, 可以使用拆分变量将其拆分为各自不同用途的变量,从而避免危险的更新操作。

使用移动和提炼函数尽量把逻辑从处理更新操作的代码中搬移出来,将业务处理逻辑代码与执行数据更新操作的代码分开。

1.4 模块单一职责

所谓模块化,就是力求将代码分出区域,最大化区域内部的交互、最小化跨区域的交互。但是经常出现一个函数跟另一个模块中的函数或者数据交流格外频繁,远胜于与所处模块内部的交流,这就是模块功能不单一的典型情况。

总看到某个函数为了计算某个值,从另一个对象那儿调用半打的取值函数。如果这个函数需要跟这些数据待在一起,那就使用移动功能把它移过去。

Strategy模式和Visitor模式是为了对抗发散式变化,但也能解决单一职责问题,最根本的原则是:将总是一起变化的东西放在一块儿。 数据和引用这些数据的行为总是一起变化的,如果有特殊情况,我们就搬移那些行为,保持变化始终只在一地发生。

上一篇 2023年02月24 20:48
下一篇 2023年03月25 17:52

相关推荐

  • 天猫客服电话是多少,天猫客服电话

    淘宝消费者服务热线:天猫服务热线:4008-608-6081、天猫服务热线:4008608608,周一~周日9:00-24:00提供天猫招商、交易、商品、活动等问题的咨询。2、天猫电器城导购热线:40

    2023年03月09 257
  • wps是谁开发的,wps是雷军开发的吗

    wps是雷军开发的吗,大部分人的印象都是——wps好像是山寨的office软件,但其实第一款wps是求伯君于1988年5月开始研发的。wps1.01988年5月,求伯君在深圳一处酒店闭关敲代码,一年后

    2023年05月03 250
  • 三星s7为什么不用贴膜,三星s7edge用不用贴膜

    本内容来源于@什么值得买SMZDM.COM|作者:玩机玩镜的GG创作立场其实这篇文章本该一周前就该发出,GG本来预定了JD20号的S20首发,然而很不幸的正好看到了大妈上的拼爹爹S20百亿补贴爆料,又

    2023年04月12 259
  • 微信地址怎么改,微信地址怎么改到国外

    我们使用社交软件时,不想别人知道我们真实的位置信息时是可以修改的。那么2人共享实时位置怎么修改呢?首先打开微信app,点搜索或者放大镜,查找“随心位移”,按照下面的步骤操作即可。下面就让小编来告诉大家

    2023年05月09 276
  • 硒鼓怎么安装,惠普1110安装图解

    硒鼓是打印机里重要的部件,直接影响打印文件的质量。对于安装,先要抽出硒鼓的密封条再以硒鼓的轴心为轴转动,使墨粉在硒鼓中分布均匀,这样可以使打印质量提高。按照打印机上面标示的图解教程一步步的安装到位即可

    2023年02月14 277
  • 引力波是谁发现的,中国第一个发现引力波的人

    2016年2月11日,美国的激光干涉仪引力波天文台(LIGO)公布了本世纪以来人类最重要的科学发现之一:引力波。这个被命名为GW150914的信号,于2015年9月14日由两台LIGO探测器所纪录,起

    2023年05月03 298
  • 光纤多少钱1米,单模光纤多少钱一米

    HDMI是高清时代的主流技术标准,最新的HDMI2.1标准,更是可以达到8K/10K的超高清分辨率。在过去乃至现在,HDMI高清线往往以以铜芯线为主,然而铜芯HDMI线路在长距离传送时受到限制和铜芯自

    2023年03月23 225
  • 办宽带要多少钱,初次安装宽带要多少钱

    近日上海市公安局崇明分局三星派出所您好,最低的360元每年,每个月只需30元,电信宽带套餐有很多,不同套餐对应的资费也是不同的,你可以登录本省电信网上营业厅查询套餐和资费详情的,然后选择合适自己的宽带

    2023年03月18 268
  • 移动多少钱一分钟,移动滞纳金收一辈子吗

    2019年6月12日,农安县的王先生给二三里资讯发来信息:我使用的是8分钱一分钟的移动卡,从今年5月初开始,移动卡却变成了2角钱一分钟,这不是胡乱收费吗?王先生说,他是5月1日发现的这个事儿,观察几天

    2023年02月25 224
  • 苹果的创始人是谁,什么档次的人用苹果

    史蒂夫·乔布斯是美国苹果公司的创始人。在他很小的时候就被父母遗弃了,但是有对好心的夫妻领养了他。乔布斯被他的邻居(惠普公司员工)所影响,第一次见到电脑,他就开始对计算机有了朦胧的认识。1976年,乔布

    2023年05月02 232
  • 抖音是怎么赚钱

    什么样的人算普通人呢?没有团队,不懂技术,没有资源,不了解行业,信息落后。这样的人,我理解应该算是一个普通人吧。其实,在我眼里,这样的普通人,仍然有很多机会赚到钱。只要你有执行力。不信?试试我分享的这

    2023年02月13 222
  • 一淘怎么用,为什么大家不用一淘

    现在大家在网上购物的越来越多,淘宝天猫也成了大家剁手的主战场。眼看中秋、国庆双节来临,为什么大家不用一淘,用不了多久双11又㕛叒叕来了。大家都有什么购物的神器来买到实惠满意的产品呢?,以前几天我买小米

    2023年02月14 217
  • 京东公司怎么样,京东是什么样的一个公司

    作为国内互联网三大巨头之一的京东,最近出了三件大事:第一件,京东是什么样的一个公司,4月7日,京东集团正式发布公告称,京东集团总裁徐雷将正式接替刘强东,担任京东集团CEO一职。此后刘强东将继续担任公司

    2023年02月13 231
关注微信