2015/08/31

Reactive Programming 響應式程式設計方法

Reactive Programming 是以 data flow 以及傳遞資料改變這兩點為核心,提出的一種 programming paradigm,尤其在 GUI Programming 的領域中,簡易的 Reactive Programming Model,讓 Programmer 能用更直覺的方式,取得資料的串流,並能跟著時間的流動,改變整個畫面的呈現結果。

Imperative vs Reactive Programming

在程式中,如果寫下

b:=2;
c:=3;
a:=b+c
// a 為 5

這個 statement,這時候 a 的結果就會等於 b+c 的運算結果,也就是 5。

然而如果在後面 b 或 c 改變了自己的數值

b:=3;
// a 為 5 或 6?

程式並 "沒有" 再寫一次 a:=b+c,如果 a 還是一樣保持不變,還是等於 5,這就是 imerative programming。

但是如果 a 自動跟著 b 的數值改變,自動再次運算了 b+c,a 自動變成了 6,這就是 reactive programming。

Excel, Spreadsheet

Reactive Programming 乍看起來有點奇怪,這跟我們學習過的程式語言 C 或是 Java 根本都不一樣,變數不應該隨著另一個變數自動改變自己。

但其實有用過 Office Excel 或是其他 Spreadsheet 試算表軟體的使用者,就已經是在做 Reactive Programming了。

在下面的例子中,C1 設定為 A1 + B1 這兩個儲存格的總和,當 A1 的數值改變時,C1 也會自動改變結果。

Office Excel 是辦公室的試算軟體,換句話說,Reactive Programming 其實是比較人性化的程式設計方法,而 Imperative Programming 是為了避免程式設計師撰寫程式時出錯,而刻意將自己簡化的結果。

畢竟當我們撰寫程式時,寫下這樣的 statements 的時候,沒有一個人會直覺地認為 a 的結果會是 6,因為大腦線性運算的結果,只會記得 a 是 5。

b:=2;
c:=3;
a:=b+c
b:=3;

那為什麼又討論起 Reactive Programming 呢?這跟最近幾年流行起來的 Functional Programming 有關係。

Functional Reactive Programming

回到剛剛的 Excel 範例,其實 C1 儲存格隱藏著一個意義,就是 C1 := SUM(A1 + B1),C1 永遠會等於後面這個 function 的運算結果。

在不支援 Reactive Programming 中,要實作出 Reactive 的功能,必須要用 Observer Design Pattern,程式中向原始資料,註冊 Observer,當原始資料異動時,就會呼叫 Observer 的 Lisener Function,主動進行對應的資料異動處理。

也許有人會想,Functional Programming 的基本原則,變數應該都是 immutable value,為什麼會有 Functional Reactive Programming 呢?

Functional Programming 將 Function 視為 first class citizens,而 Function Reactive Programming 並不是單純地將 Reactive 的概念用在變數上,而是將資料視為一個 time-varying values,依照時間變動的數值。

這個互動模式最常見於 GUI 的實作上,FRP 定義了兩種會跟著時間改變的資料:events 與 behaviors。

  • events 代表一個特定時間的數值,例如使用者在鍵盤上敲了一個鍵,就產生了一個 Event Char,並以 (t, 'a') 來表示這個 event。實際上的程式並不直接處理 event,而是處理 event stream,因為時間的連續性,讓鍵盤輸入資料也變成了一個無限的資料串流。

  • behaviors 代表跟著時間持續變動的數值,例如滑鼠游標的位置,因為滑鼠的位置是永遠存在的,而且永遠一直在改變,所以我們可隨著時間的流動,持續取得滑鼠的位置串流。

針對跟著時間流動產生的數值串流寫的程式,其實不需要 Functional Language 也可以撰寫,將 Functional 結合 Reactive Programming 的優勢在於,Functional Language 能夠直接 function 來進行運算,而這個 function 恰好可以表示有著無限資料的 stream,這可簡化大量的程式語法。

ELM Programming Language

網頁是目前最常見的 GUI,以往我們需要了解 html, css, javascript,還要知道怎麼操作 DOM Tree,讀了一堆東西,才算是知道怎麼撰寫網頁程式。

