軟體工程的目標是將工程學的嚴謹方法應用於軟體開發,提升團隊效率和程式碼品質。然而,過於強調規則可能限制程式設計師的創造力。卓越的程式設計師懂得在遵循規範與創新突破之間取得平衡,他們熱愛程式設計,持續學習新知,並能跳脫框架思考。本文分析程式設計師如同藝術家、建築師、工程師和工匠等不同角色的隱喻,並深入研究軟體工程與個人軟體工程的實踐方法,探討如何寫出優秀的程式碼,並強調良好道德品質的重要性。

軟體工程與卓越程式設計師

在工程領域中,工程師通常遵循一套既定的規則來解決特定的問題,並結合預先確定的解決方案來構建自定義的解決方案。這種方法使即使技術能力較弱的工程師也能在不必從頭開始開發系統的情況下產生有效的解決方案。軟體工程的出現正是為了透過將傳統的工程概念應用於軟體開發,從而最大化整個程式設計團隊的價值。總體而言,軟體工程革命在很大程度上是成功的。接受過適當培訓並擁有優秀長官的軟體工程師能夠比以往更快、更經濟地生產出高品質的程式碼。

純軟體工程的侷限性

純粹的軟體工程方法往往抑制了發散性思維,因為這種思維方式可能會浪費時間,並使工程師偏離成功的道路,從而導致開發成本增加和開發時間延長。一般來說,軟體工程更關注的是按時並在預算內開發應用程式,而不是以最佳方式編寫程式碼。但是,如果軟體工程實踐者從不嘗試新的方法,他們往往會錯失創造出色設計的機會,也永遠無法開發出新的實踐方法來豐富他們的規則手冊,更無法成為優秀的程式設計師。

卓越程式設計師的特質

卓越的程式設計師不僅意識到預算問題的重要性,同時也明白探索新思想和新方法對於推動該領域的發展至關重要。他們知道何時應該遵循規則,何時可以打破(或至少彎曲)這些規則。更重要的是,卓越的程式設計師能夠充分發揮他們的技能,取得那些僅憑遵循常規無法實作的成果。駭客是天生的,軟體工程師是後天培養的,而卓越的程式設計師則兼具兩者的特質。他們具備三個主要的特徵:對工作的真摯熱愛、持續的教育和培訓,以及在解決問題時能夠跳出框架思考的能力。

熱愛所做之事,做到所愛之事

人們往往在他們喜歡的事情上表現出色,而在他們不喜歡的事情上表現糟糕。歸根結底,如果你討厭電腦程式設計,你就不會成為一個優秀的電腦程式設計師。如果你不是天生具有解決問題和克服挑戰的渴望,那麼再多的教育和培訓也無法改變你的性情。因此,成為一名優秀程式設計師最重要的先決條件是,你真的很喜歡編寫電腦程式。

持續教育和培訓

優秀的程式設計師喜歡該領域所需的工作型別,但他們還需要其他東西——正式的教育和培訓。我們將在後面的章節中更深入地討論教育和培訓,但現在只需說,優秀的程式設計師都受過良好的教育(可能擁有大學學位),並且在整個職業生涯中不斷繼續教育。

跳出框架思考

正如前面提到的,遵循一組預先確定的規則來生成程式碼是對軟體工程師的典型期望。然而,正如您將在第1章中看到的那樣,要成為一名優秀的程式設計師(“大師級程式設計師”),您需要願意並且能夠設計出新的程式設計技術,這些技術源於發散性思維,而不是盲目地遵循規則。優秀的程式設計師具有突破界限和探索新的解決方案來解決他們面臨的問題的天生慾望。

成為優秀程式設計師的必備條件

總而言之,如果你想成為一名真正優秀的程式設計師,並讓你的同行對你感到敬畏,你需要具備以下條件:

  • 對電腦程式設計和問題解決的熱愛
  • 根據大學學位或同等自學所獲得的廣泛電腦科學知識
  • 終身致力於教育和培訓
  • 在探索解決方案時能夠並願意跳出框架思考
  • 始終追求卓越並產生最佳作品的個人慾望和動力

