2012年1月27日 星期五

從 Play framework 的 controller 看物件導向的優點

學習了不少的 frameworks, design patterns,我想簡單的描述它們的優點,
以讓團隊成員,甚至長官能夠瞭解,並支持 refactoring 和 test 的必要性。
很多 design patterns 的目的都不是在減少打字量,甚至還會增加程式行數。
剛好我從 Play 的官網中看到這一段,讓我想要記下來。

同樣功能的程式,分三階段演進:

public static void show() {
    String id_str = params.get( "id" );
    Integer id = Integer.parseInt( id_str );
    System.out.println( id );
}

public static void show() {
    Integer id = params.get( "id", Integer.class );
    System.out.println( id );
}

public static void show( Integer id ) {
    System.out.println( id );
}

最後的程式碼最精簡,但不代表整體的程式碼最少。事實上,是有些程式碼被隱藏起來了,
被隱藏在父類別。但是,實際應用時,程式碼確實變少了。

這是我認為 design patterns 的好處-讓物件/開發人員彼此分工。或許負責處理架構的
物件/人員,工作量變多了,但換來的是應用端的輕省及彈性,因此值得。

參考資料:
http://www.playframework.org/documentation/1.2.4/controllers

2012年1月25日 星期三

Scala Groovy and Xtend

今天看完這篇Groovy的簡介

雖然資料是舊的,但原理應該一樣。很容易懂的文章。
之前在評估要學Scala還是Groovy時,看到Scala的評價比較高,而且連Groovy的作者都推薦。所以,就選擇了Scala開始學。Scala非常有趣,令我期待它能得到大廠的支援,廣為使用。但是版本間不相容和其它的問題,對正式專案來說相當不利,只能期待它更成熟。

之前我就發現SpringCore選擇Groovy而非Scala,雖然當時我不知道原因。現在,看來是因為Groovy更簡單易懂。而且,先前學Scala的經驗沒有白費,因為它們的理念非常相同。應該說Groovy用到了部份Scala的特性,而它們的用法幾乎一致。

Xtend的立意也很好,語法和Scala也很像,不同的是,它會先產生Java的原始碼(.java),而Scala和Groovy是直接編譯成.class。但我發現它會用自己的套件,取代JDK的原生套件,這點對我要用在專案中卻是減分。因為,要說服長官讓我使用新技術的前提,通常是我得保證不會影響專案的時程和穩定性。最好就是和原來一樣。

也因此,我自己在專案中寫了一些仿Scala, Groovy或是仿Python的功能,而不能直接使用.scala, .groovy。目前我還是只能將Scala/Groovy用在自己有興趣的專案上。


其它好文章:

    Java輕鬆玩 - 陣列與水果盒之間的關係

    這篇對已經熟悉Java的我來說很有幫助

2012年1月22日 星期日

Java YAML

今天在學習Play的時侯,發現了YAML的存在。
看來真是個好東西,我迫不及待要用在JUnit裡面了。
可以彌補Java沒有"""(Scala/Python有)的缺點。
初步看到有JYAML和SnakeYAML,因為Play內建的就是SnakeYAML,
而且到Google code上去看,是活躍的專案,所以決定用SnakeYAML。

2012年1月20日 星期五

從 Imperative 到 Declarative programming

很難想像沒有 Wikipedia 的日子…

以下出自 Wikipedia - http://en.wikipedia.org/wiki/Imperative_programming


一、Imperative programming (指令式編程)


imperative programs describes computation in terms of statements that change a program state
imperative programs define sequences of commands for the computer to perform.
「狀態」和「順序」是造成程式複雜的原因。

我發現如果是Imperative的做法,通常就會有全域變數。而全域變數通常較難追蹤,也就難以維護。想像一下這種情況:

某個全域變數,它的狀態會被3個不同的method,假設是A,B,C修改,當我要追蹤這個變數值時,就要先搞清楚A,B,C執行的先後順序。然後,既然是method,它就是創造出來被重複使用的,所以,我也得把重複呼叫的地方考慮進去。如果它還沒被封裝,很多物件都可以對它做修改…。很快我就可以寫出沒有人能維護的系統了。


二、宣告式編程(Declarative programming),可以解決這種問題。

The term is used in opposition to declarative programming, which expresses what the program should accomplish without prescribing how to do it in terms of sequences of actions to be taken.
     
Functional and logical programming are examples of a more declarative approach.
http://en.wikipedia.org/wiki/Declarative_programming

「宣告式編程」描述邏輯而不管流程。不考慮「順序」和「狀態」。

「宣告式編程」包括:
1.Regular expressions
2.Logic programming (例如:SQL)
3.Functional programming
4.Makeup Language (例如:HTML, MXML, SVG, XAML, XSLT)

以上都算是宣告式編程,但因為範圍太大,不再詳細討論。

三、函數式編程(Functional programming) http://en.wikipedia.org/wiki/Functional_programming

函數程式語言最重要的基礎是 λ 演算(lambda calculus)。而且λ演算的函式可以接受函式當作輸入(引數)和輸出(傳出值)。
和指令式編程相比,函式式編程強調函式的計算比指令的執行重要。
和程式編程相比,函式式編程裏,函式的計算可隨時調用。
函式式編程經常使用遞歸。
純函式式的程式沒有變數和副作用(Side effect)。因為純函式式程式設計語言沒有變數,函式沒有副作用,編寫出的程式可以利用memoization、common subexpression elimination和平行計算在執行時和編譯時得到大量優化。

函式式編程常被認為嚴重耗費在CPU和記憶體資源。主因有二:
早期的函式式編程語言沒有最佳化。
非函式式編程語言為求提昇速度,會在某些部分放棄邊界檢查或垃圾回收等功能。


以下是不同的聲音
http://jonbho.net/2012/01/24/i-want-to-fix-programming/
    It is still composed of many discrete simple steps that excruciatingly calculate the output.