热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

代码质量管理——怎样写出文雅地代码

作为一个刚写代码不久的小菜鸟,事情的半年多让我越发意想到进步代码质量的重要性。夙昔只会关注完成功用,逐步的最先关注机能,现阶段则发明实在另有许多细节也是(如可读性、易用性、可保护性

作为一个刚写代码不久的小菜鸟,事情的半年多让我越发意想到进步代码质量的重要性。夙昔只会关注完成功用,逐步的最先关注机能,现阶段则发明实在另有许多细节也是(如可读性、易用性、可保护性、一致性)进步代码质量的症结。“完成功用”跟“文雅地完成功用”是两回事。

注:大部份内容归结自收集,将多篇文章的看法汇总加工了一下,也融会了一些个人的看法。

准绳

  • 单一职责准绳
  • 易用性准绳
  • 可读性准绳
  • 庞杂性守恒准绳:不管你怎样写代码,庞杂性都是不会消逝的

    注:假如逻辑很庞杂,那末代码看起来就应该是庞杂的。假如逻辑很简朴,代码看起来就应该是简朴的。

单一职责准绳

面向对象五大设想形式基本准绳之一。即一部份代码只应该用于某一个特定功用,不应与其他功用耦合在一同

假定你的一个function同时完成了功用a和功用b,以后需求变动,你须要修正功用a,然则由于这两个功用都在一个function里,你就不能不再去确认是不是会影响到功用b。这就造成了不必要的本钱。

以下我总结了三个拆分代码的准绳:

“and”准绳

当你为你的要领定名时不能不加上“and”时,就该斟酌斟酌是不是是要把这个要领拆分一下了。

“100”准绳

当你的一个function凌驾一百行时,肯定要举行拆分了。

注:这里的100可以有点多,只是对我个人而言,100算是我的极限,总之就是相对不要将一个函数写的太长。

敕令、查询拆分准绳

我们开辟中大部份操纵可以总结为“敕令”和“查询”,如写COOKIE、修正data、发送post要求都可以叫“敕令”,而读取COOKIE、ajax猎取数据则以为是“查询”操纵。

函数式编程中考究“数据不可变”,即:

只需纯的没有副作用的函数,才是及格的函数。

副作用:指当挪用函数时,除了返回函数值之外,还对主挪用函数发生附加的影响。比方修正全局变量(函数外的变量)或修正参数。

优点是使得开辟越发简朴,可回溯,测试友爱,削减了任何可以的副作用。

将“敕令”与“查询”拆分实际上就是函数式编程头脑的部份表现,参考以下代码:

function getFirstName() {
var firstName = document.querySelector("#firstName").value;
firstName = firstName.toLowerCase();
setCOOKIE("firstName", firstName);
if (firstName === null) {
return "";
}
return firstName;
}
var activeFirstName = getFirstName();

经由过程名字来看,该要领是用于猎取first name的,但实际上它还设置了COOKIE,这是我们没有预感的。关于一个“查询”要领,它不应该有任何修正要领外变量的行动,即“副作用”。更好的写法以下:

function getFirstName() {
var firstName = document.querySelector("#firstName").value
if (firstName === null) {
return "";
}
return firstName;
}
setCOOKIE("firstName", getFirstName().toLowerCase());

一览无余,getFirstName只返回firstName,而设置COOKIE操纵在它之外举行。

易用性准绳

简朴

这里的简朴,重要归结为function的一些设想准绳,有以下几点:挪用简朴、易明白、削减影象本钱、参数处置惩罚。

以下,仅仅想完成修正dom色彩、宽度等属性,原生代码以下:

document.querySelector('#id').style.color = 'red'
document.querySelector('#id').style.width = '123px'
document.querySelector('#id').style.height = '456px'

而封装事后:

function a(selector, color, width, height) {
document.querySelector(selector).style.color = color
document.querySelector(selector).style.width = width
document.querySelector(selector).style.height = height
}
a('#a', 'red')

霎时变得简朴可用了 ~

但该要领还存在一个题目,那就是定名太笼统了。。。除了开辟者本身之外不可以有人在不看源码的状况下一眼看出这个要领a是干吗的。那末咱再把这个要领名改写得更易明白一点:

function letSomeElementChange(selector, color, width, height) {
document.querySelector(selector).style.color = color
document.querySelector(selector).style.width = width
document.querySelector(selector).style.height = height
}

如许我们就可以一览无余该要领的作用 ~ 不过仍有可优化的处所。这么长的要领名谁记得住,要削减影象本钱啊,再改个名:

function setElement(selector, color, width, height) {
document.querySelector(selector).style.color = color
document.querySelector(selector).style.width = width
document.querySelector(selector).style.height = height
}

OK,现在这个要领已满足它的职责而且很好用了,但还以为怪怪的。这一坨参数太碍眼。。。

function setElement(selector, opt) {
const { color, width, height } = opt
color && document.querySelector(selector).style.color = color
width && document.querySelector(selector).style.width = width
height && document.querySelector(selector).style.height = height
}

把多个参数兼并一下,并在内部做兼容处置惩罚,这个要领便易用多了。纵然不传第二个参数也不会有任何副作用。

一致性

假如有如许一个要领,猎取歌曲列表,并将其设置到div的innerText中:

function getSongs() {
return $.get('/songs).then((response) {
div.innerText = response.songs
})
}