具備這些特質後,唯一阻礙你成為優秀程式設計師的就是更多的知識。這正是這本文所要提供的。

道德與品格的重要性

軟體工程師的工作是在相互衝突的需求之間找到平衡,透過在系統設計中做出適當的妥協來創造出最佳產品。在這個過程中,工程師必須優先考慮需求,並在專案的約束條件下選擇最佳的解決方案。道德和個人品格往往會影響個人在處理複雜專案(尤其是壓力大的專案)時的決策。知識上的不誠實(例如,篡改專案估計或聲稱某個軟體在未經充分測試的情況下可以運作)、盜版軟體開發工具(或其他軟體)、在未經管理階層批准的情況下在軟體中引入未記錄的功能(例如後門),或者採取精英主義態度(認為自己比其他團隊成員更優秀)都是軟體工程倫理上的失誤。實踐良好的道德判斷力和良好的道德品質,不僅會使你成為一個更好的人,也會使你成為一個更好的程式設計師。

更多資訊來源

Barger, Robert N. Computer Ethics: A Case-Based Approach. Cambridge, UK: Cambridge University Press, 2008.

Floridi, Luciano, ed. The Cambridge Handbook of Information and Computer Ethics. Cambridge, UK: Cambridge University Press, 2010.

Forester, Tom, and Perry Morrison. Computer Ethics: Cautionary Tales and Ethical Dilemmas in Computing. 2nd ed. Cambridge, MA: MIT Press, 1993.

Parker, Donn B. “Rules of Ethics in Information Processing.” Communications of the ACM 11, no. 3 (1968): 198–201. https://dl.acm.org/doi/10.1145/362929.362987.

Wiener, Norbert. The Human Use of Human Beings: Cybernetics and Society. Boston: Houghton Mifflin Harcourt, 1950.

WikiWikiWeb. “Grand Master Programmer.” Last updated November 23, 2014. http://c2.com/cgi/wiki?GrandMasterProgrammer/.

第一部分:個人軟體工程

如何定義軟體開發過程?

這似乎是一個愚蠢的問題。為什麼不乾脆說“軟體開發就是軟體開發”然後就此打住呢?好吧,如果我們能在軟體開發任務和其他專業活動之間找到類別比,我們就能深入瞭解軟體開發過程。然後,我們可以透過研究相關領域的流程改進來改進軟體開發過程。為此,本章探討了一些理解軟體開發的常見方法。

1.1 什麼是軟體?

為了更好地理解程式設計師如何建立軟體,我們可以將軟體與人們創造的其他東西進行比較。這樣做將為我們提供重要的見解,說明為什麼某些創造性的隱喻適用或不適用於軟體開發。

此圖示說明瞭軟體開發過程的基本組成部分,包括建立軟體、比較與其他創造物以及遵循既定規則等步驟。

軟體開發的不同隱喻

本章將探討不同的隱喻,以幫助我們更好地理解軟體開發過程。透過將軟體開發與其他創造性活動進行比較,我們可以獲得新的視角,從而改進我們的開發流程。

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

title 卓越程式設計師的養成之道

package "系統架構" {
    package "前端層" {
        component [使用者介面] as ui
        component [API 客戶端] as client
    }

    package "後端層" {
        component [API 服務] as api
        component [業務邏輯] as logic
        component [資料存取] as dao
    }

    package "資料層" {
        database [主資料庫] as db
        database [快取] as cache
    }
}

ui --> client : 使用者操作
client --> api : HTTP 請求
api --> logic : 處理邏輯
logic --> dao : 資料操作
dao --> db : 持久化
dao --> cache : 快取

note right of api
  RESTful API
  或 GraphQL
end note

@enduml

此圖示展示了三種不同的隱喻,分別對應結構化方法、創造性表達和探索與創新。

此圖示說明瞭成為優秀程式設計師所需的關鍵要素,包括具備相關知識和技能、良好的道德品質以及不斷學習的精神。

軟體開發的特性與挑戰

軟體工程的基礎在於理解軟體的本質及其開發過程中的獨特挑戰。Robert Pressman在其著作《Software Engineering: A Beginner’s Approach》中,闡述了軟體的若干關鍵特性,這些特性不僅揭示了軟體的本質,也定義了軟體工程師的工作內容。

軟體非製造業

軟體是被開發或設計出來的,而不是傳統意義上的製造產品。相較於硬體產品,軟體的製造成本極低:一張CD或DVD的製造成本僅需幾分錢,加上運輸和處理的費用也相當有限(電子發行甚至更為便宜)。此外,軟體設計對最終產品的品質或成本影響甚微。假設製造廠商具備合理的品質控制,軟體工程師在設計應用程式時很少需要考慮製造問題。

軟體不會損耗

軟體和硬體都會因早期設計缺陷而導致故障。然而,如果能夠消除產品中的設計缺陷(即交付無缺陷的軟體或硬體),兩者之間的差異就顯現出來了。一旦軟體正確無誤,它就不會失敗或「損耗」。只要底層的電腦系統運作正常,軟體就會持續運作。與硬體工程師不同,軟體工程師不需要擔心設計時要考慮到元件隨時間失效的更換問題。

大多數軟體是客製化的

大多數軟體是客製化開發的,而不是由現有的標準元件組裝而成。雖然人們曾多次嘗試創造標準化的軟體元件,以便軟體工程師能夠將其組裝成大型應用程式,但「軟體積體電路」的概念始終未能實作。軟體函式庫和物件導向程式設計技術鼓勵了對預先編寫程式碼的重複使用,但從較小的預元件構建大型軟體系統的概念尚未達到硬體設計所能達到的水平。

程式碼範例:模組化設計

# 定義一個簡單的模組化函式
def greet(name: str) -> str:
    """傳回一個問候訊息"""
    return f"你好,{name}!"

# 使用該函式
print(greet("玄貓"))

內容解密:

  1. def greet(name: str) -> str: 定義了一個名為 greet 的函式,該函式接受一個字串引數 name 並傳回一個字串。
  2. return f"你好,{name}!" 使用了 Python 的 f-string 功能,將 name 變數嵌入到字串中,生成一個個人化的問候訊息。
  3. print(greet("玄貓")) 呼叫 greet 函式並列印結果,展示瞭如何使用該模組化函式。

軟體易於升級

在許多情況下,可以在現場完全替換現有的軟體應用程式,而無需付出巨大的成本。使用者只需將舊軟體替換為新版本,即可享受升級帶來的好處。事實上,大多數現代軟體系統和應用程式都能在正常運作期間透過網路自動更新。

軟體非獨立實體

軟體並非獨立的產品。雖然電機工程師可以設計出能夠獨立運作的硬體裝置,但軟體必須依賴其他東西(通常是電腦系統)才能正常運作。因此,軟體開發者在設計和實作應用程式時,必須遵守外部系統(如電腦系統、作業系統、程式語言等)所施加的限制。

與其他領域的類別比

電腦程式設計師常被比喻為藝術家、工匠、工程師、建築師和技術人員。雖然電腦程式設計與這些職業並不完全吻合,但我們可以從這些領域中汲取有用的類別比和技術洞察。

程式設計師作為藝術家

在電腦程式設計的早期,軟體開發被視為一種藝術。只有少數人具備將混亂的資訊轉化為可運作程式的天賦,就像大師級的畫家或音樂大師一樣。有趣的是,有許多傳聞表明音樂家和電腦程式設計師在進行創作活動時使用的是腦部相同的區域。

然而,軟體開發是否真正是一種藝術形式呢?藝術家通常被定義為具備某些天賦並能夠以創造性的方式運用它們的人。關鍵字在於「天賦」,即一種自然的能力。因為並非每個人都具有相同的天賦,所以並非每個人都能成為藝術家。若將此類別比套用於程式設計,似乎意味著如果你想成為一名程式設計師,你必須天生具備這種能力;確實,有些人似乎天生就具有程式設計的天賦或才能。

軟體開發的隱喻:程式設計師的多重角色

軟體開發的過程可以透過不同的隱喻來理解和描述。這些隱喻幫助我們更深入地瞭解程式設計師在軟體開發中的角色和責任。

