成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

代碼整潔之道

stefan / 1407人閱讀

摘要:代碼寫得是否整潔是客觀的,是的人或后期維護(hù)的人覺得好才是真的好。三代碼設(shè)計(jì)原則要想寫出優(yōu)雅整潔的代碼,就要遵循特定的設(shè)計(jì)原則。

歡迎關(guān)注我的公眾號(hào)睿Talk,獲取我最新的文章:

一、前言

最近在做一些項(xiàng)目重構(gòu)的工作,看了不少臟亂差的代碼,身心疲憊。本文將討論如何編寫整潔的代碼,不求高效運(yùn)行,只求可讀性強(qiáng),便于維護(hù)。

二、為什么要寫簡(jiǎn)潔的代碼

作為一個(gè)合格的程序員,寫出簡(jiǎn)潔的代碼是基本的職業(yè)素養(yǎng)。相信絕大部分的程序員都不會(huì)故意寫惡心代碼的,無論是對(duì)自己或者對(duì)別人都沒有任何好處。那么,是什么阻礙我們寫出優(yōu)秀代碼呢?有下面這么幾種可能性:

時(shí)間緊任務(wù)重,沒那么多時(shí)間考慮代碼設(shè)計(jì)

偷懶圖方便,不過腦子機(jī)械式的寫代碼

注意力只集中在功能的實(shí)現(xiàn),不考慮后期的維護(hù)成本

知識(shí)儲(chǔ)備不夠,不知道怎樣寫出優(yōu)雅的代碼

出來混遲早要還的,無論是上述哪種原因,混亂代碼一旦被寫出來,代碼作者肯定是要為其買單的,只是買單的方式會(huì)各有不同。可能是后期維護(hù)的時(shí)候邊改邊抽自己,也可能是別人改代碼的時(shí)候邊改邊罵你傻x。

那么,代碼寫好了會(huì)有什么好處呢?起碼有以下幾方面:

后期維護(hù)更高效,無論是改 bug 還是新增功能,無論是自己改還是別人改

后期更少的加班

思考如何編寫整潔代碼的過程中,技術(shù)能力會(huì)隨之提高

寫出優(yōu)雅的代碼,會(huì)更有成就感,更熱愛自己的工作

別人看到這么優(yōu)雅的代碼,會(huì)贊不絕口,個(gè)人影響力會(huì)放大

既然有這么多好處,那到底怎么評(píng)判代碼寫得好不好呢?是自己覺得好就是好嗎?顯然不是。代碼寫得是否整潔是客觀的,是 code review 的人或后期維護(hù)的人覺得好才是真的好。所以加強(qiáng) code review 也是倒逼寫出優(yōu)秀代碼的一種方式。

個(gè)人認(rèn)為代碼的優(yōu)秀程度分以下幾個(gè)層次:

程序能正常運(yùn)行

異常情況有應(yīng)對(duì)方法

簡(jiǎn)單明了,易于后期維護(hù)

團(tuán)隊(duì)成員間能高效協(xié)作

能高性能運(yùn)行

層次越高,難度越大,挑戰(zhàn)越大。作為一個(gè)有追求的程序員,我們應(yīng)該不斷突破自己的邊界,追求卓越,更上一層樓。

三、代碼設(shè)計(jì)原則

要想寫出優(yōu)雅整潔的代碼,就要遵循特定的設(shè)計(jì)原則。透徹理解這些原則后,還要結(jié)合具體的項(xiàng)目落地,不斷的練習(xí)和重構(gòu)。下面總結(jié)出的一些通用原則供參考。

KISS(keep it simple, stupid)

業(yè)務(wù)邏輯要直截了當(dāng),不要引入各種依賴,多層次調(diào)用。以 React 為例,常見的錯(cuò)誤是將propsstate里存一份,計(jì)算的時(shí)候再從state中取。這樣帶來的問題是要時(shí)刻監(jiān)聽props的變化,然后再同步到state中。這完全是多此一舉,直接用props進(jìn)行計(jì)算即可。

// bad
componentWillReceiveProps(nextProps) {
    this.setState({num: nextProps.num});
}

render() {
    return(
        
{this.state.num * 2}
); } /***************************/ // good render() { return(
{this.props.num * 2}
); }

DRY (don’t repeat yourself)

不用做機(jī)械式的復(fù)制粘貼,要鍛煉自己抽象的能力,盡量將通用的邏輯抽象出來,方便日后重用。

Open/Closed (open to extension but closed to modification)

代碼要對(duì)擴(kuò)展開放,對(duì)修改封閉。盡量做到在不修改原有代碼的基礎(chǔ)上,增加新的功能。React 的容器組件和展示組件分離用的就是這種思想。當(dāng)數(shù)據(jù)來源不同的時(shí)候,只需要修改或新增容器組件,展示組件維持不變。

function Comp() {
    ...
}

class ContainerComp extends PureComponent {

    async componentDidMount() {
        const data = await fetchData();
        this.setState({data});
    }
    
    render() {
        return ();
    }
}

