顯示具有 書籍 標籤的文章。 顯示所有文章
顯示具有 書籍 標籤的文章。 顯示所有文章

Thinking in JAVA 4/e

這是一本超級厚的書,將近一千四百頁,也是我翻完過最厚的一本程式相關書籍(上一本是 Code Complete 2).  不過因為愛,花了快兩個月的時間我終於把它翻完了! 一些 5.0 後才加入的特性或語法,我就看超快了,工作上用不到還是等用到再看比較符合時間成本! 看完問我記得什麼,我完全也記不得什麼,希望這也是知識內化的一種表現方式! Orz

個人覺得這本書可以比做是工具書的強化版. 章節跟一般 JAVA 入門書差不多,從最簡單的程式流程 > 物件 > 字串 … > GUI 由淺入深的單元,但跟一般入門書不同的是,它比較像一本上課在用的書 - 不單跟你說要怎麼寫,也告訴讀者為什麼要這樣寫的! 個人比較有受益的章節大概是 集合, I/O 和 並行性 這幾章! XD

再白話一點! Thinking in JAVA = JAVA 工具書 + SCJP 認證書籍

這本書我最不習慣的地方大概就是程式碼的部份. 眼睛實在是被 IDE 寵壞了,看到白底黑字然後下面又劃線的呈現方式,一整個是要被催眠的狀態啊!

至於大家害怕的中譯問題,我覺得書翻譯的不賴,讀起來很少會有不順暢的感覺! 有興趣的苦命 RD 可以放心買下去沒關係!

最後,看完心得為這本書適合寫 Java 一小陣子,然後已經熟悉 OOP ,也大概知道有 Design Pattern 這東西,想了解為什麼 JAVA 某些東西為什麼要這麼要使用的人購買!

用客戶的角度來看待設計決策

閱讀 How To Communicate Design Decisions To Clients? 的簡單翻譯兼筆記.

漂亮並不代表有效率

  • 漂亮的介面同時也代表會花費較多的時間及心力.
  • 漂亮的介面 與 特效 並不一定會帶來相對數量的生意.
  • 何時需要使用漂亮的介面/特效,還是得根據想達到的目標來決定! (殺雞是否要用牛刀)

每一個設計都應該有能量化的目標

  • 如果目標不能量化的話,那目標就只能是目標! like 建立一個[小黑宅]的品牌!
  • 訪客數量,在線人數…,這些就是很好的例子.

你的網站應該要有一條明顯的資訊路線

  • 訪客是用像瀑布的方式來瀏覽你的網站.
  • 一張網頁有大量的選擇,很容易讓訪客迷失其中.
  • 訪客不會認真思考去找出正確的路徑.
  • 試著離螢幕遠一點,再來瀏覽你的網站,是否能一眼看出你想傳達的訊息/功能.
  • 請讀一些 eye reacking 的研究,不要再要林北用大紅大藍當做字的顏色了!

切記瑞士小刀的例子

  • Google 有很多功能(並且可能互相關聯),但它不會在同一個地方同一個時間全部亮出來給你看!
  • 有一個最主要的功能,讓初來的訪客使用並留下印象. Google –> Search
  • 其他不是主打的功能,讓進階的使用者在有需要的時候再來使用. Google –> Search –> Blogger,Picasa,…
  • 首頁就把所有刀子都亮出來的網站,很容易把初到此處的訪客給嚇跑!
  • 讓網站有明確的路線及目的,同一頁面上的多餘功能只會讓訪客混亂分心!
  • 堅定此原則: 排除任何不需要的設計.

提供一些效率圖表

  • 展示客戶最愛看的圖表.
  • 讓客戶知道”你不只是設計程式/介面,你還懂得客戶到底想要得到什麼”.

不論身處什麼行業,請用客戶的語言(思考/概念)與客戶溝通.

十個軟體設計師應該有的觀念

閱讀 Top 10 Concepts That Every Software Engineer Should Know 的簡單翻譯兼筆記.

好的 RD 了解並使用 Design Pattern,積極去 Refactor 程式碼和編寫測試程式,並讓一切事物保持簡單! 除此之外還有10個概念是我們必須要熟悉的.

Interfaces

  • 現實生活中的問題 –> 系統內的模組
  • 不要加進一個你覺得未來會很有用的方法.
  • 不要害怕承認過去自己做的蠢事.
  • 享受設計的過程.

Conventions and Templates

  • 命名規則 和 程式樣版 是最簡單最有用也是”最被人忽視”的有用觀念.

Layering

  • 相同概念的元件組成一個子系統.
  • 整個系統就像是一座金字塔,由底層子系統慢慢建構上來.
  • 系統內不會有互相依賴(迴圈)的情況發生(好萊塢 Pattern).