ELM 程式語言,是針對網頁 UI 設計的一種 Functional Reactive Programming Language,他可以即時編譯成 html 與 javascript,因此可以打包放到網頁上運作。

我們可以直接看一下 Mouse Example,簡單的一個 statement: Mouse.position 就可以持續取得滑鼠的位置。

為什麼要提到 Game 呢?因為網頁的遊戲開發,如果使用 javascript,將會耗費 programmer 相當多的時間,也許可以採用某個 javascript framework簡化開發,而 ELM 是直接用另一種程式語言的方式,取代掉繁瑣的 javascript。

看看這兩個實際的例子,就能實際感受到,簡潔的語法帶來的開發優勢:
Mario
Elmtris

References

也談響應式編程

遊戲編程的未來——FRP(函數式反應型編程)

Reactive Programming wiki

Reactive programming - 響應式編程

關於 Elm 的分享, 底稿

使用函數式編程語言 ELM 開發遊戲

FRP與函數式

The introduction to Reactive Programming you've been missing

Functional Reactive Programming (FRP)

Quora: What is Functional Reactive Programming

An Introduction to Functional Reactive Programming

2015/08/24

工程師文化

因為網際網路的規模及便利,讓工程師能在任何地方,用一台電腦,就可以連上全世界,有很多知名的網路公司,都是由工程師創業開始,逐漸發展成一個跨國的網路公司。例如 Facebook 常強調自己的企業文化是 駭客之道,而 Google 強調「實驗、犯錯、創新」的精神( 洪大倫:創新,從企業文化做起——評論《Google模式》一書關於把Google模式用在台灣,我想說的是...),因為理工科的訓練以及工作習慣,除了腳踏實地的做是態度外,更強調創新以及快速反應,網路事業的企業文化,都希望自己能持續在車庫中創業的精神,永遠能跟上新世代的網路變化。

工程師的精神

要知道工程師的精神是什麼,首先應該要問問中國古代最有名的工程天才墨翟,在當代要特別弘揚墨家思想中的工程師精神這篇文章中提到,墨家思想中最具特色的就是理性、邏輯和工程師精神。

作為機械製造大師的墨子,第一個提出機械設計三大定律,以規範機械師的設計標準。這三大定律在《墨子》中稱「三表」,說的就是:

  1. 要根據歷史的經驗
  2. 要考察人們的反應
  3. 要考察實際效果是否有利於國家人民

工程師精神有四點:

  1. 理性,面對實際問題,問題驅動。
  2. 嚴肅、嚴謹、認真、一絲不茍。
  3. 精益求精,永不滿足。
  4. 秩序感。工程師重視程序、過程的完美,在有序中努力實現結果的完美

矽谷最寶貴的精神財富:工程師文化 提供了另一種工程師精神的解釋:

  1. 有偉大的點子就必須實現它,而實現它你必須親自動手。
  2. 勇於創新,勇於嘗試,不要害怕犯錯誤。
  3. 扁平管理,民主,分權決策。杜絕公司政治與官僚。
  4. 賺錢只是結果,而不是原因。

工程師在追求一個有效且穩定的系統的過程中,會經歷許多挫折,在一次又一次嘗試錯誤之後,才能到達目標,永遠追求卓越與進步,是工程師前進的動力,這種不斷更新與改變的精神,恰好跟快速變動的網路時代一樣,因為網路的覆蓋率大,能夠接觸的使用者就很多,網路系統或服務,也必須隨著使用者的進步,不斷改變自己,沒有創新就會被其他人淘汰。

工程師文化,也可以說是研發團隊的工作規範

綜合以下這些文章的意見:

  1. 如何打造工程師文化?
  2. 我眼中的工程師文化
  3. 什麼是工程師文化?

