Brian的雜記
  • Introduction
  • Brian's 雜記
    • My Awesome API
    • FB 大頭貼
    • 硬體雜記
    • PHP
    • project
      • 模擬器
      • WAMP
    • WinMerge
    • 雜記
      • LINQ
      • 方法
      • Grid View
      • namespace
      • global
      • 物件導向
      • Excel
      • VS2017
      • single sign on
      • Master
      • Https
      • 憑證
      • 略過憑證不符
      • NLog
      • 團隊開發
      • .NET Core
      • 共用網路上的芳鄰
      • 爬蟲
      • NPOI
      • RSS
      • 多執行緒
      • 記憶體回收
      • 密碼學
        • BCrypt
        • AES
      • 主機環境建置
      • Session
      • Error
      • IIS 相關
      • 無障礙相關
      • 介面
        • 影像地圖
      • telnet
        • smtp
      • nslookup
      • 協助客戶解決問題
      • 驗證欄位
      • 網站管理
      • 工具整理
    • 正規表示法
    • 影像處理
    • IntelliJ Idea
    • 觀念
      • Clean Code
        • 命名
        • 函式
        • 註解
        • 編排
        • 物件及資料結構
        • 錯誤處理
        • 邊界
        • 單元測試
        • 類別
      • Java 程式風格
      • Design Pattern
        • 單例模式
      • 同步
      • 畫圖
        • ER-Model
        • 類別圖
        • Use Case
        • 有限狀態機
      • 資料 API 文件 分析
      • CORS & SSL
      • 利用DISC幫助溝通
      • OAS
    • 檔案上傳
      • FileStore
      • App Engine
      • Google Storage
    • OAuth vs Open ID
    • MIME
    • 虛擬桌面
    • 待看資料
    • Selenium
    • CDN
    • HTTP
    • 編碼
    • 2nd-ML100Days
      • jupyter
    • 微服務
      • 設計
        • 1 ~ 5
        • 6
        • 7
        • 8
        • 9
    • Gradle
    • Maven
    • Error
    • 批次檔 BAT
    • Kurento
    • WebSocket & WebRTC
  • 需求面能力
    • User Story
  • Google Cloud Platform
    • Compute Engine
  • Python
    • 基本語法
    • Pandas
    • 套件
    • Matplotlib
    • Encoder
    • jupyter
  • Java
    • Java
      • File
      • Exception
      • 物件導向觀念
      • 加密
      • HTTP
      • 集合
      • Stream()
      • Web
      • ResultSet
      • JDK6
      • JDK8
    • 讀取、複寫MP3 Tag
    • Log4j2
    • Servlet
      • 容器
    • JSP
    • JBOSS
    • JWT
    • PreparedStatement
    • Error
    • Spring
      • Spring Boot
        • @Value
        • Build
      • RequestParameter
      • Error
      • Autowired
      • JPA
      • FeignClient
      • WebSocket
      • thymeleaf
      • Security
      • Test
      • Scheduled
      • Redirect
    • IntelliJ
  • Linux
    • Linux
    • Shell Script
    • Cygwin(在Windows執行Linux指令)
  • 前端
    • HTML
      • Link
    • CSS
      • Position
      • padding color
      • display
    • JS
      • jQuery
        • Select2
      • fancybox
      • ES6
      • 效能
      • GoogleMap API
        • Marker
        • InfoWindow
      • 事件
      • CKEditor
      • TGOS
      • JSON
      • QRcode
      • 核心概念
        • 物件 變數 型別
          • number
          • String
          • boolean
          • null & undefined
          • Symbol
        • JS 物件概念
        • 深入理解JS 函式物件
        • 更多ES2015/ES6 全新語言特性
      • Promise
    • 效果應用
  • 資料庫
    • 注意事項
    • MariaDB
    • MySQL
      • inner join 和 join
      • 字串比對
      • 倒數資料
    • SQL
      • DDL 資料定義語言
      • DML 資料操縱語言
      • DCL 資料控制語言
      • TCL 交易控制語言
      • T-SQL
      • CTE
      • JOIN
    • Oracle
    • MSSQL 操作
      • 新增使用者
      • SQL 指令
      • Sequence
    • 差異比較
    • MyBatis
    • Workbench 操作
    • SQL Injection
  • 版本控制
    • Gitlab
      • sign up
      • sign in
      • add project
      • add members
    • SourceGit
      • install
    • SmartGit
      • install
      • operate
      • git 操作雜記
    • TortoiseGit
    • Git
    • TFS
    • SVN
  • Test
    • 軟體測試原則
    • 演算法
    • XMind
      • install
    • Jenkins
      • 建置
    • HTTPie
    • Postman
    • 測試驅動開發
    • 撰寫測試的觀念
    • 測試框架
    • IoC & DI
    • 隔絕相依性的方式
    • JUnit
    • NUnit
    • 習慣
    • 虛設常式
  • Angular
    • hello world
    • ng-options
    • ES6
    • Build & Conponect
    • HttpClient
    • 部署
  • ASP.NET Web Form
    • Chapter 2
      • 2-1
        • 小東西
    • 略過請求驗證
  • Go
