<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          真坑!整潔代碼,再見??!

          共 4738字,需瀏覽 10分鐘

           ·

          2021-02-05 15:07

          那是一個深夜。

          我的同事們剛剛提交了過去整整一周所寫的代碼。我們正在開發(fā)一個基于 Canvas 的圖形編輯器,他們負(fù)責(zé)實現(xiàn)各種“形狀”(比如:矩形、橢圓形)的縮放功能,縮放行為由拖拽“形狀”邊緣上的操作柄來實現(xiàn)。

          代碼運行正常。

          但是代碼有些重復(fù)。每個“形狀”(如:矩形、橢圓形)各自擁有若干操作柄,從不同方向拖拽操作柄都會對“形狀”的位置和尺寸產(chǎn)生相應(yīng)的影響。如果用戶按住“Shift”鍵,我們還需要保持住“形狀”的寬高比不變。這里涉及到一些數(shù)學(xué)計算。

          代碼看起來是這樣的:

          let?Rectangle?=?{
          ??resizeTopLeft(position,?size,?preserveAspect,?dx,?dy)?{
          ????//?10?repetitive?lines?of?math
          ??},
          ??resizeTopRight(position,?size,?preserveAspect,?dx,?dy)?{
          ????//?10?repetitive?lines?of?math
          ??},
          ??resizeBottomLeft(position,?size,?preserveAspect,?dx,?dy)?{
          ????//?10?repetitive?lines?of?math
          ??},
          ??resizeBottomRight(position,?size,?preserveAspect,?dx,?dy)?{
          ????//?10?repetitive?lines?of?math
          ??},
          };

          let?Oval?=?{
          ??resizeLeft(position,?size,?preserveAspect,?dx,?dy)?{
          ????//?10?repetitive?lines?of?math
          ??},
          ??resizeRight(position,?size,?preserveAspect,?dx,?dy)?{
          ????//?10?repetitive?lines?of?math
          ??},
          ??resizeTop(position,?size,?preserveAspect,?dx,?dy)?{
          ????//?10?repetitive?lines?of?math
          ??},
          ??resizeBottom(position,?size,?preserveAspect,?dx,?dy)?{
          ????//?10?repetitive?lines?of?math
          ??},
          };

          let?Header?=?{
          ??resizeLeft(position,?size,?preserveAspect,?dx,?dy)?{
          ????//?10?repetitive?lines?of?math
          ??},
          ??resizeRight(position,?size,?preserveAspect,?dx,?dy)?{
          ????//?10?repetitive?lines?of?math
          ??},??
          }

          let?TextBlock?=?{
          ??resizeTopLeft(position,?size,?preserveAspect,?dx,?dy)?{
          ????//?10?repetitive?lines?of?math
          ??},
          ??resizeTopRight(position,?size,?preserveAspect,?dx,?dy)?{
          ????//?10?repetitive?lines?of?math
          ??},
          ??resizeBottomLeft(position,?size,?preserveAspect,?dx,?dy)?{
          ????//?10?repetitive?lines?of?math
          ??},
          ??resizeBottomRight(position,?size,?preserveAspect,?dx,?dy)?{
          ????//?10?repetitive?lines?of?math
          ??},
          };

          這種重復(fù)的數(shù)學(xué)計算邏輯,對我來說,真的難受。

          這不是“整潔”的代碼。

          多數(shù)的重復(fù)都在于“方向”上的相似,舉個例子,Oval.resizeLeft()和?Header.resizeLeft()?就很類似。這是因為,它們都是在處理拖拽左側(cè)操作柄的問題。

          另一個原因在于“形狀”所擁有的方法上的相似,例如,Oval.resizeLeft()?和?Oval?上的其它方法是類似的。這是因為,它們都是在處理“橢圓形”上的問題。更進一步,Rectangle,?Header?以及?TextBlock?都有相似的地方,因為文本框都是“矩形”。

          我有個辦法。

          我們可以通過對代碼邏輯進行分組,來實現(xiàn)“去除全部重復(fù)”的目的:

          let?Directions?=?{
          ??top(...)?{
          ????//?5?unique?lines?of?math
          ??},
          ??left(...)?{
          ????//?5?unique?lines?of?math
          ??},
          ??bottom(...)?{
          ????//?5?unique?lines?of?math
          ??},
          ??right(...)?{
          ????//?5?unique?lines?of?math
          ??},
          };

          let?Shapes?=?{
          ??Oval(...)?{
          ????//?5?unique?lines?of?math
          ??},
          ??Rectangle(...)?{
          ????//?5?unique?lines?of?math
          ??},
          }

          然后,像這樣來組合它們:

          let?{top,?bottom,?left,?right}?=?Directions;

          function?createHandle(directions)?{
          ??//?20?lines?of?code
          }

          let?fourCorners?=?[
          ??createHandle([top,?left]),
          ??createHandle([top,?right]),
          ??createHandle([bottom,?left]),
          ??createHandle([bottom,?right]),
          ];
          let?fourSides?=?[
          ??createHandle([top]),
          ??createHandle([left]),
          ??createHandle([right]),
          ??createHandle([bottom]),
          ];
          let?twoSides?=?[
          ??createHandle([left]),
          ??createHandle([right]),
          ];

          function?createBox(shape,?handles)?{
          ??//?20?lines?of?code
          }

          let?Rectangle?=?createBox(Shapes.Rectangle,?fourCorners);
          let?Oval?=?createBox(Shapes.Oval,?fourSides);
          let?Header?=?createBox(Shapes.Rectangle,?twoSides);
          let?TextBox?=?createBox(Shapes.Rectangle,?fourCorners);

          代碼量減少到 1 / 2,并且,重復(fù)代碼不復(fù)存在!這真是“整潔”啊。如果我們希望改變具體某個“方向”上的或“形狀”上的行為,只需要修改一處,而非多處。

          已經(jīng)很晚了(我很疲憊了),我提交我重構(gòu)后的代碼,然后就躺下了,并對自己“幫助同事整潔代碼”而感到心滿意足。

          第二天上午

          … 事情并非我想的那樣。

          我的上級單獨找到了我,委婉地要求我撤銷昨天的那些修改。我感到很不可思議,舊代碼那么差勁,而我的是多么“整潔”?。?/p>

          我那時只好謹(jǐn)遵照守;但是后來,歷經(jīng)數(shù)年,我才明白他們的要求是對的。

          那是一個職業(yè)階段

          對“整潔代碼”的沉迷、好于“消除重復(fù)代碼”,是我們大多數(shù)開發(fā)者都會經(jīng)歷的階段。當(dāng)我們對自己的代碼沒有信心,自我價值感和專業(yè)榮譽感往往會使我們與一些可測量的東西靠攏,一組嚴(yán)格的 lint 規(guī)則、一套命名規(guī)范、一種文件結(jié)構(gòu)、無重復(fù)性指標(biāo),等等。

          你不可能讓“重復(fù)代碼”自動被消除,但是確實可以借助“實踐經(jīng)驗”使它更可行。你往往可以看到,每次修改后的代碼量是變得更多或更少。結(jié)果就是,消除重復(fù)代碼看起來提高了代碼的某些客觀的可測量指標(biāo)。然而,糟糕的是,這擾亂了人們的自我認(rèn)知,他們會對自己說:“我是那種會寫出整潔代碼的人”,而這其實跟其它的自我欺騙行為沒什么兩樣。

          一旦學(xué)會了如何“抽象”,我們似乎就會更進一步,每次看到重復(fù)的代碼,我們甚至能夠從“無”中發(fā)現(xiàn)可“抽象”的東西。編碼數(shù)年以后,我們已經(jīng)厲害得隨處都能看到重復(fù)的代碼,我們同時獲得了一項新的超能力:抽象。進而,如果有人告訴我們“抽象是好的”,我們便對此更加篤信。于是我們開始去批判那些不崇尚”整潔代碼”的人。

          我現(xiàn)在明白,我的那次“重構(gòu)行為”確實是一場災(zāi)難(譯者:夸張了吧~),從兩個方面來說:

          • 首先,我沒有告訴代碼的作者。我在沒有他們參入的情況下,重寫并提交了代碼。即便,那確是一次對代碼的“改善”(我現(xiàn)在不以為然了),它也十分可怕。一個健康的工程團隊需要不斷地“建立彼此的信任”。不經(jīng)討論而擅自重寫同事的代碼,是對高效協(xié)作能力的徹底否定。
          • 其次,一切都需要權(quán)衡。為了減少重復(fù),我的代碼難于應(yīng)付需求變更,而這并不值得。例如,我們后邊需要為不同“形狀”上的各個操作柄添加特殊的行為邏輯。為了應(yīng)付這些,我的“抽象”無疑使修改困難了數(shù)倍,反觀那原本“骯臟的”代碼,它則能夠輕松處理。

          我的意思是你應(yīng)該寫“臟”的代碼嗎?不,我建議你深入思考一下“整潔”與“骯臟”分別意指何物。你有對于批判、正確、美和優(yōu)雅的直覺嗎?你如何能確定地說你的這次工程成果達(dá)到了那些質(zhì)量指標(biāo)?它們?nèi)绾未_切地影響到代碼的產(chǎn)生與維護?

          我當(dāng)時確然對于這些問題沒有進行過深入思考;我當(dāng)時考慮的是代碼“看起來”如何,而不是代碼該如何隨著不斷流動的團隊而演進。

          寫代碼是一場旅行?;叵胍幌?,你編寫第一行代碼時的情形,到現(xiàn)在你所處的狀態(tài)。我相信,當(dāng)突然發(fā)現(xiàn)“抽取出一個函數(shù)”或“重構(gòu)一個類的定義”是如何使問題由復(fù)雜變得簡單的時候,你必定是開心的。一旦對自己的作品產(chǎn)生了自豪感,你就會熱切地去追求代碼的整潔。對此,你可以保持一段時間。

          但是不要止乎此,不要成為一個整潔代碼的狂熱分子。整潔代碼并不是目的,它只是讓我們從所面對系統(tǒng)的異常復(fù)雜性中解脫出來的方法。在你不是很明確一個改動會如何影響到整個代碼庫時,這信念可以作為一種安全防護機制。但是在未知的海洋里,你需要一個指南針。

          那就讓整潔代碼指引你吧,然后忘了它。

          源自:https://overreacted.io/zh-hans/goodbye-clean-code/

          聲明:文章著作權(quán)歸作者所有,如有侵權(quán),請聯(lián)系小編刪除。

          感謝 · 轉(zhuǎn)發(fā)歡迎大家留言

          關(guān)注數(shù):10億+?文章數(shù):10億+
          粉絲量:10億+?點擊量:10億+

          ?


          懸賞博主專區(qū)請掃描這里


          喜愛數(shù):?1億+?發(fā)帖數(shù):?1億+
          回帖數(shù):?1億+?結(jié)貼率:?99.9%


          —————END—————



          喜歡本文的朋友,歡迎關(guān)注公眾號?程序員哆啦A夢,收看更多精彩內(nèi)容

          點個[在看],是對小達(dá)最大的支持!


          如果覺得這篇文章還不錯,來個【分享、點贊、在看】三連吧,讓更多的人也看到~

          瀏覽 21
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  自拍偷拍第六页 | 大鸡吧操逼视频 | 五月情丁香五月情婷婷 | 免费看黄色一极片 | 婷婷激情丁香花 |