我認為一個研發團隊應該要有的一些特性是:

  1. 團隊成員人數少
    為了追求快速的開發與產品釋出,團隊成員人數太多,會造成過多的溝通時間成本的浪費。

  2. 有想法,做就對了
    不需要太過詳細的計畫,有任何想法,就應該先以最小的系統雛型直接開始做起,以系統原型來取代過多的討論與文件

  3. 加速系統開發 Iteration
    快速的產品釋出,

  4. 自動化
    盡可能地進行自動化,但要注意的是,自動化本身也有建置的成本,如果建置與維護自動化程序的成本太高,也不能一味地強調一定要自動化

  5. 分享 code 與文件
    在團隊中,程式碼跟文件是溝通的基本資料,強調分享的用意是在分享的過程中,每一個人都能取得正確的資訊,也沒有特殊權限的擁有者,這會產生團隊中的階級意識,任何人都應該是平起平坐的。

  6. 尋找適合團隊的人才
    與其說要找到最好的人才,倒不如說要找到最適合團隊的人才,要找到能適應團隊文化的人才。

工程師文化可以轉換成企業文化嗎?

對一個新創團隊來說,整個團隊就是公司的全部,團隊的文化就等於是企業的文化,當然在未來,團隊在成長的過程中,企業文化也必須適應公司成員的增加,這時候就必須取出工程師的精進文化,維持企業成長的動力。

創業 CEO / 雇不到優秀工程師,其實是企業文化的問題,文章提到工程師在未來十年註定成為珍貴的稀缺資源,那麼吸引並留下其中優秀者,必須成為企業最重要的核心競爭力。建立工程師文化的氛圍,提供成長的機會,做真正有意義的軟體產品,這都是一個企業能吸引員工的方法。

工程師性格不是隨時都受用

工程師文化並不是隨時都受用的,最常見的是業務單位跟開發單位的衝突,你是否中了工程師文化的毒? 中提到三個用工程師的思維做事的問題:

  1. 工程師思維來為產品命名
    MS 的 Surface RT 在面對消費者的時候,沒有人會知道 RT 究竟代表什麼意思。在銷售時,工程師也必須要講「人話」。

  2. 工程師思維來做產品文案
    工程師最常見的問題,就是不知道怎麼面對使用者界面的功能命名,沒有辦法用淺顯易懂又直接的文字或語言,描述系統的功能。

  3. 工程師思維來決定設計
    曾經 Google 用統計數據的方法,觀察使用者哪種顏色會讓使用者產生更多的點擊,來決定配色方案。但視覺設計如果完全交給數據,那就等於否定了設計師的工作信念。

    最常見的問題,就是在系統的顏色色系,每一個人都有自己的看法,然而顏色沒有對錯,只有適不適合,要怎麼拿捏分寸,需要更多尊重每一個人的意見的方法。

從研發團隊,到公司整體,到治國方法

根據這些文章的意見:

工程師治國精神

工程師治國越治越亂

英國媒體關注全球領導人學位 稱中國是「工程師治國」

醫師、律師、工程師治國 翟本喬:不能要求同樣方法

林修全/醫師、工程師治國 會比律師好?

卜大中: 工程師治國VS.律師治國

大陸在經濟起飛的那個階段,領導者大都具有工程的背景,在那個階段,推動了整體的基礎建設。在台灣也經歷過十大建設的階段,後來有了兩個律師治國,直到最近,最熱門的話提就是醫師治國。

究竟領導者該是那一種類型的專業背景,每個人都能講出自己的一番道理,而治國的成敗,也只能用結果來判定,沒辦法做過多的預測,但民主社會的優點是,只要做不好,就不會有下一次的機會,做了就會知道結果是什麼。

2015/08/17

Scala Days

看著 2015 年第三年的 Scala Days Slides,想起已經舉辦很久風光的 JavaOne,以及 JavaTwo Taiwan,記得當初還在 1.2 版,就被 JVM 的 garbage collection 以及 Write Once Run Everywhere 吸引,也才由 C 語言轉進到 Java 領域。

經過了十幾年的 Java,記憶體自動回收的技術與概念已經非常成熟,而 JVM 也因為包容了其他的 script language 而有了不同的生命,scala 有著自己的 ecosystem,也有希望能一舉完全取代 Java,成為下一代重要的 JVM 語言。

Memories of Java

還記得自己也是大約在 2001~2002 開始接觸 Java,大約跟第一屆的 JavaTwo Conference 同一個階段,曾經參加過幾次 JavaTwo,還有 Java Tech Days,後期對 Java Conference 的印象,是廠商的場次比技術的場次還多。

唸書的時候並沒有寫過 Java 的程式,後來到了職場,才慢慢地自己將物件導向、Pattern、J2EE Pattern這些知識累積起來,直到現在,Java 在商用運算的環境,還算是非常熱門的語言,另一個成功讓 Java 延長壽命的,就是 Android,使用那個軟體開發技術沒有永遠的對或錯。

參加這些活動之後 ,最後還留到現在的是 T-Shirt 跟 Java Duke 娃娃,還記得有一隻娃娃是參加 Conference 就送的,有一隻是文章投稿的獎品,已經忘記第三隻是怎麼得到的。

另一個印象最深的是洪志鵬先生,他是前昇陽的總經理,就是在他任內成功地以 JavaTwo 讓 Java 在台灣生根,後來更毅然辭職當了幾年作家,然後去了昇陽的對手微軟工作。

洪先生有一篇有趣的文章,可參閱:技術人員如何轉型成功 - 洪志鵬。另外搜尋到一篇蘋果日報在 2014 年的訪問:[動新聞]我是總監 但沒有一天不想當「作家」

Scala is getting stronger with TypeSafe

三年的 Scala Days 都是三天的活動,從 2013 年同時的三個 session,到了 2014 年是同時四個 session,到了今年,已經是在Amsterdam 與 San Francisco 兩個地方舉辦活動,規模有慢慢擴大的感覺。

scala 語言在 scala 的爸爸 Martin Odersky 設立的公司 TypeSafe 協助下,有逐年成長的趨勢,這種感覺,就像是 Java 在 Sun 的羽翼之下成長的狀況。

講得現實一些,Typesafe 如果要賺錢,首要任務就是要將 scala 的社群使用比例提高,搭配公司推廣的官方 framework,再加上更多的 scala libray/framework,越多人使用 scala,Typesafe 才能越成功。

要推廣一個語言,除了技術本身之外,也許該學學 Java Duke,找個公仔來代言,這可以讓整個開發社群更有話題性,也更能提昇自己的地位,在眾多 JVM 語言之中脫穎而出。

scala 的未來

觀察 scala 有幾個重點,一個是 JVM 語言的未來,scala 能不能成為 Java 語言之後,可以完整取代 Java 運作在 JVM 的語言,這部份是以 scala 「精簡」的語法作為推廣的策略。

第二是 Concurrency Model,既有的 Java 是採用 Multi-Thread、shared data 加上 data lock 機制來進行,scala 採用的是 actor concurrency model,這是簡化後的並行機制,程式不需要考慮什麼時候要鎖定或釋放資料。

第三是 Big Data,Spark 已經逐漸取代了 hadoop 的吸睛程度,而 spark 是以 scala 的,這等於也影響到,要使用 Big Data 的 programmer 必須要去學習 scala 的動力。

第四是 Object-Oriented Functional Programming,原本在 Java 我們學習的是 Object-Oriented 的思考方式,近幾年因為大量 concurrent user 的需求,functional programming 開發的意識抬頭,而 scala 融合了 Object Oriented 以及 Functional Programming 的精神。

OO or FP or OO+FP ?

選擇 FP 或是 OO 並沒有絕對的對或錯,或許應該說使用純粹的 FP 語言,或是純粹的 OO 語言,會讓開發變得單純,而 OO+FP 語言,或許會讓每個 programmer 寫出來的程式碼大相逕庭,互相都看不懂對方的程式碼。

物件導向重視軟體工程,搭配物件導向本身的概念,programmer還需要學習OO Pattern。FP 比較接近一邊想一邊寫 code 的 coding style,也就是說,程式碼會比較沒有組織一些,比較 free-style。

既然 OO 與 FP 各有各的優點,那麼 scala 就是希望融合兩者 OO+FP,Java 本身雖然是 Object Oriented,但也持續朝向 Functional 的功能靠攏,然而在跟傳統的 Java 相容的包袱下,再怎麼改進,總會擺脫不了沈重的語法包袱,或許 scala 是一種延續 JVM 生命的靈藥?

Language pitfalls

Java 人人會寫,但並不是每一個人都能準確地掌握這個語言,Scala 也是一樣。想像一下,Java EE 專案如果沒有 Java EE Patterns 的包裝,每一個 programmer 寫出來的 project 也都是不一樣的,而每一個開發團隊,都需要有製作專案的規範,這不是單純選擇某個語言就可以解決的問題。

以 Singleton 這個最簡單的 OO Pattern 為例,也是經過了一段時間的討論跟測試,大家才知道應該要這樣寫,才能在 JVM multithread 的環境中正常運作。

public class Singleton {
    private volatile static Singleton instance;

    private Singleton() {
    }

    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

以 scala 來說,也有一些人注意到了語言的誤區問題,例如: scala pitfalls ,還有 Scala Puzzler 這本書。

程式語言都可能會因為支援的語法越多,而產生一些正確跟可能會造成錯誤的寫法,也就是 Pattern 與 Anti-Pattern,這些資訊,會隨著更多人注意跟使用 scala 越來越多。

books

書籍量的多寡,也是程式語言熱門程度的一個指標,越多人使用的語言,書籍就會越多。目前沒看到任何一本 scala 繁體中文的書,只有幾本翻譯成了簡體中文。

scala books
amazone scala books

Reference

走入臺灣程式開發社群

2015/08/10

Top scala libraries in github projects

在 javacodegeeks 有篇文章,作者針對 github projects 裡面去分析使用了哪些 scala libraries,藉此得知目前 scala 在社群中發展的狀況,哪些 scala library 最熱門,被使用最多的 project。

文章

這個 popular scala library 的 survey 在 2014 年也有做,是另一個同樣在 takipi 工作的工程師處理的。

2015: The Top 100 Scala Libraries in 2015 – Based on 64,562 GitHub Libraries

2014: Top 100 Most Popular Scala Libraries – Based on 10,000 GitHub Projects

分析結果

在作者分析過 Top 100 Libraries 之後得到幾個結論

  1. scala 社群正在快速的發展當中,有 33 個新進榜的專案
  2. spark #45 的排名超越了 hadoop #95
  3. 21.3% 的 top scala projects 使用了 Play framework
  4. 出現了很多 javascript 與 scala 整合的 library,包含了 scala.js(scala to js compiler)
  5. 最熱門的 Scala IDE 是 IntelliJ

另外還有一些次要的結論

  1. 21個專案來自 Typesage team
  2. Akka 很熱門,排名 #9
  3. scalatest 與 junit 是最多人引用的專案,scalatest 有 2521個(34.4%)專案使用
  4. logback 是最熱門的 logging library
  5. Google Guava在 Java 領域中排名 #4,但在 scala 領域中排名 #37
  6. Scalaz 類似 Guava 的角色,延伸了 scala 的核心,排名 #18
  7. H2 是最熱門的 database
  8. Jetty在 scala 領域中比 java 熱門

比較一下2014年的結果

