技術雜談:適合初學者的小型專題

PUBLISHED ON JUL 1, 2017

    前一陣子,在某個程式設計討論區上,看到有網友在討論不知道在學完程式語言後,可以寫什樣的專案 (project) 來增進自己的功力。的確,在學習程式設計一段時間後,會碰到這樣的困擾。由於這種針對進階初學者的書較難掌握讀者的程度,實際上這種書也比較少。對於進階初學者來說,一下子跳進去看 GitHub 或其他站台的中大型專案又難度過高,要在茫茫大海中找到適合自己程度的專案也不容易。筆者提出一些個人的見解,供有需要的網友參考。

    其實,選擇專案沒有那麼困難,從使用者的角度來思考即可。首先,可以思考一般使用者 (end user) 會使用的軟體 (software) 類型,再從中選擇即可。一般使用者會使用到的軟體類型如下:

    • 命令列工具 (command line utility)
    • 桌面軟體 (desktop application)
    • 網頁軟體 (web application)
    • 行動軟體 (mobile application)
    • 電腦遊戲 (computer game)

    接下來,本文會從開發者的角度逐一介紹上述各種應用程式。

    命令列程式是最基本的,幾乎每個程式設計初學者都會寫一些命令列程式。微軟 (Microsoft) 的 cmd.exe 經過多年改變很少,後來又另外出了一套 PowerShell,看起來微軟的 cmd 命令列環境大概就是保持著介於 maintaince 和 legacy 之間的狀態。許多程式設計者會忽略命令列程式,但在 GNU/Linux 伺服器和桌面,仍然大量使用命令列環境,有新的命令列程式問世,原有的程式也繼續維護著。其實,如果不在意命令列程式看起來簡單,命令列程式相當適合練功,因為命令列環境的輸出入單純,只有標準輸入 (standard input)、標準輸出 (standard output)、標準錯誤 (standard error) 三種,程式設計者可專心在功能面的開發。

    由於現在的桌面系統 (desktop OS) 都有圖形化使用者介面 (GUI),一般人心中的軟體就是桌面軟體。但其實桌面軟體的設計較複雜,因為桌面環境不像命令列環境有制式的輸出入,而需由程式設計者重新設計使用者介面;要達到等效的功能,撰寫桌面軟體會比命令列軟體需要更長的時間。為了簡化開發,有許多開發軟體提供 RAD (Rapid Application Development) 開發模式,其中就有快速生成使用者介面的功能;但這種功能很容易被初學者誤用,寫出使用者介面和核心功能糾結在一起 (高耦合) 的軟體。比較好的方式,應該是將核心功能獨立出來,寫成函式庫,再另外橋接使用者介面。這樣比較易於測試每個部分,日後也易於重覆再利用。

    自從全球資訊網 (World Wide Web) 出現後,網頁程式不斷地在發展,現在也有許多很像桌面程式的網頁程式,像 Office Online、KKBox Web Player、Google Map 等。但其實網頁程式對初學者來說有一定挑戰性;首先,程式設計者需要學習四至五種語言,包括前端的 HTML、CSS 和 JavaScript,後端至少需要一種語言,往往也需要一種以上的資料庫 (database);另外,也要了解網頁程式運作的方式;另外,有時也要學基本的 GNU/Linux 系統管理,因為許多網頁程式使用 GNU/Linux 系統。但學會網頁程式有相當的好處,網頁程式不僅用於使用者可見的網頁,另外還有許多的程式,像是遠端 API、結合行動軟體和後端的程式、物聯網 (Internet of Things) 的後端等。筆者建議投資一些時間學習網頁程式。

    從早期的黑莓 (Blackberry) 到現在的 iPhone 及安卓 (Android) 手機,大部分的人都用這些行動裝置上網和從事其他活動,而行動軟體市集 (App Store 和 Google Play 等) 的共享商業模式,吸引許多獨立開發者 (indie developer) 投入這個市場。但行動軟體算是較為困難的,不僅僅在於要學習新的語言,如安卓系統使用的 Java 和 Kotlin,蘋果系統使用的 Swift 和 Objective C 等,另外也要自行設計使用者介面等,而行動裝置的使用者介面和傳統的桌面軟體有所不同。由於針對不同平台要重新撰寫兩套程式碼,較耗費人力和資源,後來也出現 Xamarin 和 React Native 等跨平台框架,目前這類框架有一定的使用人口,比起原生程式仍然算是少數。

    許多人有過撰寫自己的電腦遊戲的夢想,但筆者不太建議一開始就從遊戲軟體入門。電腦遊戲算是較複雜的程式,不僅僅要撰寫使用者介面,使用大量的美工和音樂素材,還要撰寫遊戲中 NPC 的人工智能,對於初學者來說,要自己完成這類項目較為辛苦。如果想要挑戰這類題材,通常建議從棋類、方塊、益智等類型入門,因為這類遊戲較不依賴外部素材,可專注在程式的核心功能上。

    前述內容是軟體的發布形式。接下來,就要思考軟體的核心功能。這個步驟是最有趣的,沒有制式的答案,在思考的過程中會引發許多想法;有時候會把專案想得太大太複雜,反而不知道如何下手。由於軟體的主題沒有固定的答案,筆者在這裡給予一些思考的方向:

    • 簡明:即使像是電子計算機 (digital calculator) 這種乍看起來很無聊的專案,仍然可以做為初學者的專案,例如,可以先寫一個解析四則運算 (algebra) 的直譯器 (interpreter),再透過外部介面呼叫該核心程式。
    • 單一:雖然許多商業軟體會提供許多複合的功能,像是 Office 就有好幾個子軟體,但對於初學者來說,針對單一主題來做會比較好。一些傳統的電子遊戲,像是俄羅斯方塊,整個程式的功能單一、主題明確,就很適合做為專案的主題。
    • 規律:對於初學者來說,找有明確運作規則的軟體比較好入門,像黑白棋 (Reversi) 就是一個主題明確、規則簡單的項目。而一些 ERP (Enterprice Resource Planning) 軟體就不適合,因為 ERP 軟體隨著不同情境和需求會有所變化,初學者易感到無所適從。
    • 小而美:一開始不要期待馬上會有成品 (product),先試著做一些原型 (prototype) 以驗證自己的想法和做法是否正確。如果某個橫向卷軸遊戲有 99 關,先試著只做一關看看。這個過程相當地有用,如果發現原先的想法不可行,及早重來會比最後才放棄整個專案來得好。

    在規畫專案的過程中,選擇程式語言重不重要呢?初學者會以為程式語言很重要,但其實沒有那麼重要,某個語言背後的生態圈才是重點。例如,若堅持使用 Python 開發手機軟體而使用 Kivy,但 Kivy 的學習資源相對缺乏,那還不如學習一下 Java,就可以確保可用到原生 Android 程式所有的功能。程式碼是將想法轉化成電腦程式的媒介,並不是最後的產品;所有的程式語言,最後都會轉為機械碼,只是過程略有不同。

    透過撰寫小型專案,會學到許多開發程式的經驗和方法,在做過幾個專案後,就漸漸脫離初學者,可以用解決實際問題的角度來思考,不需在程式語言、函式庫和框架上打轉。