iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 3
0
AI & Data

行銷廣告、電商小編的武器,FB & IG 爬蟲專案從零開始系列 第 3

【Day3】努力寫出更好的程式碼,有時你不是一個人在戰鬥

不是每個人都能成為明星,但是所有人都可以努力做到能力範圍的最好,並持續提高 - Henk Vermeyden

接下來幾天,我會把這個專案開發前所需具備的基礎知識分幾個主題向各位分享,希望這些文章能給初學者正確的觀念、也能讓老手思考自己開發上是否有忽略的細節

/images/emoticon/emoticon19.gif 為什麼寫這篇文章?

我直到近一年才真正意識到好的程式碼在團隊合作中有多麼重要
在團隊裡面你不只是要完成自己負責的功能,你更要讓其他同事能在短時間理解你的程式
就算你是一個人獨立完成專案,好的程式碼能讓你在日後維護上節省更多的時間及精力

希望未來我們回頭看一年前寫的專案時,不求內心的小精靈呼喊:"X,寫得太精采了!",只希望內心的小精靈不要滿嘴髒話就好


/images/emoticon/emoticon12.gif 今日目標

對我來說高效能演算法與複雜的語法並不是我所追求的東西(其實是因為筆者資質駑鈍看不懂)
所以今天的目標就是如何寫出讓笨笨的筆者都能看懂的程式XD,這在程式界有個專有名詞叫做 Clean Code(無暇程式碼)
我將裡面幾個重要的點列在下方,並用我實際的經驗作解釋

  1. 正確的宣告變數
  2. 有意義的命名
  3. 避免重複的程式碼
  4. 大眾都能理解的程式
  5. 好的註解
  6. 錯誤處理 & 日誌(log)

1. 正確的宣告變數

用對的方式宣告變數才會讓人了解到他的意義

  • var : 作用範圍在函式(function裡面),這樣的宣告方式讓他可以在函式內的任何位置使用,但因為容許重複宣告,所以會造成變數被覆寫的意外,請盡量減少使用
    function test() {
      // 宣告時給一個初始值
      var baby = "寶寶本尊"
    
      // 再次宣告
      var baby = "寶寶被污染了"
      console.log(baby) // 會印出'寶寶被污染了'
    }
    
  • let : 作用範圍在區塊(block裡面{}),可被重新指定值,let 與 const 皆不可重複宣告會報錯
    function test() {
        // 宣告時給一個初始值
        let baby = "寶寶本尊"
    
        // 重新指定值
        baby = "寶寶變身"
        console.log(baby) // 會印出'寶寶變身'
    
        // 再次宣告
        let baby = "寶寶壞掉了"
        // 會跳出錯誤 SyntaxError: Identifier 'baby' has already been declared
    }
    
  • const : 作用範圍在區塊(block裡面{}),宣告後為不可被重新指定值的常數,使用他就是為了避免該常數被修改
    • 定義不做改變的常數 : const PI = 3.14159
      function test() {
          // 宣告時給一個初始值
          const baby = "寶寶不可改變"
      
          // 重新指定值
          baby = "寶寶變身失敗"
          // 會跳出錯誤 TypeError: Assignment to constant variable.
      }
      
    • 特別注意如果 const 宣告陣列(array)或物件(object)時是可以被改變的,因為他們都是 reference type
      function test () {
          // 宣告為物件
          const baby = { name: "寶寶本尊" }
      
          // 重新指定值
          baby.name = "寶寶變身"
          console.log(baby) // 會印出'{ name: '寶寶變身' }'
      }
      

2. 有意義的命名

這裡要看你工作環境的默契去做調整,但還是有幾個基礎要求

  • 函式(function)的命名

    • 要一眼就能明白他要做的事情
      // 不好的命名,你無法從名字理解他要做的事情
      function abc(a, b) {
        return a + b
      }
      
      // 好的命名,淺顯易懂
      function sum(a, b) {
        return a + b
      }
      
    • 命名不要複雜化,做一件事情就好
      // 不好的命名,一個函式做太多事情了
      function goBackpageWriteContent() {...}
      // 好的命名,一個函式昨一件事,上面的function可以做拆分
      function goBackpage() {...}
      function writeContent() {...}
      
  • 變數(variable)的命名能直接知道他代表甚麼

    // 不好的命名,你看到會覺得疑惑
    let haha = '猜猜看這個變數代表甚麼'
    
    // 好的命名,非常直觀無須猜想
    let name = '好想兔'
    

3. 避免重複的程式碼

在快速開發時期複製貼上是最爽的事情,但你在未來會付出沉重的代價如下

  • 專案需求變更 : 你會發現維護是如此的困難,你可能已經忘記之前有多少程式是複製貼上,導致不斷產生新的Bug
  • 程式體積龐大理解不易 : 兩段長得很像的程式你會需要用大家來找碴的方式去思考