这就违犯了要领的内外一致性,也违犯了上文的单一职责准绳敕令、查询拆分准绳,由于它不仅猎取了歌单,同时还修正了innerText,要让其更合理:

  • 要么换个名字
  • 要么拆分为两个要领

低耦合

耦合是权衡一个递次单位对其他递次单位的依靠水平。耦合(或高耦合)是应该尽力防止的。假如你发明本身正在复制和粘贴代码并举行小的变动,或许重写代码,由于其他处所发生了变动,这就是高耦合的表现。

耦合会严峻影响代码的复用性及可扩展性,让后人保护时不能不修正以至重写这部份代码,不仅浪费时刻还会致使仓储中又多出一块类似的代码,很轻易让人疑惑。

同时,修正耦合度高的代码时常常会牵一发而动全身,假如修正时没有理清这些耦合关联,那末带来的效果可以会是灾难性的,特别是关于需求变化较多以及多人合作开辟保护的项目,修正一个处所会引起原本已运转稳固的模块毛病,严峻时会致使恶性循环,题目永久改不完,开辟和测试都在种种题目之间奔走劳顿,末了致使项目延期,用户满意度下降,本钱也增加了,这对用户和开辟商影响都是很卑劣的,种种风险也就显而易见了。

高内聚

不应该将没有任何联络的东西堆到一同。

内聚是一个类中变量与要领衔接强度的范例。高内聚是值得要的,由于它意味着类可以更好地实行一项事情。低内聚是不好的,由于它表明类中的元素之间很少相干。每一个要领也应该高内聚,大多数的要领只实行一个功用,不要在要领中增加‘分外’的指令,如许会致使要领实行更多的函数,同时也违反了上文的单一职责准绳

低内聚的表现:假如属性没有被类中的多个要领运用,这多是低内聚的标志。一样,假如要领在几种差别的状况下不能被重用,或许假如一个要领基础不被运用,这也多是低内聚的一个标志。

高内聚有助于减缓高耦合,高耦合是须要高内聚的标志。然则,假如两个题目同时存在,应该挑选内聚的体式格局。关于开辟者来讲,高内聚平常比低耦合更有协助,只管二者平常可以一同完成。

毛病处置惩罚

  • 可预感的毛病:诸如ajax回调、函数参数,这类题目很好处理,只需在开辟时多斟酌一步,对种种极度状况做好兼容即可。
  • 不可预感的毛病:类似兼容性题目,这类题目没法在开辟时准确预感的毛病,可以准备好抛错,console.error/log/warn,末了你还可以为本身的递次留些后路: try…catch。

可读性准绳

定名

定名应该保证他人经由过程称号一眼就可以晓得这个变量保留的是什么,或许这个要领是用来做什么的。

  • 平常变量、属性用名词以下:

    var person = {
    name: 'Frank'
    }
    var student = {
    grade: 3,
    class: 2
    }

  • bool变量、属性用(形容词)或许(be动词)或许(神态动词)或许(hasX),以下:

    var person = {
    dead: false, // 假如是形容词,前面就没必要加 is,比方isDead 就很空话
    canSpeak: true, //神态动词有 can、should、will、need 等,神态动词背面接动词
    isVip: true, // be 动词有 is、was 等,背面平常接名词
    hasChildren: true, // has 加名词
    }

  • 平常函数、要领用(动词)开首:

    var person = {
    run(){}, // 不及物动词
    drinkWater(){}, // 及物动词
    eat(foo){}, // 及物动词加参数(参数是名词)
    }

  • 回调、钩子函数:

    var person = {
    beforeDie(){},
    afterDie(){},
    // 或许
    willDie(){}
    dead(){} // 这里跟 bool 争执,你只需差别时暴露 bool dead 和函数 dead 就行,怕争执就用上面的 afterDie
    }
    button.addEventListener('click', onButtonClick)
    var compOnent= {
    beforeCreate(){},
    created(){},
    beforeMount(){}
    }

  • 定名一致性

    • 递次一致性:比方 updateContainerWidth 和 updateHeightOfContainer 的递次就使人很别扭
    • 时刻一致性:有可以跟着代码的变迁,一个变量的寄义已差别于它一最先的寄义了,这个时刻你须要实时改掉这个变量的名字。