Powered by GitBook
On this page
  • 一個函式應該只做一件事情
  • 具描述能力的名稱
  • 用 switch 的時機:
  • 函式的參數
  • 要無副作用
  • 指令和查詢的分離
  • 使用例外處理取代回傳錯誤碼
  • 不要重複自己
  • 如何達到上述的原則?
  • 總結

Was this helpful?

  1. Brian's 雜記
  2. 觀念
  3. Clean Code

函式

一個函式應該只做一件事情

如何定義只做一件事情?

這個函式做的事情,在同一層的抽象概念裡,那就是只做一件事情。

也就是 每個函式只有一層抽象概念

倘若一個函式內,有的在高層次、有的在低層次,這種混合層次的抽象概念,令讀者不容易分辨 (分辨是一個概念還是細節)。倘若將細節與本質混在一起,就會有越來越多細節混雜於函式中。

具描述能力的名稱

一個較長但具描述性質的名稱 > 一個較短但難以理解的名稱

用 switch 的時機:

1.只出現一次 2.用來產生多型物件 3.被藏匿在某個繼承關係下 (上述盡量就好,有的時候還是會違反)

要讓switch只做一件事情很困難,畢竟本質上switch總是在做N件事情,但我們無法永遠避開switch,只能盡量把它埋在低層次。

函式的參數

函式的參數數量,最理想是零個,數量盡量越少越好。除非有特殊的理由,不然無論如何都不要超過三個參數。

從測試的角度看,輸入的參數越多,參數可能的組合就越多,負擔就會越大。

旗標(flag)參數 很爛,不要用。盡量避免將布林變數傳給函式。

單一參數的常見形式

使用單一參數通常有兩個常見的理由:

1.詢問關於這個參數的問題

2.對這個參數進行某種轉換後回傳。

另一個不普遍,但是很有用的單一參數形式 事件

這種形式中,會有一個輸入參數,但沒有任何輸出型參數。整個程式刻意將函式呼叫看做一個事件,並利用參數修改系統狀態。

兩個參數的函式

倘若兩個參數是有序元件組成的單一值,EX: new point(1,2); (直角坐標上本質就是需要兩個參數)

倘若是非有序的兩個參數,可以考慮將順序放進名稱。(可以節省讀者必須跳進function查看順序,所導致的思慮中斷)

需要查看這件事情,應該盡量避免。

三個參數的函式

參數的順序性、看到函式時的停頓、對於參數的忽略等等所導致的問題,都讓人更加難以理解。當要建立三個參數的函式時,請審慎思考。

物件型態的參數

函式參數太多時,可以嘗試將相關的函數包成類別,利用物件去傳遞。

不要覺得這看起來像是在作弊,當他們是某個概念裡的相似部分,這個概念應該獲得一個屬於它們的名稱。

參數串列

public String format(String format, Object... args)

雖然這個函式可以丟很多參數進去,但本質上還是兩個參數,那就OK。倘若本質上超過三個,那就是個錯誤了。

要無副作用

函式保證只做一件事情,卻暗地裡偷偷做其他事情,這就是副作用。

有時會導致奇怪的時空耦合(temporal coupling)和順序相依性問題。

所以務必讓函式只做一件事情,或是在函式名稱讓人知道。

指令和查詢的分離

函式應該是能做某些事情,或是回答某些問題,但不應該同時發生。

如果想要兩件事情都做,應該要拆成兩個函式。

使用例外處理取代回傳錯誤碼

因為回傳錯誤碼,有點違反指令和查詢分離原則,也會導致更深層的巢狀結構。因為當你回傳錯誤碼時,就是要求呼叫者馬上處理。

而使用 例外處理 取代 錯誤碼,就可以將錯誤處理的程式碼從正常的路徑中抽離出來,達到簡化程式碼的效果。

因為錯誤處理就是一件事情,在一個函式只處理一件事的原則下,一個處理錯誤的函式,不應該再做其他的事情。也就是說這個函式應該是 try 開頭,在catch/finally之後就不應該再有其他程式碼。

不要重複自己

如何達到上述的原則?

寫軟體就像寫作,先有想法,再有粗糙的草稿,有了第一份能跑的內容,開始精簡、修改、雕琢,當無法再精簡時,就代表完成了。

Uncle Bob 表示他開始寫函式,一開始總是又複雜又長,有很多縮排&巢狀迴圈,有很長的參數串列,有著隨意的命名,也有重複的程式碼。 (我還以為只有我廢廢的才這樣,高人都是直接下筆如有神助,想好直接寫出神code)

但他也有一整套Unit test,測試範圍涵蓋每一行粗糙的程式碼。

將函式分開、重新命名、減少重複、縮短方法並重新安排順序,甚至會打散類別但保持著單元測試能夠通過。

當函式都符合本書的準則時,就完成了這個函式。

他並不認為有任何人可以辦得到一開始就寫出神Code。

總結

函式簡短、有良好的命名、漂亮的結構。

描述系統的故事,各函式整潔的結合在一起。

Previous命名Next註解

Last updated 5 years ago

Was this helpful?