CoderClark
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights
    • Engagement control
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Versions and GitHub Sync Note Insights Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       owned this note    owned this note      
    Published Linked with GitHub
    Subscribed
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    Subscribe
    # A0003 程式碼是寫給人看的。易讀很重要 ## 程式碼是寫給誰看的? **「程式碼是是寫給人看的」** 這件事情,在程式設計領域已經是老生常談了;正因為要給人看,所以如何讓程式碼好閱讀,就是很重要的課題。這就是所謂的**易讀性**(或許有些人稱作是**可讀性**,指的是同一件事情)。許多文獻都強調了這件事情, 這裡僅舉例列出2則經典書籍的名言供參考。 >**「任何傻子都能寫出電腦能懂的程式碼,而好的程式設計人員才能寫出人類能懂的程式碼」**[^1] > -- Martin Fowler et. al., _Refactoring: Improving the Design of Existing Code_, 1999. [^1]: "Any fool can write code that a computer can understand. Good programmers write code that humans can understand." Martin Fowler et. al., _Refactoring: Improving the Design of Existing Code_, 1999. > **「寫程式要優先給人看,然後才是電腦」**[^2] > -- Steve McConnell, _Code Complete: A Practical Handbook of Software Construction, Second Edition_, 2004 [^2]: "Write programs for people first, computers second." Steve McConnell, _Code Complete: A Practical Handbook of Software Construction, Second Edition_, 2004 ## 易讀性的重要 即使知道文獻都這樣說、大師們、前輩們都認為易讀性很重要,但為什麼大多數程式碼還是寫得晦澀難懂呢?或許是沒有認真思考過「為什麼易讀性很重要」吧!要知道,人們通常是透過思考並理解原因後,才能將知識與觀念內化,然後才是實踐。換句話說,如果沒有打從心底覺得易讀性很重要,自然是不會在寫程式的時候把它放在心上。 下面就來探討易讀的重要性、與不願意寫易讀程式碼的原因吧。 ### 程式碼是需要維護與複用的 對於程式碼要寫得易讀,常見的解釋一般都圍繞在程式碼是需要**維護**與**複用**做討論,比方說會有下面這些考量: * 很多時候程式碼可能不只有自己要用,當別人要使用的時候,我們會希望易讀才容易複用。 * 雖然有的時候程式碼只有自己要用,但人是健忘的,幾個月後如果還需要使用或調整,不易讀的程式碼會很難召回記憶,要維護或複用都很困難。 * 即使撰寫中的程式碼只是一次性測試或實驗用的,也很可能在未來重新挖出來使用。如果不易讀,挖出來使用就會很痛苦。 總結來說,寫一個不易讀的程式碼,就可能在未來害人害己。如果想趨吉避凶,最好還是讓程式碼易讀。 ### 懶惰是人類的天性 既然考量都是很好的、都是很實際會遇到的情況,為什麼還不足以說服大家身體力行去提升易讀性呢?根本原因就在於 **「惰性」**! 人總是會想要偷懶的。對於未來的事情,會有不想處理的惰性。試想,這些維護與複用的考量,倘若未來不發生,為什麼要現在處理呢?別人要使用是未來式、忘記怎麼處理自己寫過的程式碼是未來式、重複使用一次性的程式碼也是未來式。只要是未來式就不一定會發生;只要僥倖不發生的話,這樣不處理就能獲得一種**賺到了的體驗**。即使未來發生了,等發生的時候再煩惱吧,甚至煩惱的可能也不是自己呀,何必當下操這個心呢?**反正程式碼能完成當前的目的就好,易讀性再說**。 ### 讓程式行為正確其實更重要 「反正程式碼能完成當前的目的就好」、「以後的事情以後再說」等想法是不容易反駁的,畢竟我們本來就不可能、也不應該做太久遠以後的考量,才不至於讓整個程式藍圖過於龐大,導致無法完成。無怪乎人們總是不願意多付出心力在易讀性上面了。 然而,把**未來不一定會有用處**作為偷懶的藉口是陷入一個**盲點**。程式碼易讀的重要性其實在**當下**就非常重要了!這是一個想偷懶也躲不掉的理由:**讓程式行為正確**。怎麼說呢?首先,我們應該重新檢視一下**程式碼**到底是做什麼用的。 所謂程式碼,就是程式設計人員撰寫出來的文字描述,去告訴電腦要做到什麼事情;也就是說,電腦要做什麼事情,依照的是該程式碼所代表的**行為集合**。電腦不可能直接知道程式設計人員想要做什麼事情,一切都要透過程式碼才能辦到。所以要思考的是**要如何確保撰寫出來的程式碼,等價於自己想讓電腦執行的行為集合**。這個等價性,是不是就應該**讓程式碼易讀,然後透過閱讀理解,直觀去確認是否跟自己心中所想的相符**呢?一份不易讀的程式碼,想要精準理解該程式碼所代表的行為集合,是非常困難的。 ```mermaid graph TD; PROGRAMMER["程式設計人員"] --> CODE["程式碼"] ; CODE --> CPU["電腦(運算平台)"]; ``` 當程式碼難以理解,就很難確保電腦進行我們所預期行為;而電腦產生不預期行為,就是所謂的 Bug,是程式設計人員不樂見的。減少 Bug、讓**程式行為正確**不是未來的問題,是真真切切當下就要處理的事情,實在不應該有任何偷懶的理由! ### 慢慢來比較快 除了沒想清楚易讀性是當下的課題外,另一個常見的偷懶理由是**想更快完成程式碼**。因為要讓程式碼易讀,可能需要用字白話、邏輯直觀、概念精準,即使不花額外敲程式碼的時間,也需要花思考的時間來做規劃。 不管易讀性,程式碼寫起來真的會比較快嗎?在這樣認知前,請先釐清一個事實:**一個程式的完成,不是程式碼敲完就好了,是必須行為正確**。經驗上,要保證程式行為正確,敲完程式碼後通常要經歷 Debug 階段才算達成。所以可以這麼說,一個完整的程式撰寫流程,應該包括敲程式碼與 Debug。 撰寫一個不易讀的程式碼,可能花費 20% 的時間在完成程式碼,然後因為程式碼不易讀,就會花費 80% 時間進行 Debug 與修正程式碼;相反地,撰寫一個易讀的程式碼,撰寫當下不容易出錯,因此時間佔比往往會反過來:花費 80% 的時間在完成程式碼,而只要 20% 的時間 Debug 即可。時間佔比相反的原因,主要在於撰寫易讀程式碼通常 Debug 的情況會很好掌握,而偷懶隨意寫程式碼的 Debug 的情況會很難掌握,不小心就會弄成解不掉的 Bug,甚至需要重寫程式碼才有機會解決問題!所以**要覺得撰寫易讀程式碼的過程看起來很慢,但其實最後是比較快完成程式的**。 ### 愉快地寫程式吧 再退一步講好了。假設不管有沒有寫易讀程式碼,最後完成程式所花的總時間相同,那應該要選擇什麼方式進行比較好呢?一般而言,單純寫程式碼是愉悅的,但 Debug 是痛苦的;如果是看著難懂的程式碼,肯定會更加痛苦。請試著思考下面的例子,哪一個是比較愉悅的體驗: * 花費4小時建構一個易讀的程式碼,加上1小時的 Debug * 花費1小時建構一個難讀的程式碼,加上4小時的 Debug 答案應該是顯而易見的。撰寫易讀程式碼吧!人生已經很苦了,就不要再讓完成程式的過程也是痛苦的了。 ## 易讀程式碼好處多,不寫嗎? 總結來說,不要再為了莫名的理由而偷懶寫逃避易讀性了。確保易讀性,不但容易保證程式碼行為,還能更快完成程式,而且體驗愉悅。易讀程式碼好處多多,不寫嗎?**程式碼是寫給人看的**,這個經典文獻的金玉良言,相信只要人類還需要寫程式碼的一天,就不會有過時的時候吧! --- ## 延伸閱讀 [B0001 易讀程式碼的特性:白話](/bdQxzTadSP-HIfXlQZHxLg) [B0002 易讀程式碼的特性:直觀](/dlMMeRFHTbODazo1B5DgCw) [B0003 易讀程式碼的特性:精準](/v3PlMq0cQkO25DqTpRhXYg)

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully