Go

Go

自動生成重複代碼:使用 Go 的 Template

開發軟體時,常常會發現有些函式或方法很類似,例如對 Callback Function 來說,開發者都需要註冊回調函式,並在適當的時機,將資料交給回調函式處理,我們可以將這兩個動作,稱為 OnAction 跟 EmitAction。儘管繼承或組合能讓程式碼重複使用類似的組件,幫助開發者節省時間,但對於較複雜的情況,像是不同類(Class)的函式名稱也要不同時,仍需要仰賴開發者自行編寫。 試著想想,如果開發者僅僅寫設定檔(Config File),就有程式能根據設定檔來自動產生程式碼,不是很美好的事嗎?這是有的,在實務上,這類用於產生程式的程式被稱為 Code Generator,例如前面介紹過的 genny。Golang 有內建 generate 這個命令行工具,能幫助開發者將 Code Generator 跟編譯更密切結合在一起。 本文會用 Callback 的 Generator 當例子,講解如何開發並使用一套 Code Generator。

By Ken Chen

Go

Go 的泛型替代方案:型別斷言與代碼生成

用函數式編程(Functional Programming)的風格寫程式時,會常常重複使用一些通用函式,舉個例子,假設有個 array,開發者需要從該 array 中篩選符合條件的元素,重新組成新的 array。合理的情況是,如果有個 filter 函式,只需要設定條件,剩下的事情都能交給語言處理。 Golang 的 append 有點這味道,類似 JavaScript 的 push,能新增 slice 中的元素,但 Golang 畢竟不是徹底的函數式語言,內建函式庫中沒有 filter、map、reduce 等等 array 常用的函式。如果想要自行實現,語言的強型別系統會要求開發者在使用前告知對象型別,這等於是對不同的型別都要實現幾乎相同的函式,可想而知不切實際。 同樣是強型別語言,C++ 或 C# 在面對這問題時,是靠著泛型(

By Ken Chen

Go

資料庫版本遷移:以 Go 為例

接續前面,繼續來討論資料庫議題吧。 在商務初期,追求的是驗證市場,這時資料庫往往只有相對簡單的版本,各種欄位也還不是很齊全。隨著商業模式逐漸成熟,資料庫會需要負擔更多的營運功能,也會需要在原有表格中加入新欄位。資料庫的版本管理問題就出現了。 我們通常稱呼資料庫版本遷移為 Migration,在 Laravel 或 RoR 中都有整合好的 Migration 工具,而 Golang 目前仍需要仰賴自己動手,golang-migrate 是現在比較成熟的專案。本文會講解如何使用 golang-migrate 的 CLI 跟函式庫,來建立資料庫 Migration。 Introduction 既然說版本遷移是 Migration,為什麼不直接稱呼 Version 就好,它跟 Version 有什麼不同?兩者的區別可以看看下圖 簡單來說,Version 指的是資料庫的狀態,而 Migration 指的是狀態到狀態之間的改變。因為後端程式會使用到資料庫,如果用到資料庫沒有的欄位,就會出現問題。

By Ken Chen

Go

MQTT:輕量的消息隊列協定

這幾年隨著物聯網(IoT)越喊越熱,MQTT 這套通訊協定也越來越常聽人提起。物聯網的核心精神是將終端數據傳輸到網路,網路中的運算單元在分析這些數據後,可以將它轉化為使用者想要的應用。在網路中,數據是用通訊協定來交換,而常見的通訊協定 HTTP 結構相對複雜,傳輸成本較高,也更要求終端裝置的效能,而且 HTTP 採用輪詢(Polling)機制來取得資料,需要客戶端頻繁跟裝置拉取訊息,不適合 IoT 的應用;相對的,MQTT 輕量、採用發佈/訂閱模式,更適合 IoT 的傳輸需求。 最常見的 MQTT 工具是由 Eclipse Foundation 維護的 mosquitto,相關工具也都有開源。本文會講解如何使用 Golang 的 mqtt 套件,搭配 mosquitto 的中間人 Broker 服務,

By Ken Chen

Go

GORM:從建置到 CRUD