Algorithmic Complexity

  • big O notation. Orz 我全部還給老師了!
  • 以下為翻譯兼復習 囧rz
    • 在串列中,用一個一個比對的方式會是 O(n).
    • 在串列中,用 Binary Search 會是 log(n).
    • 而將 n 的項目排列則是 n*log(n).
  • 少用多層次的巢狀迴圈,而改用 Hashtable , list 或 單層巢狀迴圈.

Hashing

  • 我們有很多的現成實作函式庫,讓我們可以把精力花在”判斷何時要使用 Hash” 以及 “微調參數提升 Hash 效率”這兩件事情上.

Caching

  • 每一次打資料庫都是一件耗時的工作.
  • 快取”時常需要產生並不太需要即時反應的結果”.

Concurrency

Package java.util.concurrent

Cloud Computing

Security

Relational Databases

自己的心得:

寫程式的面向真的很多,要全部都會我看我自己這輩子是不可能了! 但如同原作者最後所述:

But a good craftsman still needs to know what tools to use, when and why.

做不成大師也要成為一個不錯的工匠! 就這樣!

美麗程式 第7章 美麗測試

學生時代,程式對我來說似乎沒有美不美的問題,只有可不可以交差的問題! 工作之後遇到 Ivan 才漸漸地會去思考”如何寫出漂亮的程式碼”這件事!

我不太愛跟別人討論編碼的事,我覺得有時這跟政治口水一樣,碰到不理性或固守陳規的人,最後往往是意見相左,更別提激盪出什麼創意的火花! 所以我喜歡看書! 書不會跟你爭論,沒有意氣之爭的狀態下,我也能好好靜下心來想想這到底是不是好的作法!

扯遠了! 反正會買這本書是因為覺得,工程師在工作上常常會檢視別人的程式碼,新手更可能被他第一次所接觸的程式碼而影響他往後的寫作風格.但我們如何知道我們看到的是值得模仿或學習的編碼風格呢?

我沒有時間/精力/興趣去看網路上有名的 Open Source 的原碼,但買一本書就能看到38位大師的一些思考方式,我相信這點時間是我這個編碼黑手需要付出的! 囧rz

美麗程式

(封面轉載自博客來)

內容簡介:

本書收集了軟體設計領域的大師級作品,每個作品都獨一無二,而又見解深刻。走在時代前驅的設計大師,引領讀者一章章走過解決特殊難題的優雅方案,並說明各個方案的迷人因素。這不是另一本設計模式書籍,也不是另一本探討軟體工程方法對錯的專著。我們希望讀者有機會站在軟體設計巨人的肩上,從他們的高度看世界。三十八位撰碼大師,把他們打造專案架構、判斷建置代價、決定打破成規的重要時刻,化為字字珠磯,呈現在讀者面前。

上尉詩人

(圖片轉自詹姆仕布朗特 官方部落格)

不知為何,我看到 美麗程式 腦中就會浮現 詹姆士布朗特 唱的那句 “You are so beautiful” !

上面根本就是在勸敗(讀),以下就是個人超簡短的第七章筆記:

測試導向編碼(先寫簡單測試再開始編碼)的優點:

  • 一開始便以第三方的角度來切入自己寫的程式,讓程式慢慢浮現出它所需要展現的功能,實作的成果也比較有模組化的架構.
  • 在編碼初期給予編碼者對於自己寫出來的程式碼有一定的信心. 當然你不寫測試程式也是可以很有信心啦! XD
  • 在專案中後期遇上架構的變動或重構時,也能馬上驗證程式碼的正確性.
  • 撰寫一次測試碼! 之後受用一輩子(or 直到你換公司)!

如何寫測試程式(要怎麼測)? 以下按順序排列:

  1. 基本: 寫些最基本使用程式碼的行為.
  2. 邊界值: 寫些比較極端的使用情況.
  3. 無窮無盡: 利用亂數or程式產生大量使用程式碼的行為,看是否都能正確通過測試.
  4. 效能: 根據 系統時鐘 或是 執行次數 來檢視效能是否為自己預計範圍內的結果.

結論:

測試程式 就和 建構版本 一樣能被自動執行,寫一次就能永遠自動執行,馬上就知道有沒有問題而不是人腦判斷!

測試 會隨著 程式碼 同步演化的! 隨著程式碼加入的新功能,測試也會加上相對應的測試方式.

軟體建構之道 (Code Complete) 第二版 第二十七章到第三十四章心得

軟體建構之道

第二十七章-程式大小對構築的影響

白話的說,專案越大所需要耗費的心力越多,在小專案中認為是理所當然的事,也必須詳細地設計討論才能用於大專案中.

第二十八章-構築管理

要求專案成員寫出具有閱讀性的程式碼.

落後的進度時,加入更多的人力並不會扭轉情勢.

根據統計,程式設計師有30%的時間花在非技術性的活動(Orz).

越尊重程式設計師的公司,越容易得到程式設計師的回報(Orz).

