07 March 2014

昨天我拒絕了同事在 iOS 上開發使用 coredata ,我後來要求他用 SQLite 重寫。這只是我拒絕同事採用技術的其中一個例子。我在公司是很獨裁的。本文要探討的內容其實已經在我腦中很久了,昨天的案例正好是個引子,我就一口氣寫了出來。

Why I reject X technology

coredata 有優點,也有缺點。我可能會因為優缺點取捨而做出選擇。不過很多時候我考量的是學習與維護的成本。Coredata 也許比純 SQL 好學好用,但是我們公司的開發者要同時會 iOS、Android、Server side 三個幾乎完全不相干的平台。也許有些人偏 iOS 一點,有些人偏 Server 一點,但最終三個平台都要熟悉,這有一部份是因為我們公司是採 pair programming,而且也會輪替工作。

如果各個平台上都盡量運用 SQL。那花精力投資在 SQL 上,一次就能 master 三個平台。你的知識可以互通、可以不斷累積強化,我認為整體而言成果較好、成本較低,效果比東學一點 coredata、西學一點 SQL、再學一點 mongodb 什麼的要好的多。

基於類似的原因,我也拒絕了公司原本要採用的技術:

  • 使用 scala

Scala 是 JVM 界最潮的語言了,我這種愛玩新玩意兒的是沒有放過這個機會的。我花了一些時間寫了實驗性的程式,但最終我拒絕自己在公司內使用 Scala。其一是我的實驗失敗了,其二是 Scala 可做到的 Java 都做的到,沒有理由增加員工學習維護的成本。

  • 使用 Hibernate

我已經會 Hibernate 了,對我來說沒有成本的。但後來我也拒絕自己使用它了,其一的原因它實在太複雜了,難以駕馭,學習成本實在太高。其二是純 SQL 也能做到同樣的成果,這個額外的工夫很浪費。

  • 使用新的 web server - Undertow

Undertow 是 RedHat 新的 web server,架構與傳統的 servlet 不同。它在 benchmark 的分數很高。不過最後我也回絕了這個 server。因為那時的需求是 Restful API http server。Restful Http 已經是很成熟的技術了,相關功能已經發展到很完整,stackoverflow 一堆常見的問與答。我可以選成熟穩健的 Spring MVC 來做到一樣的事,我就不會再引進新的 server,增加額外的學習成本。

引進新 server 是有必要的,但那是原本的 server 不夠使用時才會做的事。例如用戶暴增,造成 Tomcat + Spring 撐不住了,我們才會尋求新的解決方案。但這個機會也很低,因為 restful 很好 scale。

  • 使用 python 做 server 開發

我們同事有 python 的背景,他用 python 開發 prototype 很快。我以前也有一陣子很著迷 python,也實驗了一些 python 的 web framework。後來我要求全部改成 Java。我停止導入的原因是,雖然 python/Java 各有千秋,但 web server framework 這領域已經相當的成熟,Python 能做的,Java 也能做,反之亦然,沒有必要在同個公司導入兩個重覆的技術。

一般而言用 python 做 prototype 的成本比較低,但我們公司有四個 TWJUG (Taiwan Java User Group) 的成員,是個 Java shop,維護 Java 對我們反而成本較低。我不可能要求同事同時要精通 Java、Android、iOS 的情況下,又要維護好 Python Server。即使是像我這樣寫了十年的,愛亂玩技術的人也是很吃力的。

我們公司仍然需要 python,但它用在 bash/Java 使不上力的 scripts 上。使用上很侷限,也不需要花太多時間學習和維護。

Learning deep and wide, not duplicate

如果說十年來的開發經驗告訴我了什麼,我會說 -- 不要學習太多重覆的技術 。我是在 Java web framework 全盛時期進入這一行業的,那時我很愛嘗試不同的 framework,我也從中學到了一些技巧,一些優缺點。大家用不同的工法,但最終呈現的結果是一樣的 -- 一個 web app server。

後來有後起之秀 Rails ,雖然語言平台完全不同,但其實面臨的問題差不多,解決的 pattern 也是 MVC + ORM 。從那時候起,我就開始觀察到了一個技術的循環,新技術雖然看似很新,很潮,但其實換湯不換藥。而現在,這個世代輪到了 NodeJs,你會發現他們只是再循環一次之前做過的事。

Rails shop 應該轉 Java 嗎? Java shop 要導入 NodeJs 嗎?我的答案這是在浪費時間,因為做出的成果都是相同的,都是在寫 web app server。如果你熟悉 Rails,那就該繼續下去,學習的更深入。而不是看到人家 NodeJs 很夯就跳船,然後造成團隊同時使用兩種以上的平台。只有原平台使不上力時, 例如效能問題,或是部署很困難等等瓶頸,才值得考慮異質的解決方案。

我會建議大家往深、往廣的方向學習,而不是學習重覆的技能。用講的可能不清楚,我直接列範例比較好表達意思。下面是我希望我們團隊成員和我自己學習的方向:

往廣的方向:

  • 學習如何使用 Lucene 做搜尋、做分類
  • 學習管理、監控 Amazon EC2
  • 學習如何寫 Android launcher
  • 學習 Voip 技術
  • 學習 HTML5
  • 學習 WebGL、OpenGL
  • 學習 iBeacon
  • 學習 Unit Test
  • 學習如何在 Postgres 使用 GIS
  • 學習 Functional Programming 概念
  • 學習 CAP 理論與優缺點
  • 學習 Machine Learning
  • 學習 Continous integration

往深的方向:

  • 學習如何最佳化 Android animation
  • 學習避免 Android GC
  • 學習如何 tuning SQL index
  • 學習如何 tuning apache server
  • 學習 Security 最佳實踐、如何正確部署 TLS
  • 熟稔各種資料結構
  • 學習如何 tuning JVM Garbage collector
  • 學習開發高效能的 socket server
  • 學習 horizontal scale with Akka
  • 學習 iOS 7 新的設計趨勢
  • 學習如何 Profile iOS app,如何避免 memory leak
  • 深入學習 regular expression

看了上面這個列表應該可以理解 -- 它們都不重疊,對我來說這才算 學習 。這個列表是基於我們公司 iOS/Android/Java/SQL 的技術平台開出來的,這個表可以無限延伸下去。我們有太多的未知領域要探索,有太多最佳實踐要學習。Mobile、Browser、Cloud 三大 paradigm 糾纏著我們開發者,我實在不建議花無謂的工夫在可以達到 同樣成果 的重覆技術上。要投資就要投資在刀口,投資在可以做出不同的產品、不同效果的技術上。或甚至自己研發技術,開一條全新的路,全新的 paradigm。

小結

研究和學習別的平台怎麼做同樣的事,增廣見聞是好的。但如果你同時會 Spring、Rails、NodeJs、Django 開發 web app,那你可能浪費了無謂的時間,因為他們的成果都一樣。而且在同個團隊導入重覆功能的技術,只是增加學習和維護的成本,長遠來看是扣分,而不是加分。學習新技術是在軟體業生存的必備能力,我期許我自己,也建議各位,往更廣、往更深的方向前進。