程式設計師作為藝術家

將程式設計師比喻為藝術家,尤其適用於那些頂尖的程式設計師。藝術家遵循一套規則來創作高品質的作品,但往往在突破規則、探索新的創作領域時,創造出最傑出的作品。同樣地,優秀的程式設計師熟悉良好的軟體開發規則,但也願意嘗試新的技術,以改進開發過程。正如真正的藝術家不滿足於重複現有的作品或風格,「程式設計師作為藝術家」更樂於創造新的應用程式,而不是機械地重複舊有的版本。

值得注意的是,唐納德·克努斯(Donald Knuth)的《電腦程式設計藝術》(The Art of Computer Programming)是電腦科學領域中備受尊敬的教科書系列。這表明,將程式設計視為一種藝術形式的觀念在電腦科學領域中根深蒂固。

程式設計師作為建築師

對於小型專案,「程式設計師作為藝術家」的比喻很合適,因為藝術家創造了想法並實作了作品,就像程式設計師設計和實作了一個小的軟體系統。然而,對於較大的軟體系統,「程式設計師作為建築師」的比喻可能更合適。建築師設計結構,但將實作交給他人(因為通常一個人無法完成整個建設)。在電腦科學中,那些為他人設計系統以供實作的人通常被稱為程式設計師/分析師。

建築師對專案進行大規模的創意控制。例如,設計一座華麗建築的建築師定義了它的外觀、使用的材料以及施作業員員遵循的指導方針,但不直接參與施工。建築師可能會監督建設過程(就像程式設計師/分析師會審查他人新增到他們軟體系統中的模組一樣);然而,建築師不直接操作工具或機器。

這種比喻同樣適用於小型專案,只要允許個人「轉換角色」。也就是說,在專案的第一階段,程式設計師戴上建築師/程式設計師/分析師的帽子,建立系統的設計。然後,程式設計師轉換角色,戴上程式設計師/編碼員的帽子來實作系統。

「程式設計師作為建築師」的正規化比「程式設計師作為藝術家」模型多了驗證和安全措施。當藝術家繪畫、作曲或雕塑時,他們通常不需要擔心作品是否符合任何要求,除了自己的審美標準。同時,他們也不需要擔心作品是否會對生命或財產造成物理傷害。

另一方面,建築師必須考慮物理現實,以及糟糕的設計可能導致傷害或損害的事實。「程式設計師作為建築師」的正規化將個人責任、審查(測試)和安全性引入了程式設計師的任務中。

程式設計師作為工程師

1968年,北約(NATO)會議挑戰了好的程式設計師是天生的而非後天造就的觀念。如同本文中提到的,當時世界正面臨軟體危機——新的軟體應用需求增長速度超過了程式設計師培訓的速度。因此,北約贊助了1968年的會議,提出了「軟體工程」這個術語,以描述如何透過將工程原理應用於混亂的電腦程式設計世界來解決這個問題。

工程師關注的是以成本效益的方式解決實際問題,無論是在設計工作還是在生產成本方面。由於工程專業已經存在很長時間(尤其是機械和化學工程),多年來,工程師制定了大量的程式和政策來簡化他們的工作。

在許多工程領域中,今天工程師的任務是從較小的預先設計的構建塊中構建大型系統。想要設計電腦系統的電氣工程師不會從自定義電晶體或其他小型元件的設計開始;相反,他們使用預先設計的CPU、記憶體元件和I/O裝置,將它們組裝成一個完整的系統。同樣,機械工程師可以使用預先設計的桁架和基座來設計一座新橋。設計重用是工程專業的標誌,也是盡快生產出安全、可靠、功能性且具成本效益的設計的關鍵要素之一。

軟體工程師同樣遵循一套明確定義的程式和政策,從較小的預定義系統中構建大型系統。事實上,電氣和電子工程師學會(IEEE)對軟體工程的定義如下:

對軟體開發、營運和維護採用系統化、規範化、可量化的方法;也就是將工程應用於軟體。

程式設計師作為工匠