这一条是最难做到的,由于写代码轻易,改代码难。假如这个代码构造得不好,极可以会涌现牵一发而动全身的状况(如全局变量就很难改)

解释

不须要多花梢,只需把作用、用法形貌清晰即可。要领的范例解释应该以下:

/**
* [function_name description]
* @param {[type]} argument [description]
* @return {[type]} [description]
*/
function function_name(argument) {
// body...
}

将要领的参数与返回值都写清晰,我现在用的IDE是sublime,运用Docblockr插件可以自动天生格式化解释,很轻易。

Bad Smell

项目中我们常常可以遇这类代码,它们仍可用,然则很“臭”,外洋管这类代码有一个统称,即“bad smell”。以下这类代码可以说是很“臭”了:

  • 内外不一的代码
  • 过期的解释
  • 逻辑很简朴,然则看起来很庞杂的代码
  • 反复的代码
  • 类似的代码
  • 老是一同涌现的代码
  • 未运用的依靠
  • 差别作风的代码

款式范例

  1. 准确定名:class必须用“-”写法,不要用驼峰和下划线。
  2. 准确嵌套:一般状况下肯定要将class嵌套闭合,不然就相当于增加到全局,假如有反复定名的class就会受影响。
  3. 谢绝copy:假如想复用已有的款式,直接在原有class上用“,”语法支解,就可以运用,不要再copy一份款式,会让两份款式都被运用,就要斟酌款式掩盖的题目,很不友爱。
  4. 滥用class:没有必要加的class不要加,每一个class的增加都应该有明白来由。滥用class的话可以会致使款式掩盖,不应运用这个款式的处所用了这个款式。
  5. 慎用 !important,会强行掩盖一切同属性款式,一旦运用后会让代码难以保护,开辟过程当中相对不要依靠该要领。以下总结了一些运用 !important的履历:

    • 肯定要优化斟酌运用款式划定规矩的优先级来处理题目而不是 !important
    • 只需在须要掩盖全站或外部 css(比方援用的 ExtJs 或许 YUI )的特定页面中运用 !important
    • 处理紧要线上题目可以运用,但以后也要尽快用可保护的体式格局将代码替代返来
    • 永久不要在全站局限的 css 上运用 !important
    • 永久不要在你的插件中运用 !important

说得轻易,做起来难

破窗效应

此理论以为环境中的不良征象假如被听任存在,会诱使人们仿效,以至变本加厉。一幢有少量破窗的修建为例,假如那些窗不被修理好,可以将会有损坏者损坏更多的窗户。终究他们以至会突入修建内,假如发明无人居住,或许就在那边定居或许放火。一面墙,假如涌现一些涂鸦没有被清洗掉,很快的,墙上就布满了杂乱无章、不堪入目的东西;一条人行道有些许纸屑,不久后就会有更多渣滓,终究人们会视若天经地义地将渣滓随手抛弃在地上。这个征象,就是犯罪心理学中的
破窗效应,在编程范畴一样存在。

要做到:只需是经由你手的代码,都会比之前好一点。

参考文章:

  • Javascript的api设想准绳
  • Coding with Clarity
  • Don’t leave broken windows
  • 从JS对象最先,谈一谈“不可变数据”和函数式编程
  • 重构 – 代码优化技能
  • 怎样和什么时候运用CSS的!important
  • css优先级