請把程式設計師當人看(Orz).

第二十九章-整合

直接看書卡實在. 跟以前上軟體工程教的東西差不多. Orz

第三十章-程式設計工具

工欲善其事,必先利其器.

第三十一章-配置與樣式

程式設計師工作的一小部份是寫電腦能讀的程式,更大部份是寫人類能讀的程式.

將完成一件工作相關的程式碼集中於同一個段落.

讓大腦用於了解程式如何解決問題的大方向上,而不是花費時間在讀懂運算式,語法...等.

第三十二章-自行紀錄的程式碼

好的註解說明高階的抽象概念,爛的註解就是重複程式碼內容.

使用虛擬碼程式設計流程減輕加上註解的時間.

第三十三章-個性

強烈建議不知道該不該買此書的人,先去書店翻一下這章,心有戚戚焉再敗吧!

程式設計資訊變動的特性,讓"經驗"不在那麼吃香.

第一次學習新事物時,請以正確的方式學習.

程式設計中最重要的工作即是思考,但人在思考時看起來不會有太忙的感覺(被誤認為在混?). 真希望老闆們知道這個道理. Orz

第三十四章-軟體工藝

寫程式給人看,而非寫程式給電腦看.

一次就寫好一個好的程式碼,而不是花很多時間寫一個複雜不好懂的程式碼.

一個專業程式設計師一定寫可讀的程式碼.

一拿到問題就開始狂寫程式碼,然後花更多時間來除錯.  - 這不是聰明的工作方法.

軟體建構之道 (Code Complete) 第二版 第二十章到第二十六章心得

軟體建構之道
這幾章都在討論如何改善程式碼,我心得不太多,應該說重點太多,不知能說啥. Orz

第二十章-軟體品質面貌

使用者關心的是軟體好不好用,而不是程式碼用了哪些驚為天人的設計. (心酸貌)

每項影響軟體品質的參數是會互相抵制的,就跟你老闆要你在最短的時間,最少的人力下,做出效率最高的應用程式.

第二十一章-共同構築

兩個 RD 一起趕一個專案. 雖然書上說好處多多,但我當初被電很慘. 由其一開始沒導入 CVS ,版本的統整根本是惡夢一場.

第二十二章-開發人員測試

RD 自己測自己寫的程式. 這應該是很多 RD 每天都在做的事吧. 我通常只有在重要的子系統部份會做先行測試,先寫出測試程式,等等寫完系統就能馬上測試. 雖然有些人會覺得寫一份 Code 還嫌不夠多嗎? 但說也奇怪,寫完馬上能測還真的怪爽的. 我自己覺得先行測試好處如下:

  • 撰碼前先寫測試程式,不會掉入已經熟悉功能而寫些無關痛癢的測試方法.
  • 以使用這個功能的角度來測試,讓程式的介面更容易被使用(更有模組的感覺).
  • 寫完可測,亂爽一把.
  • 之後修改或重構功能,馬上能用測試程式驗證.

第二十三章-除錯

請利用 Debug 工具,縮小錯誤可能發生的範圍,不要用心電感應來找到錯誤.

花費了大量的時間來除錯,若可以請認命重寫程式碼比較好(尤其是在一大塊爛 Code 中找 Bug).

了解問題所在,才開始修改程式碼. 不要用 +1 不行那我 -1 看看能不能跑的烏龜心態. 這不叫 Debug ,這叫碰運氣!

第二十四章-重整

這章要自己看啊! 書上寫了很多關於需要重整程式碼的線索(比如: 不斷看到相同的程式碼片段...etc). 若確定寫完的 Code 不會再被射回自己臉上者,可跳過此章節.

第二十五章-程式碼微調策略

不要太早最開始最佳化. 你這個月房貸都快繳不出來了,你還在想要買什麼 3C 產品來提升自己的生活品味嗎.

正確的程式比快速的程式重要.

只有經過實際測試,才能得知是否真的最佳化. 沒有數據,一切都是瞎猜!

第二十六章-程式碼微調技巧

就說是微調了,我不知有啥心得啊! 超多~小重點啊!

你是哪種程式設計師?