工匠模型介於藝術家和工程師之間。這個正規化的核心思想是將程式設計師視為個人;也就是說,軟體工匠的隱喻承認了人的重要性。在問題上投入更多的人手和嚴格的規則並不能產生更高品質的軟體,但更好地培訓個人並讓他們發揮自己的天賦和技能則可以。

傳統工匠的發展過程與軟體工匠的發展過程有相似之處。像所有工匠一樣,軟體工匠從學徒或實習生開始。學徒在另一位工匠的密切指導下工作。學習了一段時間後,學徒程式設計師成為一名熟練工匠,通常在資深軟體工匠的監督下與其他程式設計師團隊合作。最終,程式設計師的技能提高到足以成為一名大師級工匠

內容解密:

本章節主要探討了四種不同的隱喻,分別是「程式設計師作為藝術家」、「程式設計師作為建築師」、「程式設計師作為工程師」以及「程式設計師作為工匠」。這些隱喻分別對應不同的開發模式和思維方式,並且每個隱喻都有其特定的適用場景和優缺點。

程式碼範例與解析

def example_function():
    # 定義一個簡單的函式來示範基本的程式結構
    print("這是一個範例函式")

# 呼叫函式
example_function()

內容解密:

  1. def example_function(): 定義了一個名為 example_function 的函式,這是 Python 語言中定義函式的基本語法。
  2. print("這是一個範例函式") 在函式內部輸出一句話,這裡使用了 Python 的 print 函式來實作輸出功能。
  3. example_function() 呼叫剛剛定義的函式,這是執行函式內部程式碼的方式。

此範例展示了 Python 中定義和呼叫函式的基本方法,同時也體現了軟體開發中對於程式碼重用模組化的思想。

軟體開發的隱喻與工程方法

撰寫出色的程式碼需要了解什麼是「好」的程式碼,並使用最佳工具、技術、程式和政策。在軟體開發過程中,不斷增進知識和改進開發流程至關重要。本章節將探討不同的軟體開發方法,理解軟體產品的特性,並選擇最合適的方法。

藝術家、建築師、工程師還是工匠?

要成為偉大的軟體開發者,需要從藝術、建築、工程和工匠等領域汲取有用的理念,並摒棄無效的方法。簡單來說:

  • 藝術家透過練習來發展技能,並進行發散性思維以探索新的表達方式。
  • 建築師利用現有的設計和標準元件來創造客製化的產品,同時考慮成本、安全性、需求和可靠性。
  • 工程師重視一致性,透過檔案化和自動化開發步驟來提高效率,並鼓勵重用現有的設計以提供更強健和經濟的解決方案。
  • 工匠在師傅的指導下訓練和練習技能,目標是成為大師,強調個人在問題解決和組織能力上的品質。

軟體工程

自1960年代末期誕生以來,軟體工程已經取得了巨大的成功。如今,很少有專業程式設計師會接受該領域初期的「標準做法」。現代程式設計師理所當然地接受的概念,如結構化程式設計、適當的程式佈局(例如縮排)、註解和良好的命名政策,都歸功於軟體工程的研究。

軟體工程的正式定義

對於軟體工程的定義眾說紛紜,不同作者有不同的「詮釋」。IEEE定義軟體工程為: 「對軟體開發、運作和維護採用系統化、紀律化、可量化的途徑;也就是將工程應用於軟體。」 本文使用的定義是: 「軟體工程是研究大型軟體系統的開發與管理。」 關鍵字在於「大型」。大多數軟體工程的研究都與非常龐大的系統相關,因此這個定義更符合實際情況。

個人軟體工程

為了避免與通用術語「軟體工程」混淆,本文使用了一個更專門的術語——「個人軟體工程」,來描述適用於單一程式設計師在小型專案或大型專案中的小部分工作的流程和方法。這樣可以更專注於程式設計師認為的軟體工程的精髓,而不會陷入與寫出色程式碼無關的細節中。

「大型」系統的認知差異

不同的人對「大型」系統的認知差異很大。電腦科學的本科生可能認為幾千行原始碼就是一個大型系統,而波音公司的專案經理則會有完全不同的標準。