推荐阅读
  • 深入解析Android 4.4中的Fence机制及其应用
    在Android 4.4中,Fence机制是处理缓冲区交换和同步问题的关键技术。该机制广泛应用于生产者-消费者模式中,确保了不同组件之间高效、安全的数据传输。通过深入解析Fence机制的工作原理和应用场景,本文探讨了其在系统性能优化和资源管理中的重要作用。 ... [详细]
  • Web开发框架概览:Java与JavaScript技术及框架综述
    Web开发涉及服务器端和客户端的协同工作。在服务器端,Java是一种优秀的编程语言,适用于构建各种功能模块,如通过Servlet实现特定服务。客户端则主要依赖HTML进行内容展示,同时借助JavaScript增强交互性和动态效果。此外,现代Web开发还广泛使用各种框架和库,如Spring Boot、React和Vue.js,以提高开发效率和应用性能。 ... [详细]
  • 技术日志:使用 Ruby 爬虫抓取拉勾网职位数据并生成词云分析报告
    技术日志:使用 Ruby 爬虫抓取拉勾网职位数据并生成词云分析报告 ... [详细]
  • 【问题】在Android开发中,当为EditText添加TextWatcher并实现onTextChanged方法时,会遇到一个问题:即使只对EditText进行一次修改(例如使用删除键删除一个字符),该方法也会被频繁触发。这不仅影响性能,还可能导致逻辑错误。本文将探讨这一问题的原因,并提供有效的解决方案,包括使用Handler或计时器来限制方法的调用频率,以及通过自定义TextWatcher来优化事件处理,从而提高应用的稳定性和用户体验。 ... [详细]
  • 为了确保iOS应用能够安全地访问网站数据,本文介绍了如何在Nginx服务器上轻松配置CertBot以实现SSL证书的自动化管理。通过这一过程,可以确保应用始终使用HTTPS协议,从而提升数据传输的安全性和可靠性。文章详细阐述了配置步骤和常见问题的解决方法,帮助读者快速上手并成功部署SSL证书。 ... [详细]
  • 在《ChartData类详解》一文中,我们将深入探讨 MPAndroidChart 中的 ChartData 类。本文将详细介绍如何设置图表颜色(Setting Colors)以及如何格式化数据值(Formatting Data Values),通过 ValueFormatter 的使用来提升图表的可读性和美观度。此外,我们还将介绍一些高级配置选项,帮助开发者更好地定制和优化图表展示效果。 ... [详细]
  • 本文深入解析了WCF Binding模型中的绑定元素,详细介绍了信道、信道管理器、信道监听器和信道工厂的概念与作用。从对象创建的角度来看,信道管理器负责信道的生成。具体而言,客户端的信道通过信道工厂进行实例化,而服务端则通过信道监听器来接收请求。文章还探讨了这些组件之间的交互机制及其在WCF通信中的重要性。 ... [详细]
  • 使用 ListView 浏览安卓系统中的回收站文件 ... [详细]
  • 本文详细介绍了如何利用CSS技术对链接下划线进行个性化定制和美化,涵盖了多种实用技巧和方法。通过对CSS属性的灵活运用,可以实现不同风格的下划线效果,提升网页的视觉体验。文中不仅提供了基础的代码示例,还结合实际案例进行了深入解析,帮助读者更好地理解和应用这些技巧。此外,文章还引用了《CSS2.0中文手册》中的相关内容,增加了技术的权威性和实用性。 ... [详细]
  • 本文深入解析了 jQuery 中用于扩展功能的三个关键方法:`$.extend()`、`$.fn` 和 `$.fn.extend()`。其中,`$.extend()` 用于扩展 jQuery 对象本身,而 `$.fn.extend()` 则用于扩展 jQuery 的原型对象,使自定义方法能够作为 jQuery 实例的方法使用。通过这些方法,开发者可以轻松地创建和集成自定义插件,增强 jQuery 的功能。文章详细介绍了每个方法的用法、参数及实际应用场景,帮助读者更好地理解和运用这些强大的工具。 ... [详细]
  • 利用爬虫技术抓取数据,结合Fiddler与Postman在Chrome中的应用优化提交流程
    本文探讨了如何利用爬虫技术抓取目标网站的数据,并结合Fiddler和Postman工具在Chrome浏览器中的应用,优化数据提交流程。通过详细的抓包分析和模拟提交,有效提升了数据抓取的效率和准确性。此外,文章还介绍了如何使用这些工具进行调试和优化,为开发者提供了实用的操作指南。 ... [详细]
  • 本指南介绍了 `requests` 库的基本使用方法,详细解释了其七个主要函数。其中,`requests.request()` 是构建请求的基础方法,支持其他高级功能的实现。此外,我们还重点介绍了如何使用 `requests.get()` 方法来获取 HTML 网页内容,这是进行网页数据抓取和解析的重要步骤。通过这些基础方法,读者可以轻松上手并掌握网页数据抓取的核心技巧。 ... [详细]
  • 深入解析 Android 中 EditText 的 getLayoutParams 方法及其代码应用实例 ... [详细]
  • 本文全面解析了JavaScript中的DOM操作,并提供了详细的实践指南。DOM节点(Node)通常代表一个标签、文本或HTML属性,每个节点都具有一个nodeType属性,用于标识其类型。文章深入探讨了DOM节点的创建、查询、修改和删除等操作,结合实际案例,帮助读者更好地理解和掌握DOM编程技术。 ... [详细]
  • 在Java分层设计模式中,典型的三层架构(3-tier application)将业务应用细分为表现层(UI)、业务逻辑层(BLL)和数据访问层(DAL)。这种分层结构不仅有助于提高代码的可维护性和可扩展性,还能有效分离关注点,使各层职责更加明确。通过合理的设计和实现,三层架构能够显著提升系统的整体性能和稳定性。 ... [详细]
author-avatar
蘑菇-2166_315
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有