從架構(gòu)層面說,微內(nèi)核架構(gòu)也是遵循這一設(shè)計(jì)原則。它能保證核心模塊不變的情況下,通過插件機(jī)制為系統(tǒng)賦予新的能力。我們常用的 Webpack 就是一個(gè)很好的例子,它通過引入 loader 和 plugin 的機(jī)制,極大的擴(kuò)展了其文件處理的能力。

Composition > Inheritance

首先說一下類這個(gè)概念。本質(zhì)上來說,定義類就是為了代碼的復(fù)用,對(duì)于需要同時(shí)創(chuàng)建多個(gè)對(duì)象實(shí)例的情況下,這種設(shè)計(jì)模式是非常有效的。比如說連接池中就需要同時(shí)存在多個(gè)連接對(duì)象,方便資源復(fù)用。而對(duì)于前端來說,絕大部分的業(yè)務(wù)場(chǎng)景都是單例,這種情況下通過定義工具函數(shù),或者直接使用對(duì)象字面量會(huì)更加高效。工具函數(shù)盡量使用純函數(shù),使代碼更易于理解,不用考慮副作用。這里說的僅限于業(yè)務(wù)代碼的范疇,如果是框架型的項(xiàng)目,場(chǎng)景會(huì)復(fù)雜得多,類會(huì)更有用武之地。

既然類都不需要用了,繼承就更無從談起了。繼承的問題是多級(jí)繼承之后,定位問題會(huì)非常困難,要一級(jí)一級(jí)往上找才能找到錯(cuò)誤出處。而組合就沒有這種問題,因?yàn)槎鄠€(gè)功能都是平級(jí)的,哪里出問題一眼就能看出來。比較一下下面 2 種風(fēng)格的代碼:

繼承的寫法:

class Parent extends PureComponent {
    componentDidMount() {
        this.fetchData(this.url);
    }
    
    fetchData(url) {
        ...
    }
    
    render() {
        const data = this.calcData();
        return (
            
{data} ); } } class Child extends Parent { constructor(props) { super(props); this.url = "http://api"; } calcData() { ... } }

組合的寫法:

class Parent extends PureComponent {
    componentDidMount() {
        this.fetchData(this.props.url);
    }
    
    fetchData(url) {
        ...
    }
    
    render() {
        const data = this.props.calcData(this.state);
        return (
            
{data} ); } } class Child extends PureComponent { calcData(state) { ... } render() { } }

哪種更易于理解呢?

Single Responsibility

遵循單一職責(zé)的代碼如果設(shè)計(jì)得好,組合起來的代碼就會(huì)非常的清爽。舉一個(gè)注冊(cè)的場(chǎng)景,可以劃分為下面幾個(gè)職責(zé):

UI 展示

輸入合法性判斷

網(wǎng)絡(luò)請(qǐng)求

聚合層

偽代碼如下:

// UI.js
export default function UI() {
    ...
}

// api.js
export function regist(name, email) {
    ...
}

// validate.js
export function validateName(name) {
    ...
}
export function validateEmail(email) {
    ...
}

// Regist.js
export default class Regist extends PureComponent {
    ...
    
    onSubmit = async () => {
        const {name, email} = this.state;
        
        if (validateName(name) && validateEmail(email)) {
            const resp = await regist(name, email);
            ...
        }        
    }

    render() {
        
    }
}

可以看到聚合層的代碼非常簡(jiǎn)潔,哪里出問題了就到相應(yīng)的地方改就好了,即使是多人協(xié)作,也不容易出問題。

Separation of Concerns

關(guān)注點(diǎn)分離原則跟單一職責(zé)原則有點(diǎn)類似,但更強(qiáng)調(diào)的是系統(tǒng)架構(gòu)層面的設(shè)計(jì)。典型的例子就是 MVC 模式,Model、View、Control 三層之間都有明確的職責(zé)劃分,做到了高內(nèi)聚低耦合。

React 的源碼設(shè)計(jì)也是基于這一原則,分為ReactElement, ReactCompositeComponentReactDomComponent 三層。ReactElement 負(fù)責(zé)描述頁面的 DOM 結(jié)構(gòu),也就是著名的 Virtual DOM;ReactCompositeComponent 處理的是組件生命周期、組件 Diff 和更新等邏輯;而ReactDomComponent是真正進(jìn)行 DOM 操作的類。三層之間分工明確,緊密協(xié)作,共同組成了一個(gè)強(qiáng)大的前端框架。

Clean Code > Clever Code

提倡簡(jiǎn)潔易懂的代碼,而不是晦澀難懂的“聰明”代碼,如下面這種:

let a, b=3, t = (a=2, b<1) ? (console.log("Y"),"yes") : (console.log("N"),"no");

單一代碼文件不超過 200 行

文件一旦超過 200 行,說明邏輯已經(jīng)有點(diǎn)復(fù)雜了,要想辦法抽離出一些純函數(shù)工具方法,讓主線邏輯更加清晰。工具方法可以放在另外的文件里面,減少讀代碼的心理壓力。有一點(diǎn)需要說明一下,并不是所有的文件都不能超過 200 行,像工具方法這種,都是各自獨(dú)立的邏輯,寫多少行都無所謂。需要控制的是緊密關(guān)聯(lián)的業(yè)務(wù)代碼的行數(shù)。