進行後端開發時,少不了要使用資料庫,由於資料庫的設計與使用方式偏向函數思維,跟主流的物件導向習慣不同,因此很多語言都有對應的 ORM 套件,用來將資料庫轉為物件,方便開發者使用。 Golang 同樣有許多第三方的 ORM 套件,例如 lib/pq、go-pg、gorm、pgx,其中 gorm 是 GitHub 上星星數較多的專案,而且能對應到不同類型的資料庫,在 Golang 中常被使用。本文會講解如何使用 gorm 來操作 Postgres,順帶走一次後端資料庫開發的基本流程。 Establish Database 既然要使用 ORM 來開發資料庫,當然要先有資料庫啦。Postgres 是常用到的關聯式資料,它是 web based,支援高併發,相對傳統的 SQLite 等 file based

By Ken Chen

Go

模組間的解耦合:發佈/訂閱模型

Observer Pattern 是物件導向常用的架構,例如多個 Chart 與單一 Data Source 的互動,就可以使用 Observer Pattern 設計,好避免資料不同步的問題。而且 Observer Pattern 可以切開 Subject 跟 Observer,讓個別模組的功能更明確,修改副作用更小。 Golang 的哲學是簡單,語言上更強調小元件的延展與復用,例如使用組合取代繼承,使用 Goroutine 取代 Thread 等。本文會講解怎麼使用 channel 來實現 Observer Pattern,或者更現代的說法,實現 Publish/Subscribe 的架構,來建構彼此獨立的模組。 Introduce Observer Pattern 先來對 Observer Pattern 做個解說。

By Ken Chen

Web

一種更緊湊的數據格式:Protobuf 入門

Protocol buffers,簡稱 Protobuf,是由 Google 設計的結構化序列化資料技術。對網路應用來講,常常需要在不同的伺服端、客戶端之間交換資料,這些資料格式有 XML、JSON 等等之類。XML 特點是完整,便於記載更多的 meta data,但格式複雜,需要更強的效能來解析,傳輸時也需要更多頻寬;而 JSON 是 JavaScript 用於表示物件的語法,相對 XML 來得簡潔,隨著 JavaScript 普及,也變成現在常用的輕量級資料交換格式。 儘管 XML 跟 JSON 在當前網路應用中已經相當常見,但用不同語言開發的伺服端程式,都需要分別實現自己語言的 XML 或 JSON 解析,同時,這些格式定義也是團隊協作的痛點。假設 A 團隊開發某支應用,

By Ken Chen

Go

訊息的處理架構:路由與中間層模式

進行後端程式開發時,常會使用到 Golang 的 http 標準庫。例如要對某個 URL 進行處理時,會用到 http.Handle("/foo", fooHandler) 可以想像,如果沒有 http 庫,就需要使用大量的 if else 來對 URL 判斷,大幅降低程式碼可讀性。http 庫對 URL 進行 function 註冊的設計模式,不僅可以使用在後端開發,也能應用於更普遍的情境。對於要對同類型資訊進行不同處理的例子,都可以使用這個設計模式。 本文會用 Golang 來開發一個類似 http middleware 的程式,處理自訂的訊息格式,藉由這過程,也順便走一次 http 庫的路由設計原理。 Build a

By Ken Chen

Go

Go 命令行工具初體驗:使用標準包開發

最初是在社群活動時接觸到 Golang,前陣子換工作後,新的產品團隊也是使用 Golang 來開發產品,在接觸新語言時覺得有些地方很有意思,好像能看到某種程式語言的變遷,或者說開發方向之類?跟常見的物件導向語言不同,Golang 不強調物件,而且帶有一些函式編程的特色,如果說 C++ 是替 C 補上物件導向的環節,那 Golang 更像是 C 語言的現代版。 本篇會簡單介紹如何使用 Golang 來開發一個簡單的命令行工具。我們可以假設一個微服務開發的情境,開發者需要頻繁在開發環境中啟動或關閉微服務,這時它會需要一個工具,能依照需求啟動各個微服務,通常在 Linux,我們會使用 shell script 來做這件事;如果是 Windows,則會使用 power shell 或 batch file;更正式的生產環境,可能會採用容器調度工具。Golang 由於具有跨平台的特性,也可以用在這個情境中。 Install

By Ken Chen