呆伯特
(圖片來源: http://elielin.chu.jp/blog/bimg/061106.jpg)

原本只是 Code Complete 的一個例子,補充一下應該能補齊所有種類(以下皆轉自書中 Orz).

  • 青澀的理論學家,完全盡信所有讀過的書籍.
  • 經歷過無數艱苦戰役,老學院代表-"真材實料"的程式設計師.
  • 年輕有自信,但卻自命不凡的電腦高手.
  • 厭倦未來空想大餅的資深程式設計師,只想尋找一些有效的做法.
  • 有智慧的老程式設計師.

自己補充(以下才是我想的 Orz):

  • 自命不凡,說的一嘴好 Code 的偽電腦高手.
  • K 完幾本快快樂樂學程式,一招半式就想闖天下的偽程式設計師.
  • 緊抱舊技術,新技術退散的老程式設計師.
  • 寫程式只是為了生活,來一個需求,我就寫一個功能的程式公務員.

最後自我分析:

我是一個青澀的理論學家,只信自己想信的書籍. 年輕無自信,不知未來何去何從的小螺絲釘. 厭倦不切實際天馬行空的需求,只想尋找有效率的做法. 緊抱 JAVA,C 語言退散的程式設計師. 寫程式只是為了生活,但卻有種生小孩的感覺,努力讓每個我生出去的孩子都能長得乾乾淨淨的,別人家的小孩不干我的事(請參考螢火蟲之墓). 我是一個自以為程式設計師的公務員.

歡迎補充. Orz

容易忽略的小事 - 命名

今天 K 了 The Greatest Challenge in Software Development 這篇. 裡頭包含了一些延伸閱讀,有興趣的人可以去看看.

身為一個程式工程師,每天除了看大盤指數和王建民昨晚有沒有拿下勝投外,最常幹的是應該就是替你的程式碼想名字了.

命名就像人每天都要吃飯,不吃飯人活不久,不命名我不知道你要怎麼寫程式. 有人三餐亂吃,身體吃出毛病,也許短期內身體看不出什麼異狀,但長期來看一定是有損健康的.

最常看到的爛變數命名: a1, a2
我實在不知道為什麼工作那麼久的人會寫出這種變數? 難道他知道我要接他的 Code? 還是他度濫我? 還是他寫的 Code 都經過他延腦 Obfuscate 過了?

一樣東西有不同的名字
我知道 "小叮噹" 跟 "哆啦A夢" 是同一個人. 問題是若新加入的成員不看日本漫畫怎麼辦? 若沒有人去解釋這些名字是指同樣的東西,這倒楣鬼可能要花很多時間才知道 "貝吉達" 就是 " 達爾",他們都是指一個額頭很高的賽亞人. 若他沒理解這件事就直接開始寫 Code 的話,那 "七龍珠" 這故事就可能越來越可怕了(變成同人誌 或 番外篇 吧 Orz).

剛本來想找小叮噹的圖來放,找到這張,這張這張. 別人畫的,有興趣自點,我不敢亂放. 我只能說你亂命名就會寫出這種小叮噹. Orz

反正,我只是想說,竟然你天天都要幫程式想名字,何不就學一個好一點的命名方法呢? 萬丈高樓也是平地起,打好基礎也會有好理解的程式碼,不是嗎?

軟體建構之道 (Code Complete) 第二版 第十七章到第十九章心得

軟體建構之道

第十七章-異常控制結構

使用保護子句簡化複雜的錯誤處理

if (checkUserName() == true)
{
  if (checkPassword() == true)
  {
    if (checkBirthday() == true)
    {
      if (checkCertificationPhoto() == true)
      {
        // lots of code.
      }
    }
  }
}

改寫為

if (checkUserName() == false)
{
  /* 可加上錯誤提示. */
  return;
}

if (checkPassword() == false)
{
  /* 可加上錯誤提示. */
  return;
}

if (checkBirthday() == false)
{
  /* 可加上錯誤提示. */
  return;
}

if (checkCertificationPhoto() == false)
{
  /* 可加上錯誤提示. */
  return;
}

/* 通過以上重重考驗才能抵達此處. */
// lots of code.

前者若要加上錯誤提示,又會產生出一堆 else 區塊. 後者則不會降低閱讀性. 不過 return 應該要小心使用就是. Orz

謹慎使用 goto

以下引述自書中:

使用 goto 會違反程式碼應該完全由上而下流動的原則.

我自己在考古別人的程式碼時,也最討厭看到跳來跳去的邏輯,總之謹慎使用會改變程式碼流程的語法.

第十八章-資料表導向法

書上先是舉了個取出每個月天數的範例,與其在程式中寫出以下程式碼:

if (month = 1)
{
  return 31;
}
else if (month = 2)
{
  return 28;
}
...
..(落落長的程式碼)..
...
else if (month = 12)
{
  return 31;
}

不如直接建立一個每月天數的陣列,也就是一個存在於記體的資料表,直接查表就不需要寫出一長串無聊的條件判斷了.

int[] daysOfMonth =
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int daysOfJuly = daysOfMonth[7 - 1]; // 直接查表. 此處可以搬出成一個常式,來處理 -1 的邏輯.

看完這例子,我只覺得超簡單,這樣也能寫成一章. 書上接著舉了一個 "彈性訊息格式" 的範例,我只能說 "我錯了!!",我對這個範例一點 Sence 都沒有啊. 囧rz

有興趣的人請自己翻書來看,以下心得請不要認真看,算是自己解釋給自己看的東西,完全不知道正不正確.

系統內有 20 種資訊格式,因為每種資訊內的欄位都不一樣,書中將 "如何解讀資訊" 的動作包裝出來:
Hard cord: 類似每月取天數的例子,一種解讀資訊的方法就寫在一個 if 裡頭.
OOP: 建立一個解讀資訊的繼承樹,或是使用 Strategy Pattern 來封裝不同的解讀方式.

好戲上場. Orz
資料表:
1. 先定義出欄位會出現哪些型別(int, String...).
2. 利用 1 定義出的型別,建立每種資訊用來解讀的 meta data,系統內會有 20 個這樣的 meta data,這些 meta data 集合就是一個資料表(可以存在檔案內).
3. 建立讀取欄位型別的共用常式.
4. 系統接收到一個資訊,它就根據資訊編號去資料表找出對應的 meta data,然後透過 3 建立的常式就能解讀資訊.

好處是若又有新的資訊,我們不用更動程式碼,只需要在資料表建立新的 meta data. 程式碼變少了,因為都轉成 meta data(但我還是要寫 囧).

我承認,這章我看得超痛苦,我對含有 meta-data 這種例子的東西真的很不行. 我覺得我之後又會忘光光了. Orz

第十九章-一般性控制問題

以隱含的方式將布林式作真及假

不要寫 while (isDone == false) 而寫成 while (!isDone) .
不要寫 while ((a > b) == true) 而寫成 while (a > b).

這樣的好處是不用記太多項數,讀起來也較像是對話式的英文. 不過我忘記我在哪裡看到,最好不要在在條件判斷中使用 "!" .

while (!isDone) // 我看這句腦中是浮現 while ((!isDone) == true) , 反而更亂.
while (isDone == false) // 我很直覺就把 isDone 想成變數,它要等於 false 才會執行.

反而我覺得看個人啦,我思考方式比較像電腦,念起來順不順不重要,我只關心 isDone 是一個變數,它要等於 false 才會執行. Orz

以數線順序編寫數字運算式

(MIN <= i && i <= MAX)
(i >= MIN && MAX >= i)

哪一個看起來比較有感覺? 哪一個一看就知道 i 的範圍?

---- MIN ---- i ---- MAX ----

這樣還看不出來? 那這一個重點你可以跳過. Orz

書上有一段話我覺得很不賴,跟大家共勉之.

寧可努力找出好的解決方法並避開失敗,也不要嘗試找出最佳的解決辦法.

又找到了個偷懶的好理由了. Orz

軟體建構之道 (Code Complete) 第二版 第十四章到第十六章心得

軟體建構之道

第十四章-組織直線碼

讓相依性明顯可見

/* 看不出相依性的例子. */
loadPlayerList();
caculatePlayerAvgHeight();
caculatePlayerAvgWeight();
...

以上程式碼,首先從檔案或資料庫載入球員名單,再算出球員的平均身高跟體重. 如果沒有先執行 loadPlayerList(),那根本沒有辦法算出平均身高跟體重. 對於閱讀的人也不是那麼容易看出相依性的關係.

/* 利用 傳入參數常式命名 讓下一個倒楣的 RD 看出相依性關係. */
List thePlayerList = initPlayerList();  // 使用 init 前置命名.
caculatePlayerAvgHeight(thePlayerList);  // 一定得要有一份球員清單.
caculatePlayerAvgWeight(thePlayerList); // 一定得要有一份球員清單.
...

若真的無法使用比較好的技巧來顯示出相依性 - 最後最後再動用註解.
ex: 在 caculatePlayerAvgHeight() 前附註,使用此方法前必需先呼叫 loadPlayerList().

使用 "接近法則" 來排列陳述式

theBreakfast.getPrice();
theLunch.getPrice();
theDinner.getPrice();
theBreakfast.getCalories();
theLunch.getCalories();
theDinner.getCalories();
theBreakfast.getProtein();
theLunch.getProtein();
theDinner.getProtein();

換成

theBreakfast.getPrice();
theBreakfast.getCalories();
theBreakfast.getProtein();

theLunch.getPrice();
theLunch.getCalories();
theLunch.getProtein();

theDinner.getPrice();
theDinner.getCalories();
theDinner.getProtein();

眼睛是不是比較舒服? 把相關的陳述式歸類在一起,不確定這樣編排對不對? 問你的眼睛就知道了.

第十五章-使用條件式

case 陳述式請避免省略 break

switch(theParam)
  case 1:
    boo();
    break;
  case 2:
    foo();
    break;
...

我知道這是超基本的東西,但我就碰到過. 所有流程看都沒問題,但就是有問題,最後找出來問題所在,也想順便把前輩找出來鞭一輪. 養成寫作好習慣,才不會犯這種基本錯誤.

盡量不要在 case 陳述式中利用 break 來操作流程

switch(theParam)
  case 1:
    boo(); // 如果 theParam = 1 就會執行 boo() 跟 foo().
  case 2:
    foo(); // 如果 theParam = 2 就只會執行 foo().
    break;
  case 3:
    gotoHell(); // 如果 theParam = 3 就會執行 gotoHell().
    break;
...

其他人得花時間去了解程式的邏輯,事後修改也可能發生預期外的錯誤. 若你想下地獄,自己去就好,不要推別人下去. Orz

第十六章-控制迴圈

小心使用 Break 和 Continue

請確定你知道 Break 和 Continue 的定義,要不請不要亂用. 使用太多 Break 或 Continue 也會增加迴圈的複雜度,請謹慎用之.

Break: 結束迴圈,程式繼續執行迴圈後的第一行.
Continue: 跳過此次迴圈,程式回到迴圈下次重覆的開始處執行.

什麼還是不懂? 請去翻書,一個好的程式設計師,不懂就去搞懂.

由內而外建立迴圈

以下引述:

先從具體處著手,一次考慮一樣東西,然後採由簡入繁的方式建立迴圈.

我覺得我亂說反而會誤導人(因為我寫迴圈都由外而內建立),大家去翻書看看,我覺得在面對複雜迴圈邏輯時,這是很好的寫作及思考方式.

這三章都在描述程式碼的流程,我只針對我比較有感覺(有慘痛經驗)或之前沒注意的部份寫心得.

軟體建構之道 (Code Complete) 第二版 第十二章到第十三章心得

軟體建構之道
第十二章-主要資料型別
本章在說明使用 int, float, ... 這些資料型別的注意事項..
很多小重點..
我只紀錄一下對我寫程式比較有幫助的..
有需要自己去書店翻一下..

使用布林變數簡化複雜的測試..

if ((eatBreakfast() && eatLunch() && eatDinner()) || (hasHeadache() || hasStomachache()))
{
}

上面看完應該眼睛都花了..
你應該開始會想 "我會在需要的時候弄懂這段程式碼在做啥" ..
其實我上面例子想表達的是..
如果 三餐都有吃 或者 身體哪裡不舒服 的話再去做區塊內的事..
而不改寫成..

boolean eatMeals = ((eatBreakfast() && eatLunch() && eatDinner());
boolean isSicked = (hasHeadache() || hasStomachache());

if (eatMeals || isSicked)
{
}

這樣不就清楚多了..

避免常值即便是安全的常值..
就算你知道打籃球最多同時上場 5 個人..
程式碼中最好還是使用 具名常數 來取代 5..

private int final MAX_PLAYERS_COUNT = 5;
...
public void checkPlayerOnCourt(int inPlayerOnCourt)
{
  if (inPlayerOnCourt > MAX_PLAYERS_COUNT)
  {
    // 判技術犯規.
  }
}

另外這樣你程式中也避免掉到處都有 "5" 這個魔術數字的問題..

如果是多維陣列請考慮用比 i 和 j 更有意義的名稱..
比如 Array[i][j][k] 考慮改成 Array[長][寬][高] 之類的..
要不改成 Array[ptrX][ptrY][ptrZ] 也比較不會弄錯(但還是不夠好)..
總之轉成現實中對應的物件而不是電腦程式的術語..

第十三章-異常資料型別
本章比較著墨在 結構 和 指標 上面..
我總覺得 JAVA 的 類別 就含蓋掉 結構 的部份了..
另外寫 JAVA 也不會處理到指標.. Orz
不過我還是乖乖看完了..

使用結構簡化參數清單..
直接拿書上例子..

addEmployeeData(name, address, phone, ssn, gender, salary)

如果我們直接包裝出一個員工結構(員工包含 name, address, ...)..
那這一大串參數就可以變成..

addEmployeeData(employee) // 參數簡化成一個員工結構.

這樣做的優點有..
1. 不用去記參數的順序..
2. 之後若參數增減也不用修改常式的參數介面(當然還是要修改常式裡的程式碼)..
缺點則是..
1. 增加耦合度..
之後要使用到此常式也必須知道 員工結構 這個東西..
所以結論是..
程式設計師要自行判斷哪種情況適合 建立新的結構來簡化參數清單 ..
用到的參數數目夠多 -> 直接傳入結構
用到的參數數目少 -> 直接傳入基本資料型別的參數

使用抽象概念層級來存取指標..

node = node.next <-> account = NextAccount(account)
event = eventQueue[queueFront] <-> event = HighestPriorityEvent()

右邊的作法 將原本的程式碼抽像化成一個常式..
對我來說..
比較好閱讀..
且可以重複利用常式 而不是 到處都看到 event = eventQueue[queueFront] 這種東西..

這兩章..
我看得有點辛苦.. Orz

軟體建構之道 (Code Complete) 第二版 第十章到第十一章心得

軟體建構之道
第十章-使用變數的一般問題
變數有效的時間越短越好..
要使用時才宣告定義..
使用該變數的程式碼集中在一起..
原因無它..
就是增加閱讀性..
你不用擔心是不是別的地方會去修改到該變數..

跨距越短越好..
跨距就是同一個變數下次出現之間隔的行數..

int a = 0;
int b = 1;
a = a + b; // a 的跨距為 1.

其實觀念同上..
反正你就想你家冰箱會去冰箱拿飲料的就家裡那幾個人..
遭小偷我不知該如何解釋 Orz..
若你家冰箱擺在馬路上..
你想要是哪個路人幹了你家飲料就比較麻煩了..

避免變數有隱藏的意義..
比如..

int thePlayerCount; // 球員數目.

thePlayerCount 就專心至力於紀錄球員數目就好..
不要搞個..

int thePlayerCount; // 球員數目,若為-1代表籃球社倒了.

一個變數就專心做一件事就好了..
這種偷吃步..
都是爽一時..
一痛就痛到你離職換公司..
再痛到下一個倒楣 RD 身上而已..

書中一句話個人覺得很實在..

僅可能保持變數的區域性,因為區域範圍有助於智慧管理.

這章也很實用..
建議入手可先翻一翻..
小小習慣大大改善..

第十一章-變數名稱的力量
這章大至說明一些慣例..
幾個熱門的語言也有命名的表格供參考..
關於縮寫也有幾個不錯的規則(命名太長一直是我的痛處 Orz)..

命名要清楚..
不要亂加入數字..
...
(超多請自己去書店翻)

這章適合..
還沒有建立起自己命名習慣的人..
覺得 Review 自己 Code 會產生閱讀障礙的人..

變數命名這種事都說起來簡單..
有心的人就是有心..
沒心的人就還是 x1, x2, temp 照樣給你寫一堆啦..
又想到我那用 JAVA 寫 C 風格的前輩了.. Orz
不知道他現在過得好不好..
快轉行吧你..

軟體建構之道 (Code Complete) 第二版 第九章心得


軟體建構之道
第九章-虛擬碼程式設計流程
虛擬碼程式設計(PPP, Pseudocode Programming Process)..
簡單說明就像是寫一篇作文..
先訂好大綱..
在根據大綱來寫出每章節的內容..

對應到寫程式..
作文 <-> 常式
大綱 <-> 虛擬碼
每章節的內容 <-> 實作的程式碼

這樣做的好處有..
比較高的層次切入而非一頭栽入程式碼中..
而後..
虛擬碼也能轉換成程式中的註解..

對我來說..
從比較高階的層次切入我就不用先去管要用哪些語法去實作..
虛擬碼之後就可以直接拿來當註解..
比我整個程式碼都寫完再來寫註解的那種不得不做的感覺來得好太多了..

以下則是其他我比較有印象的部份..

當虛擬碼所需要的實作程式碼行數超乎預期..
請將這些程式碼集中建立一個新的常式..

請懷疑自己的程式碼..
根據書中提供的數據..
只有大約 5% 的錯誤來自硬體,編譯器和 OS..
看來 "為何在我電腦上可以跑" 這句經典名言是最好少用.. Orz

以下這句新名詞還蠻屌的..
大鍋炒編譯: 大鍋炒 -> 來編譯 -> 修到正
程式碼東拼西湊..
混在一起 Compile 看看能不能跑..
有錯在修..
重新 Compile..
(以下重複)

還好我還沒有這種問題.. Orz
我只是在不穩的房子上面加蓋危樓而已(遠望狀)..

最後一段書裡的話自己要記住..

埋頭苦幹通常代表不完整的認知..
而且也是現在和未來必然出錯的保証..
重新設計錯誤的常式絕對值回票價..

這章建議有買的人可以先看..
實用度蠻高的..

軟體建構之道 (Code Complete) 第二版 第八章心得

軟體建構之道
今天都在解 Bug ..
所以也是低一下看一下..
反正只是寫寫心得..
非專業分享.. Orz
說不定有人看了就會去買這本書..
除了勸敗外我這樣也算對台灣軟體產業盡一份微薄的心意啊.. Orz

第八章-防禦性程式設計
之前看 Head First 系列稍微有點印象..
就你所有的常式傳入的參數你都給他檢查一遍..
不管他看起來像不像男生..
你都還是要給他檢查下去..
不過書裡頭當然不像 Head First 那麼簡單只給個大方向啦..

建立一層專門驗證的 Level(路障,防火牆)在外部與內部類別之間..
有點像 Facade 模式..
但我以前從沒想到這樣做..
沒設計就直接在 View 的層次就開始驗證了..
不好的習慣..
好 RD 不要學..

其他大部份就是編寫程式中的實際範例啦..
對我來說可能比較有感覺的就是..
接到低階例外要丟出高階例外以符合架構上的抽像概念..
若接到例外不處理也要在程式碼中說明..
這兩點我比較常用到..

喇賽完了..
看到 220+ 頁..
還有快 700 頁待看.. Orz

軟體建構之道 (Code Complete) 第二版 第一章到第七章讀書心得

軟體建構之道
前陣子因為 老涂的咁仔店: 軟體業界有救了?! 這一篇得知了這本書..
自認還是新手的我(新手愛買書)就上網訂了一本回來..
反正我最近應該很閒..
乾脆寫寫心得..
但應該都是寫我犯過的錯..
或是我有興趣的重點或笑話..
想要一窺書中精華的人..
還是去買一本回家慢慢啃吧..
900多頁真的是要用啃的..

第一章-歡迎加入軟體建築的行列
寫 Code 請經過大腦..
事前要設計..
一開始你認為節省的時間..
後來很可能都會乘上一百倍又射在你臉上..

第二章-用隱喻角度探討軟體開發
其實這章我覺得比較像..
如果跟不懂的人或者是你老闆(你有種的話)解釋為何需要花時間設計的理由..
寫程式就像蓋房子..
我覺得很有道理..
試想想你敢買一間完全沒有設計圖..
建商直接叫工人直接蓋起來的房子嗎..
更屌的是蓋到一半又告訴你一樓隔間全部打掉要改成停車庫..
這種房子沒有人敢買..
但是這種程式倒是許多不 Care 的人在用..

第三章-三思而後行:上游的前置作業
先不論設計..
開始編寫程式時最好是能充份了解客戶的需求..
小弟我最近才發生過..
整個功能我都寫好了..
老闆隔週竟完全翻盤..
變成了一個完全不同的需求..
還好這塊我有獨立挖出來編寫..
要不應該又是幹了吃力又沒薪水多拿的苦差事..
反正我覺得 了解客戶需求 > 設計..
你在女廁蓋個容易抽換的小便斗是有屁用..

第四章-重要構築決策
這章在介紹各種程式語言..
而我最有印象的只有"程式設計語言影響程式設計人員很大"..
他舉了一個例..
原本都在寫 Fortran 的工程師正以 C++ 編寫新系統..
但卻是經過偽裝的 Fortran.. 囧rz
個人深受 Turbo J 的荼毒很久了..

第五章-構築的設計
為何要做設計..
除了為了因應未來的變化外..
最主要就是要降低複雜度..
世上應該多少人能掌握整個專案的所有細節吧..
若在開始編寫時就將整個專案模組化..
我們不但對系統能有各概念化的認識..
同時也分解了原本很複雜龐大的工作..
反正你要一頭栽進泥沼是你家的事..
不要連累到我就好.. 囧rz

第六章-工作類別
這章已經進入實際編寫階段..
就是書上已經可以看到範例程式碼了.. Orz
關於類別..
看下來我都沒啥犯錯的地方..
反正不外乎是..
封裝類別內的成員..
內聚力要高(類別內是否都是做一致的事情)..
藕合力要低(類別與其它類別的關聯性)..
"繼承"只有兩種使用方式:小心使用,以及禁止使用..
我自己是覺得..
有時候就是懶或是寫昏頭..
反正最後出包倒楣的還是自己(或是接你包的人).. Orz
上面..
誰 Care 這個勒..

第七章-高品質常式
先說一下常式就始類別裡的方法(我自認為)..
這章零星的重點很多..
我覺得要自己親自去看..
發現"原來不能這樣喔"的效果會比較好..
反正最大兩重點就是..
常式命名要清楚..
林北改人家扣就看過..
方法名稱 - doSomething(int inValue);
當下真想幹他祖宗十八代..
度喪心..度..度林娘親..
個人覺得這真的是 RD 最不道德的行為之一..
還有會這樣寫的人通常也不會寫註解(幹)..
將複雜的步驟包裝成一個常式..
比如說你今天要去大便..
你要先..
脫外褲();
脫內褲();
拉大便();
擦屁股();
穿內褲();
穿外褲();
若你程式三不五時就要你去大便 若 你又超愛用 Copy & Paste..
你程式碼到處都有以上6個的呼叫區段..
其實你就直接包裝進一個新的常式(叫去上大號()好了)..
這新的常式會去呼叫以上六個常式..
看你程式的人也比較不吃力..
對你 上大號() 有興趣的人在點進去看就好了..
另外也比較好修改..
像我上面少打了 沖水();
你用 CP 大法..
那你就慢慢找出來改吧..
若都包裝成一個常式了..
改一個地方全部搞定..
這章節我比較有印象的錯誤只有..
不要修改常式傳入的參數..
之前就是為了一個類似的 Bug (前輩寫的)..
花了我兩到三天的時間..
現在想起來頭皮就發麻..

以上拉拉雜雜寫一堆..
主要是自己放 Pi 一下也比較有印象..
看完的人有興趣去書店翻翻書吧.. Orz
之後章節有看就會寫..