四、前端代碼如何拆分

上面提到要合理的拆分代碼,那到底怎么拆呢?對(duì)于前端組件代碼,有下面一些拆分點(diǎn)以供參考:

UI

展現(xiàn)邏輯

事件處理

業(yè)務(wù)邏輯

網(wǎng)絡(luò)請(qǐng)求

配置類純JSON對(duì)象

工具類純函數(shù)

需要說明的是展現(xiàn)邏輯和業(yè)務(wù)邏輯是兩回事,最好不要混在一起寫。比如組件的顯示隱藏是展現(xiàn)邏輯,而數(shù)據(jù)的校驗(yàn)就是業(yè)務(wù)邏輯。

五、總結(jié)

本文討論了書寫整潔代碼的必要性和重要性,結(jié)合實(shí)例列出了一些設(shè)計(jì)原則,還給出了組件代碼拆分的方式。程序員的職業(yè)生涯是一個(gè)自我修煉的過程,時(shí)刻關(guān)注代碼質(zhì)量,是提高技術(shù)水平的重要一環(huán)。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/105330.html

相關(guān)文章

  • 代碼整潔之道

    摘要:在代碼整潔之道,提出一種軟件質(zhì)量,可持續(xù)開發(fā)不僅在于項(xiàng)目架構(gòu)設(shè)計(jì),還與代碼質(zhì)量密切相關(guān),代碼的整潔度和質(zhì)量成正比,一份整潔的代碼在質(zhì)量上是可靠的,為團(tuán)隊(duì)開發(fā),后期維護(hù),重構(gòu)奠定了良好的基礎(chǔ)。 現(xiàn)在的軟件系統(tǒng)開發(fā)難度主要在于其復(fù)雜度和規(guī)模,客戶需求也不再像Winston Royce瀑布模型期望那樣在系統(tǒng)編碼前完成所有的設(shè)計(jì)滿足用戶軟件需求。在這個(gè)信息爆炸技術(shù)日新月異的時(shí)代,需求總是在不停...

    icattlecoder 評(píng)論0 收藏0
  • 代碼整潔之道 - 有意義的命名

    摘要:我們這里再介紹一下,朱重八家族的名字,都很有特點(diǎn)。取這樣的名字不是因?yàn)橹旒沂歉銛?shù)學(xué)的,而是因?yàn)樵谠?,老百姓如果不能上學(xué)和當(dāng)官就沒有名字,只能以父母年齡相加或者出生的日期命名。所以說命名不僅僅是一種科學(xué),更是一種藝術(shù)。 在小朱元璋出生一個(gè)月后,父母為他取了一個(gè)名字(元時(shí)慣例):朱重八,這個(gè)名字也可以叫做朱八八。我們這里再介紹一下,朱重八家族的名字,都很有特點(diǎn)。朱重八高祖名字:朱百六;朱...

    mengbo 評(píng)論0 收藏0
  • 代碼整潔之道 - 有意義的命名

    摘要:我們這里再介紹一下,朱重八家族的名字,都很有特點(diǎn)。取這樣的名字不是因?yàn)橹旒沂歉銛?shù)學(xué)的,而是因?yàn)樵谠?,老百姓如果不能上學(xué)和當(dāng)官就沒有名字,只能以父母年齡相加或者出生的日期命名。所以說命名不僅僅是一種科學(xué),更是一種藝術(shù)。 在小朱元璋出生一個(gè)月后,父母為他取了一個(gè)名字(元時(shí)慣例):朱重八,這個(gè)名字也可以叫做朱八八。我們這里再介紹一下,朱重八家族的名字,都很有特點(diǎn)。朱重八高祖名字:朱百六;朱...

    Cobub 評(píng)論0 收藏0
  • 架構(gòu)整潔之道(二)——兩個(gè)價(jià)值的故事

    摘要:每個(gè)軟件系統(tǒng)都提供兩個(gè)價(jià)值給利益相關(guān)者表現(xiàn)和結(jié)構(gòu)。來自利益相關(guān)者的觀點(diǎn),開發(fā)者僅僅只提供了一些形態(tài)上的粗略改變,來自開發(fā)者的觀點(diǎn),老板的需求越來越難。記住,作為一個(gè)開發(fā)者,你就是利益相關(guān)者,你需要維護(hù)的軟件里有你的利益。 每個(gè)軟件系統(tǒng)都提供兩個(gè)價(jià)值給利益相關(guān)者:表現(xiàn)和結(jié)構(gòu)。軟件開發(fā)者應(yīng)的確保這兩個(gè)價(jià)值盡量高負(fù)責(zé)。然而很不幸,程序員很多只關(guān)心其中一個(gè)而忽略另一個(gè),甚至更不幸,他們可能關(guān)注...

    denson 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<