解決方案

  • 如果有功能一模一樣且多次被不同檔案使用的函式建議你寫一個專案共用函式庫(ex: public.js),這樣功能修改時只要改一個地方就好
  • 如果遇到功能很接近的需求請把他們結合到一個函式中吧,你可以搭配參數來處理當中的差異性

4. 大眾都能理解的程式

  • 我周圍曾經遇過程式能力極強,但是幾乎無法與人合作的工程師,他們所寫的程式有幾個特點

    • 程式邏輯非常難理解:他們可能使用效能最好的處理方案,但是邏輯非常跳躍晦澀難懂
    • 語法非常新潮:使用時代最尖端的語法,但同事在閱讀理解上會很痛苦
  • 也遇過只求完成功能得過且過的工程師,他們也有幾個特點

    • 他們不知道自己寫了甚麼:都是從網路上複製貼上,能跑就好,甚至參數命名都不改,於是交接的時候就是地獄,因為連他都不知道這段程式做了什麼
    • 功能都是複製貼上:就算是一模一樣的功能,由於過去都是從網路複製貼上完成,所以有時他們甚至忘記自己寫過他,再次從網路複製另一段程式不一樣但功能一樣的code貼上...,認真覺得這種解決事情的方法超級母湯

遇到前者是你的幸運也是你的不幸,雖然你可以與神同行,但是要不斷的提升自己才能夠勉強跟上他們的思路;遇到後者就當成鍛鍊,你要嘗試將這些不明所以的程式碼重構,讓他足以被大眾理解

而我寫程式的目標是希望在交接的時候被人輕易理解,所以在撰寫的過程中會不斷反思這些程式碼寫在這裡的意義是甚麼,如果自己都無法解釋的程式,就不用期待他人能夠理解了


5. 好的註解

雖然有神人說過:最好的註解就是程式碼本身
但我想絕大多數的人都難以到達這個境界,所以要乖乖地寫註解

  • 註解的好處
    • 交代前因後果:為什麼這樣寫?遇到了什麼困難?解決了什麼問題?
    • 作為文件說明:有些技術是需要被學習後才能夠看得懂的(ex:引入的模組、套件),你的註解能讓他快速理解這些工具怎麼使用
  • 請不要有註解如下
    • 毫無意義的牢騷(ex:我好崩潰啊,這段程式我寫了一個禮拜...)
    • 把註解當成版本控制(ex:2020/08/23完成此函式)
    • 說明這段程式是誰寫的(簽名檔)
    • 把舊的程式碼註解起來怕以後會用到(但通常再也不會用到,而且這個問題用版控就能解決)

6. 錯誤處理 & 日誌(log)

寫的再好的程式都會有漏洞,而完善的錯誤處理 & 明確的日誌紀錄可以協助你更快速的除錯(debug)

  • 錯誤處理:通常使用 try-catch 的方式來處理,這個部分在後面的章節會更詳細介紹
  • 日誌(log):記錄程式執行時重要的節點
    • 程式執行到哪個步驟
    • 資料是否取得
    • 如果發生錯誤時式在哪個環節

以上是我對 Clean Code 的個人感想,如果大家對於文章的內容有任何想法歡迎討論~


/images/emoticon/emoticon41.gif 參考資源

  1. Clean Code 無瑕的程式碼
  2. 變數、常數與命名
  3. var, let, const 差異
  4. var 與 let 的主要差別
  5. JavaScript ES6 中使用 const 宣告常數

https://ithelp.ithome.com.tw/upload/images/20210720/20103256fSYXlTEtRN.jpg
在許多人的幫助下,本系列文章已出版成書,並添加了新的篇章與細節補充:

  • 加入更多實務經驗,用完整的開發流程讓讀者了解專案每個階段要注意的事項
  • 將爬蟲的步驟與技巧做更詳細的說明,讓讀者可以輕鬆入門
  • 調整專案架構
    • 優化爬蟲程式,以更廣的視角來擷取網頁資訊
    • 增加資料驗證、錯誤通知等功能,讓爬蟲執行遇到問題時可以第一時間通知使用者
    • 排程部分改用 node-schedule & pm2 的組合,讓讀者可以輕鬆管理專案程序並獲得更精確的 log 資訊

有興趣的朋友可以到天瓏書局選購,感謝大家的支持。
購書連結https://www.tenlong.com.tw/products/9789864348008


上一篇
【Day2】開發環境大補帖 - Node.js、NVM、git、yarn、VSCode
下一篇
【Day4】建立Node.js專案 & 全面解析專案管家package.json
系列文
行銷廣告、電商小編的武器,FB & IG 爬蟲專案從零開始30

尚未有邦友留言

立即登入留言