  1. 2014年還是 slf4j 與 log4j 的年代,但在 2015年已經換成了 logback
  2. scalatest, Akka 維持了熱門程度

特別的發現 scala.js

scalajs 是我沒有聽過的一個專案,專案目標是可以將 scala code 轉換為 javascript,還將一堆 scala 專案都 porting 到了 javascript。

scala.js 把 scala 跟 javascript 連結在一起,讓 javascript library 取得了 scala 靜態資料型別的優勢,同時我們可以從 demo code 中發現,簡潔的 scala 語法,轉換出來的 javascript code 的成效,也就等於把 scala 帶入了 browser 的領域,不再專屬於 java JVM。

Tutorial/Training: Why Scala.js - Preview 是一個簡短的 scalajs tutorial,影片中簡短 demo 了 scalajs 的能力,首先是在網頁上繪圖,另外是從 scalajs 中呼叫另一個氣象網站的 API。

T2_Haoyi_Why_Scala.js.pdf 是 Li Haoyi,一位早期的 scala.js code contributor 的簡報,他提到 scala.js 誕生的原因,是因為現在的 web programmer 都需要學習 client 與 server 兩種語言,程式碼不能重用。另外 javascript 程式碼中 String 的濫用,如果使用 scala.js 可以讓 String-typing 變成 Strong-typing,更容易寫出堅固的 web application。

scala.js 並不是 javascript,有個最簡單的例子:

javascript>["10", "10", "10", "10"].map(parseInt)
[10, NaN, 2, 3] // WTF

scala.js> List("10", "10", "10", "10").map(parseInt)
List(10, 10, 10, 10) // Yay!

2015/08/04

自訂AngularJS Directives(一)

AngularJS

AngularJS是當前知名的JavaScript框架,其主要理念是透過MVC(Model-View-Controller)架構來幫助Web App開發者建置網站。

Directives

在AngularJS中,Directives指的是其自行定義的DOM元件,屬性,class名稱...等。曾接觸過AngularJS的讀者,一定對ng-controllerng-bindng-model, ng-repeat...等等名詞不陌生,這些都是AngularJS內建的Directives。

AngularJS透過Directives賦與DOM元件額外的能力,如:ng-bind可以自動將某個記憶體中的變數與HTML元件建立關連;當該變數內容異動時,相關連的HTML元件的內容也將自動更新。

此外,AngularJS允許網頁開發者自訂Directives,這也是本篇文章將要探討的主題。

自訂Directives為AngularJS中稍微進階的議題。未曾接觸過AngularJS的讀者們,建議可以先參考幾篇AngularJS的基本介紹:

AngularJS官方文件

前端工程的極致精品: AngularJS 開發框架介紹

AngularJS 入門簡介(slideshare)

對於AngularJS的基本概念,本篇文章將暫不贅述。

為何需要自訂Directives

筆者前陣子開始研究AngularJS,並試著思考:已往曾經寫過的網頁,倘若是使用AngularJS食,該如何撰寫。

然而,卻遇到了一些瓶頸。如:我需要把我的網頁切成多個子頁面,並將每個子頁面的HTML/JavaScript獨立出來,並視情況顯示某些子頁面,或是移除某些子頁面。最重要的-這些子頁面可能需要可以被重複使用。

後來看了各大論壇的討論,以及幾篇部落格文章,都介紹到了AngularJS的自訂Directives功能,如:
SushiWen's Blog: 比較Backbone.js, Angular.js, Ember.js, Knockout.js 心得

AngularJS的自訂Directives功能,概念上接近允許使用者自訂一個DOM元件。
您若已經非常熟悉AngularJS,亦可參考AngularJS官方對自訂Directives功能的介紹:Creating Custom Directives

本文僅從最簡單的範例開始介紹。

自訂Directives範例一:Hello World

以下範例自訂了一個helloWorld directive。

<!doctype html>
<html lang="en" ng-app="myapp">
<head>
  <meta charset="utf-8">
  <title>My HTML File</title>
  <script src="angular.js"></script>
  <script>
    angular.module('myapp', [])
    .directive('helloWorld', function() {
        return {
            restrict: 'AE',                
            template: '<h3>Hello World!!</h3>',
            replace: true,
        };
    });
  </script>
</head>
<body>    
    <hello-world></hello-world>
</body>
</html>

結果呈現了簡單的:

Hello World!!

若使用瀏覽器的開發工具檢視DOM元件,可以看到:

<body>    
    <h3>Hello World!!</h3>
</body>

Directive名稱

以上範例在HTML中,寫的是hello-world;而AngularJS會自動將其轉換為helloWorld

Directive名稱的轉換規則如下:

1.去掉元素/屬性名稱前面的x-以及data-

2.將冒號( : ), 連字號( - )或底線( _ )作為分隔符號,將元素/屬性名稱轉為駝峰式大小寫(camelCase)格式。

如以下寫法都會符合helloWorld directive:

<hello-world></hello-world> <br/>
<hello:world></hello:world> <br/>
<hello_world></hello_world> <br/>
<data-hello-world></data-hello-world> <br/>
<x-hello-world></x-hello-world> <br/>

restrict參數

restrict參數表示此Directive允許以何種方式呈現。

A表示屬性:

<div hello-world></div>

E表示元素:

<hello-world></hello-world>

C表示類別:

<div class="hello-world"></div>

A, E, C參數可以混合使用。如範例中使用'AE',表示以下兩種寫法都會被接受:

<div hello-world></div>
<hello-world></hello-world>

template/templateURL參數

template參數表示此Directive實際上呈現的HTML內容,
如上例中:

<h3>Hello World!!</h3>

此外,若HTML內容比較龐大時,可以改將其放在一個檔案中,
並使用templateURL參數

因此上例可改成:

  <script>
    angular.module('myapp', [])
    .directive('helloWorld', function() {
        return {
            restrict: 'AE',                
            templateURL: 'helloWorldTemplate.html',
            replace: true,
        };
    });
  </script>

helloWorldTemplate.html內容如下:

<h3>Hello World!!</h3>

replace參數

replace參數表示原本的DOM元素是否需要被取代。

在上例中,replace為true,因此在使用瀏覽器的開發工具檢視DOM元件,只會看到:

<body>    
    <h3>Hello World!!</h3>
</body>

若replace為false時,則會看到:

<body>    
    <hello-world>
        <h3>Hello World!!</h3>
    </hello-world>
</body>

需特別注意的是,replace參數在AngularJS 1.3之後已不被建議使用,並可能在未來的版本被移除;因此可能的話,請避免使用replace參數。

小結

上述內容僅讓讀者對AngularJS的自訂Directives有了最基礎的概念;而下一篇將進一步介紹如何為自訂Directives建立其專屬的函式/API, 發揮其真正強大的功能, 以建立可重用的web元件。

2015/08/03

Null 造成了數十億的損失 Null Reference is the Billion Dollar Mistake

Tony Hoare 是 Quick Sort 的發明者、發明 Hoare logic 用來驗證程式的正確性,同時也是 Null Reference 的發明者,1980 ACM Turing Award 的得主。

在 2009 年的 conference 中,他主講了一個主題Null References: The Billion Dollar Mistake, 8/25 2009,Null Reference 造成了系統一些不可預期的錯誤,間接就等於是大量的金錢損失。

Null 的問題是語意不清,字面上的意思是「空」、「無」、「沒有」、「不存在」,Java 開發者常常會在 method 不需要傳送任何東西時傳回 return null。

然而吊詭的是,明明在那個 method 的定義上,就要回傳一個物件,使用這個 method 的開發者,並不一定會知道,這個 method 回傳的物件有可能會是 null,這就造成了 NullPointerException 問題,而這個 Exception 沒辦法在編譯時期就被發現,只能在運作時期產生出來,並在 JVM 直接造成系統停止運作。

這常會造成一種開發的循環,開發者說程式寫好了,上線測試了一段時間,怎麼系統突然掛掉了,然後找開發者去問,第一時間會回答不知道為什麼,然後去伺服器上取 log,找了半天,才發現出了 NullPointerException,然後就修改程式,判斷一下是不是 null,又重演一次上面的循環。

回頭來看看作者對 Null Reference 的看法:1965年時,我正在設計程式語言 ALGOL W ,這是第一個 comprehensive type system for reference in OO language,目標是確保每一個 object reference 都是安全可用的,而且可以由 compiler 自動檢查。

但是他卻沒辦法抗拒將 Null Reference 放進實作中,因為它實在是太容易實作出來了,而 Null 造成了 innerable errors, vulnerabilities 與 system crash,間接等於近四十年來造成了數億元的損失。

要避免遇到 NullPointerException,唯一的解決方法就是完全不使用 null,不過,剛說完不使用 null 可能馬上就會被打臉,因為 RDBMS 的資料欄位中,設計時為了節省儲存實體的硬碟空間,通常預設值都是 null。

Java 8 提出要用 Optional 處理 null,scala 也建議要使用 Option/Some/None Pattern,當語言的設計本身難免都會有一些誤區,也就是 Anti-Pattern,建議開發者要多深入了解語法的意義,並以「正確」的方式使用他們。

說避免不使用 null 還是夢想,還是得回頭提醒開發者,隨時都得要注意,除非確定該變數不是 null,否則一定要針對 null reference 進行處理,多寫一些檢查的程式碼,不會讓你的生命多浪費幾秒鐘,反而會讓系統更加穩定,不會發生不可預期的錯誤。

Refernces

補救null的策略

圖靈獎得主Tony Hoare:我的錯誤造成了十億美元損失