摘要:?jiǎn)卧獪y(cè)試不僅涉及早期錯(cuò)誤檢測(cè)。當(dāng)組件的架構(gòu)設(shè)計(jì)很脆弱時(shí),就會(huì)變得難以測(cè)試,而當(dāng)組件難以測(cè)試的時(shí)候,你大概念會(huì)跳過(guò)編寫單元測(cè)試的過(guò)程,最終的結(jié)果就是組件未測(cè)試??蓽y(cè)試性是確定組件結(jié)構(gòu)良好程度的實(shí)用標(biāo)準(zhǔn)??蓮?fù)用的組件是精心設(shè)計(jì)的系統(tǒng)的結(jié)果。
翻譯:劉小夕原文鏈接:https://dmitripavlutin.com/7-...
本篇文章重點(diǎn)闡述可測(cè)試和富有意義。因水平有限,文中部分翻譯可能不夠準(zhǔn)確,如果你有更好的想法,歡迎在評(píng)論區(qū)指出。
盡管 組合、復(fù)用 和 純組件 三個(gè)準(zhǔn)則閱讀量不高,不過(guò)本著有始有終的原則,當(dāng)然我個(gè)人始終還是覺(jué)得此篇文章非常優(yōu)質(zhì),還是堅(jiān)持翻譯完了。本篇是最后 可靠React組件設(shè)計(jì) 的最后一篇,希望對(duì)你的組件設(shè)計(jì)有所幫助。
更多文章可戳: https://github.com/YvetteLau/...
———————————————我是一條分割線————————————————
如果你還沒(méi)有閱讀過(guò)前幾個(gè)原則:
可靠React組件設(shè)計(jì)的7個(gè)準(zhǔn)則之SRP
可靠React組件設(shè)計(jì)的7個(gè)準(zhǔn)則之封裝
可靠React組件設(shè)計(jì)的7個(gè)準(zhǔn)則之組合和復(fù)用
可靠React組件設(shè)計(jì)的7個(gè)準(zhǔn)則之純組件
可測(cè)試和經(jīng)過(guò)測(cè)試經(jīng)過(guò)測(cè)試的組件驗(yàn)證了其在給定輸入的情況下,輸出是否符合預(yù)期。可測(cè)試組件易于測(cè)試。
如何確保組件按預(yù)期工作?你可以不以為然地說(shuō):“我通過(guò)手動(dòng)驗(yàn)證其正確性”。
如果你計(jì)劃手動(dòng)驗(yàn)證每個(gè)組件的修改,那么遲早,你會(huì)跳過(guò)這個(gè)繁瑣的環(huán)節(jié),進(jìn)而導(dǎo)致你的組件遲早會(huì)出現(xiàn)缺陷。
這就是為什么自動(dòng)化組件驗(yàn)證很重要:進(jìn)行單元測(cè)試。單元測(cè)試確保每次進(jìn)行修改時(shí),組件都能正常工作。
單元測(cè)試不僅涉及早期錯(cuò)誤檢測(cè)。 另一個(gè)重要方面是能夠驗(yàn)證組件架構(gòu)是否合理。
我發(fā)現(xiàn)以下幾點(diǎn)特別重要:
一個(gè)不可測(cè)試或難以測(cè)試的組件很可能設(shè)計(jì)得很糟糕。
組件很難測(cè)試往往是因?yàn)樗泻芏?props、依賴項(xiàng)、需要原型和訪問(wèn)全局變量,而這些都是設(shè)計(jì)糟糕的標(biāo)志。
當(dāng)組件的架構(gòu)設(shè)計(jì)很脆弱時(shí),就會(huì)變得難以測(cè)試,而當(dāng)組件難以測(cè)試的時(shí)候,你大概念會(huì)跳過(guò)編寫單元測(cè)試的過(guò)程,最終的結(jié)果就是:組件未測(cè)試。
總之,需要應(yīng)用程序未經(jīng)測(cè)試的原因都是因?yàn)樵O(shè)計(jì)不當(dāng),即使你想測(cè)試這樣的應(yīng)用,你也做不到。
案例學(xué)習(xí):可測(cè)試意味著良好的設(shè)計(jì)我們來(lái)測(cè)試一下 封裝章節(jié)的兩個(gè)版本的
import assert from "assert"; import { shallow } from "enzyme"; class Controls extends Component { render() { return (); } updateNumber(toAdd) { this.props.parent.setState(prevState => ({ number: prevState.number + toAdd })); } } class Temp extends Component { constructor(props) { super(props); this.state = { number: 0 }; } render() { return null; } } describe("", function () { it("should update parent state", function () { const parent = shallow( ); const wrapper = shallow( ); assert(parent.state("number") === 0); wrapper.find("button").at(0).simulate("click"); assert(parent.state("number") === 1); wrapper.find("button").at(1).simulate("click"); assert(parent.state("number") === 0); }); });
我們可以看到
測(cè)試時(shí),需要一個(gè)額外的組件
當(dāng)
import assert from "assert"; import { shallow } from "enzyme"; import { spy } from "sinon"; function Controls({ onIncrease, onDecrease }) { return (); } describe("", function () { it("should execute callback on buttons click", function () { const increase = sinon.spy(); const descrease = sinon.spy(); const wrapper = shallow( ); wrapper.find("button").at(0).simulate("click"); assert(increase.calledOnce); wrapper.find("button").at(1).simulate("click"); assert(descrease.calledOnce); }); });
良好封裝的組件,測(cè)試起來(lái)簡(jiǎn)單明了,相反,沒(méi)有正確封裝的組件難以測(cè)試。
可測(cè)試性是確定組件結(jié)構(gòu)良好程度的實(shí)用標(biāo)準(zhǔn)。
富有意義很容易一個(gè)有意義的組件作用是什么。
代碼的可讀性是非常重要的,你使用了多少次模糊代碼?你看到了字符串,但是不知道意思是什么。
開(kāi)發(fā)人員大部分時(shí)間都在閱讀和理解代碼,而不是實(shí)際編寫代碼。我們花75%的時(shí)間理解代碼,花20%的時(shí)間修改現(xiàn)有代碼,只有5%編寫新的代碼。
在可讀性方面花費(fèi)的額外時(shí)間可以減少未來(lái)隊(duì)友和自己的理解時(shí)間。當(dāng)應(yīng)用程序增長(zhǎng)時(shí),命名實(shí)踐變得很重要,因?yàn)槔斫夤ぷ麟S著代碼量的增加而增加。
閱讀有意義的代碼很容易。然而,想要編寫有意義的代碼,需要清晰的代碼實(shí)踐和不斷的努力來(lái)清楚地表達(dá)自己。
組件命名 帕斯卡命名法組件名是由一個(gè)或多個(gè)帕斯卡單詞(主要是名詞)串聯(lián)起來(lái)的,比如:
組件越專業(yè)化,其名稱可能包含的單詞越多。
名為
當(dāng)名稱有意義地暗示意圖時(shí),組件易于理解。為了實(shí)現(xiàn)這一點(diǎn),通常你必須使用詳細(xì)的名稱。那很好:更詳細(xì)比不太清楚要好。
假設(shè)您導(dǎo)航一些項(xiàng)目文件并識(shí)別2個(gè)組件:
為了獲取詳細(xì)信息,你不得不打開(kāi)
更專業(yè)的名稱而不是
一個(gè)詞代表一個(gè)概念。例如,呈現(xiàn)項(xiàng)目概念的集合由列表單詞表示。
每個(gè)概念對(duì)應(yīng)一個(gè)單詞,然后在整個(gè)應(yīng)用程序中保持關(guān)系一致。結(jié)果是可預(yù)測(cè)的單詞概念映射關(guān)系。
當(dāng)許多單詞表示相同的概念時(shí),可讀性會(huì)受到影響。例如,你定義一個(gè)呈現(xiàn)訂單列表組件為:
渲染項(xiàng)集合的相同概念由2個(gè)不同的單詞表示:list 和 table。 對(duì)于相同的概念,沒(méi)有理由使用不同的詞。 它增加了混亂并打破了命名的一致性。
將組件命名為
組件,方法和變量的有意義的名稱足以使代碼可讀。 因此,注釋大多是多余的。
案例研究:編寫自解釋代碼常見(jiàn)的濫用注釋是對(duì)無(wú)法識(shí)別和模糊命名的解釋。讓我們看看這樣的例子:
//渲染 games 列表 // "data" prop contains a list of game data function Games({ data }) { // display up to 10 first games const data1 = data.slice(0, 10); // Map data1 to component // "list" has an array of components const list = data1.map(function (v) { // "v" has game data return ; }); return {list}
; }
上例中的注釋澄清了模糊的代碼。
如果重構(gòu)組件,使用有意義的 props 名和變量名,那么注釋就可以被省略:
const GAMES_LIMIT = 10; function GamesList({ items }) { const itemsSlice = items.slice(0, GAMES_LIMIT); const games = itemsSlice.map(function (gameItem) { return; }); return
不要使用注釋去解釋你的代碼,而是代碼即注釋。(小夕注:代碼即注釋很多人未必能做到,另外因團(tuán)隊(duì)成員水平不一致,大家還是應(yīng)該編寫適當(dāng)?shù)淖⑨?
表現(xiàn)力階梯我將一個(gè)組件表現(xiàn)力分為4個(gè)臺(tái)階。 組件在樓梯上的位置越低,意味著需要更多的努力才能理解。
你可以通過(guò)以下幾種方式來(lái)了解組件的作用:
讀取變量名 和 props
閱讀文檔/注釋
瀏覽代碼
咨詢作者
如果變量名和 props 提供了足夠的信息足以讓你理解這個(gè)組件的作用和使用方式,那就是一種超強(qiáng)的表達(dá)能力。 盡量保持這種高質(zhì)量水平。
有些組件具有復(fù)雜的邏輯,即使是好的命名也無(wú)法提供必要的細(xì)節(jié)。那么就需要閱讀文檔。
如果缺少文檔或沒(méi)有文檔中沒(méi)有回答所有問(wèn)題,則必須瀏覽代碼。由于花費(fèi)了額外的時(shí)間,這不是最佳選擇,但這是可以接受的。
在瀏覽代碼也無(wú)助于理解組件時(shí),下一步是向組件的作者詢問(wèn)詳細(xì)信息。這絕對(duì)是錯(cuò)誤的命名,并應(yīng)該避免進(jìn)入這一步。最好讓作者重構(gòu)代碼,或者自己重構(gòu)代碼。
持續(xù)改進(jìn)重寫是寫作的本質(zhì)。專業(yè)作家一遍又一遍地重寫他們的句子。
要生成高質(zhì)量的文本,您必須多次重寫句子。閱讀書面文字,簡(jiǎn)化令人困惑的地方,使用更多的同義詞,刪除雜亂的單詞 - 然后重復(fù),直到你有一段愉快的文字。
有趣的是,相同的重寫概念適用于設(shè)計(jì)組件。有時(shí),在第一次嘗試時(shí)幾乎不可能創(chuàng)建正確的組件結(jié)構(gòu),因?yàn)椋?/p>
緊迫的項(xiàng)目排期不允許在系統(tǒng)設(shè)計(jì)上花費(fèi)足夠的時(shí)間
最初選擇的方法是錯(cuò)誤的
剛剛找到了一個(gè)可以更好地解決問(wèn)題的開(kāi)源庫(kù)
或任何其他原因。
組件越復(fù)雜,就越需要驗(yàn)證和重構(gòu)。
組件是否實(shí)現(xiàn)了單一職責(zé),是否封裝良好,是否經(jīng)過(guò)充分測(cè)試?如果您無(wú)法回答某個(gè)肯定,請(qǐng)確定脆弱部分(通過(guò)與上述7個(gè)原則進(jìn)行比較)并重構(gòu)該組件。
實(shí)際上,開(kāi)發(fā)是一個(gè)永不停止的過(guò)程,可以審查以前的決策并進(jìn)行改進(jìn)。
可靠性很重要組件的質(zhì)量保證需要努力和定期審查。這個(gè)投資是值得的,因?yàn)檎_的組件是精心設(shè)計(jì)的系統(tǒng)的基礎(chǔ)。這種系統(tǒng)易于維護(hù)和增長(zhǎng),其復(fù)雜性線性增加。
因此,在任何項(xiàng)目階段,開(kāi)發(fā)都相對(duì)方便。
另一方面,隨著系統(tǒng)大小的增加,你可能忘記計(jì)劃并定期校正結(jié)構(gòu),減少耦合。僅僅是是實(shí)現(xiàn)功能。
但是,在系統(tǒng)變得足夠緊密耦合的不可避免的時(shí)刻,滿足新要求變得呈指數(shù)級(jí)復(fù)雜化。你無(wú)法控制代碼,系統(tǒng)的脆弱反而控制了你。錯(cuò)誤修復(fù)會(huì)產(chǎn)生新的錯(cuò)誤,代碼更新需要一系列相關(guān)的修改。
悲傷的故事要怎么結(jié)束?你可能會(huì)拋棄當(dāng)前系統(tǒng)并從頭開(kāi)始重寫代碼,或者很可能繼續(xù)吃仙人掌。我吃了很多仙人掌,你可能也是,這不是最好的感覺(jué)。
解決方案簡(jiǎn)單但要求苛刻:編寫可靠的組件。
結(jié)論前文所說(shuō)的7個(gè)準(zhǔn)則從不用的角度闡述了同一個(gè)思想:
可靠的組件實(shí)現(xiàn)一個(gè)職責(zé),隱藏其內(nèi)部結(jié)構(gòu)并提供有效的 props 來(lái)控制其行為。
單一職責(zé)和封裝是 solid 設(shè)計(jì)的基礎(chǔ)。(maybe你需要了解一下 solid 原則是什么。)
單一職責(zé)建議創(chuàng)建一個(gè)只實(shí)現(xiàn)一個(gè)職責(zé)的組件,并有一個(gè)改變的理由。
良好封裝的組件隱藏其內(nèi)部結(jié)構(gòu)和實(shí)現(xiàn)細(xì)節(jié),并定義 props 來(lái)控制行為和輸出。
組合結(jié)構(gòu)大的組件。只需將它們分成較小的塊,然后使用組合進(jìn)行整合,使復(fù)雜組件變得簡(jiǎn)單。
可復(fù)用的組件是精心設(shè)計(jì)的系統(tǒng)的結(jié)果。盡可能重復(fù)使用代碼以避免重復(fù)。
網(wǎng)絡(luò)請(qǐng)求或全局變量等副作用使組件依賴于環(huán)境。通過(guò)為相同的 prop 值返回相同的輸出來(lái)使它們變得純凈。
有意義的組件命名和表達(dá)性代碼是可讀性的關(guān)鍵。你的代碼必須易于理解和閱讀。
測(cè)試不僅是一種自動(dòng)檢測(cè)錯(cuò)誤的方式。如果你發(fā)現(xiàn)某個(gè)組件難以測(cè)試,則很可能是設(shè)計(jì)不正確。
成功的應(yīng)用站在可靠的組件的肩膀上,因此編寫可靠、可擴(kuò)展和可維護(hù)的組件非常中重要。
在編寫React組件時(shí),你認(rèn)為哪些原則有用?
最后謝謝各位小伙伴愿意花費(fèi)寶貴的時(shí)間閱讀本文,如果本文給了您一點(diǎn)幫助或者是啟發(fā),請(qǐng)不要吝嗇你的贊和Star,您的肯定是我前進(jìn)的最大動(dòng)力。https://github.com/YvetteLau/...
關(guān)注小姐姐的公眾號(hào),加入交流群。文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/106861.html
摘要:組件可以處理其他組件的實(shí)例化為了避免破壞封裝,請(qǐng)注意通過(guò)傳遞的內(nèi)容。因此,將狀態(tài)管理的父組件實(shí)例傳遞給子組件會(huì)破壞封裝。讓我們改進(jìn)兩個(gè)組件的結(jié)構(gòu)和屬性,以便恢復(fù)封裝。組件的可重用性和可測(cè)試性顯著增加。 翻譯:劉小夕原文鏈接:https://dmitripavlutin.com/7-... 原文的篇幅非常長(zhǎng),不過(guò)內(nèi)容太過(guò)于吸引我,還是忍不住要翻譯出來(lái)。此篇文章對(duì)編寫可重用和可維護(hù)的Re...
摘要:幸運(yùn)的是,組合易于理解。組件的組合是自然而然的。高效用戶界面可組合的層次結(jié)構(gòu),因此,組件的組合是一種構(gòu)建用戶界面的有效的方式。這個(gè)原則建議避免重復(fù)。只有一個(gè)組件符合單一責(zé)任原則并且具有合理的封裝時(shí),它是可復(fù)用的。 翻譯:劉小夕原文鏈接:https://dmitripavlutin.com/7-... 原文的篇幅非常長(zhǎng),不過(guò)內(nèi)容太過(guò)于吸引我,還是忍不住要翻譯出來(lái)。此篇文章對(duì)編寫可重用和...
摘要:編寫組件時(shí)要考慮的基本準(zhǔn)則是單一職責(zé)原則。這些更改通常要求組件在隔離狀態(tài)下易于修改這也是的目標(biāo)。解決多重責(zé)任問(wèn)題需要將分割為兩個(gè)組件和。組件之間的通信是通過(guò)實(shí)現(xiàn)。更改的唯一原因是修改表單字段。 翻譯:劉小夕原文鏈接:https://dmitripavlutin.com/7-... 原文的篇幅非常長(zhǎng),不過(guò)內(nèi)容太過(guò)于吸引我,還是忍不住要翻譯出來(lái)。此篇文章對(duì)編寫可重用和可維護(hù)的React組...
摘要:前端還有一個(gè)很重要的事就是設(shè)計(jì)。,中文版譯名為認(rèn)知與設(shè)計(jì)理解設(shè)計(jì)準(zhǔn)則。實(shí)驗(yàn)室是布拉德弗羅斯特依照這個(gè)設(shè)計(jì)系統(tǒng)所建立的一套工具,可以前往的來(lái)試試。中文翻譯為流暢設(shè)計(jì)體系,是微軟于年開(kāi)發(fā)的設(shè)計(jì)語(yǔ)言。微軟于年月日的開(kāi)發(fā)者大會(huì)上公開(kāi)了該設(shè)計(jì)體系。 showImg(https://segmentfault.com/img/bVbkgFI?w=1142&h=640); 想閱讀更多優(yōu)質(zhì)文章請(qǐng)猛戳Gi...
摘要:很明顯,非對(duì)稱加密的極大的消耗成了一種瓶頸。其中,利用非對(duì)稱加密的方案大概就是我前面說(shuō)的那樣,偽代碼已經(jīng)展示過(guò)了。 其實(shí),前面兩篇翻來(lái)覆去只為叨逼叨叨逼叨兩件事情: 對(duì)稱加解密,典型算法有AES、DES、3DES等等 非對(duì)稱加解密,典型的算法有RSA、DSA、ECDH等等 但是,我知道大家最討厭在看這種文章的時(shí)候冒出來(lái)的一坨橢圓曲線、素?cái)?shù)、質(zhì)數(shù)等等這樣的玩意,反正看也看不懂,理解也...
閱讀 2048·2023-04-25 15:45
閱讀 1458·2021-09-29 09:34
閱讀 2578·2021-09-03 10:30
閱讀 2081·2019-08-30 15:56
閱讀 1512·2019-08-29 15:31
閱讀 1335·2019-08-29 15:29
閱讀 3258·2019-08-29 11:24
閱讀 3120·2019-08-26 13:45