2012年11月27日 星期二

javascript is a(an) OO language?

推薦一本書,javascript patterns
http://shop.oreilly.com/product/9780596806767.do

不少專案在研究javascript如何實作繼承(inheritance)這件事情,者本書的第六章專門討論這個章節,有興趣的人也可以跑去研究coffeescript如何實做這件事情
我思考了這個議題的後續發展multiple inheritance三天,終於了解到了他跟類似C++/Java發展的差異性

看backbone.js跟prototye lib的時候,我一直懷疑,為何要包裝成這樣,感覺不如使用javascript來的直觀,效能稍微也比較差一點,但是仔細想想後,他們都有他們的道理,只能說用javascript來實作C++/Java的語意,實在有一定的難度

我得到的東西

  • javascript prototype, property生成的方式
  • C++/Java在多重繼承上面的考量,在multiple-interface跟multiple-inheritance的實作上的差異
  • javascript如何實作多重繼承(我自己弄了一個,就不野人獻曝了)


整體可以看出,javascript在彈性上面很方便,可是如果要實作多重繼承則是非常吃力,code reuse無法如C++/Java容易,反倒是用另外一種觀點(duck typing),反而來的輕鬆,這樣來說算不算OO呢?我覺得是見仁見智囉

2012年11月19日 星期一

Javascript is OOP?

這是個會引發"聖戰"之類的話題,我想這件事情留給有能力的人去回答,退而在此討論javascript"做得到"跟"做不到"的事情

is-a關係,很多人第一刻在繼承裡面學到的。我們說objC is a objP,也就是說可以把objC當成objP一樣對待,兒子應該跟老爸有相同的四肢構造。

可以先看底下的文章,解釋如何使用javascript的prototype完成繼承
http://peter.michaux.ca/articles/transitioning-from-java-classes-to-javascript-prototypes

首先要解釋的是javascript是duck type的程式語言,很多程式語言都是duck type,也就是一個物件看起來像是鴨子(特徵attributes),走路像鴨子(methods),那麼我們就認定他是一隻鴨子

javascript藉由prototype,隨時隨地可以將一個物件的屬性跟介面加入另外一個物件裡面,讓一個物件看起來像是另外一類的物件,比方說在上面peter給的範例實作了observer pattern,如果今天我有個物件擁有update方法,那我就看起來像是observer,真的是這樣嗎?所以要預防這種事情,絕對的方式是用instanceof來檢驗update方法真的來自observer。第二個問題,跟著如果併入另外一組物件的屬性跟介面(也有update)的時候,兩個function A跟B想要的是不同型態的參數,這時候呼叫的是哪一個update??似乎兩者都可以互通,這是duck type的特性
extends(WeatherModel, Observable);
extends(WeatherModel, Observable2);<=????????????????
function A(o:Observable);<=????????????????
function B(o:Observable2);<=????????????????
可以預期的是上面的程式碼可以順利運作(一定會呼叫某個物件的update,或者某個型態的update),但是未必如你所料

回頭來看java/C++,如果今天要在程式執行期間的實作一組介面,恐怕沒有辦法,你只能期待能不能從java Reflection或者C++的pointer跟強制轉型,擠出一點希望,但反過來說,是你可以確定的是不會讓一個不該屬於某個介面的物件放進一個不應該屬於那個型態的function之內(compile time)

OO上很重的一個觀念是is-a的體現,但兩者不同的做法沒有絕對的好壞,因為OO上is-a的解釋很寬廣。從上面可以看出來java/C++是strong type,所以在這種事情上給了某種保證,但是也失去了彈性,javascript獲取了彈性(duck type),但是也付出了某種代價。
OO的體現差異,上面提到的只是兩者之間在OO方面實作差異的冰山一角,希望能對大家在OO上面有進一步的體驗。

Peter的文章告訴我們不要從語言上面學習OO是個很重要的觀念,同時了解語言的差異在體現OO的特性上也很有幫助。對於學習OO觀念,或許從CRC卡上著手是個不錯的開始

可是也別太過極端,認為任何程式語言都可以實作OO,那恐怕是程度上的區別。不要被程式語言綁架了體現OO的作法,但一個程式語言號稱是OOP亦有他的道理

P.S. 網路上爬了一堆號稱javascript繼承實作的方式(甚至多重繼承),請仔細檢驗,是否能夠達成呼叫super class的constructor?是否能使用super class的variable?這往往跟我們直覺不大一樣,一旦在sub class/instance 呼叫了super class的method,其中帶有super class的variable,很快地會看到interpreter跟你抱怨,那個method不是一個function(奇怪吧!)
比方說下面這個網址的實作,至少就犯了兩三個錯誤
www.amirharel.com/2010/06/11/implementing-multiple-inheritance-in-javascript/

下面是一個例子,討論串中有它的問題
http://www.steinbit.org/words/programming/multiple-inheritance-in-javascript

2012年11月18日 星期日

KML and google map

下雨天,好憂鬱的天氣,百般無聊下,整理舊的硬碟資料,想不到看到以前的kmz檔案,想說打開軟體看一下,結果一開,掛點 orz,想說那就自己來寫吧
就拿起一本之前借來的google map書籍,想來個依樣畫葫蘆,體驗一下google map的威力,結果一查資料,才發現原來...是已經過期了,才一年多前的資料,竟然google map已經從v2搬移到v3,一堆寫法都改變了,傷腦筋!! P.S.看來這也是GPS logger附贈軟體無法運作的原因,因為api改了,這軟體應該是內嵌一個瀏覽器做map的偽裝
已經超過六七年沒寫過javascript了,好吧,接著就是開始跟ajax, jquery, google map, flot裝熟,花了兩天大致上把一些功能寫出來
  • 要能載入kml (google map搞定)
  • 要能顯示速度跟高度(要parse kml,用flot畫圖)
  • 要能依照速度資料點顯示位置(在google map上加上marker跟監控flot的onplothover事件)

基本上完成的圖案類似下面

經過一番研究,終於可以把圖表直接整合到google map上

接下來只要把kml上傳跟管理的功能整合應該就差不多,如果可以應該再來個動畫效果會更精采
直接來個demo影片吧^.^"野人獻曝了

2012年11月8日 星期四

eclipse -- plug-in directory

舊版的eclipse(<3.4)通常把plug-in直接拷貝到eclipse root directory底下的features或者plugins就可以,可是會顯得相當雜亂
在3.4之後導入了P2(Provision Platform),plug-in被安置到eclipse root directory底下的dropins目錄內了,如果是JAR只要直接放到dropins底價即可,但是如果是跟eclipse功能相關的plug-ins則是放在dropins/eclipse底下的features&plugins目錄底下

eclipse -- JRE selection

年代久了,就會有不同的java版本開發的應用程式要維護,就必須選擇相對應的JRE,eclipse可以在[window]->[preference]->[Installed JREs]裡面統一管理JRE
可以在各個專案上,按下滑鼠右鍵,然後選擇[Run as]->[Configurations]內去設定想要的JRE


eclipse -- Tasks

Tasks是指那些用註解寫在檔案內要使用的的東西,預設會使用TODO跟FIXME開頭的註解當作task,後面的註解用來描述要提示的內容,可以打開task view就可以看到需要完成的tasks
同樣的還可以自訂標籤[window]->[preference]->[java]->[compiler]->[Task Tag]
這裡要注意的是tasks跟右邊的Mylyn所主導的Task list是不一樣的,Task list比較偏向專案的工作項目,而非軟體內要注意跟改善的地方

eclipse -- SVN

安裝SVN plug-in,一樣[help]->[Install New Software],跟著選擇Collaboratin下的Subversion SVN Team Provider
安裝完畢之後重新啟動,會詢問要使用Pure Java寫成的SVN Kit或者含有windows native code的JavaHL,我選擇的是SVN Kit,接下來就是依照步驟
切換Perspective到SVN的Perspective底下,可以設定svn server相關設定
最後回到Java perspective,在某個project下按下滑鼠右鍵,選擇[team]->[share project]->svn,跟著依指示設定

eclipse -- 其他資源


  • 反組譯: JD-Eclipse
  • UML: AmaterasUML
  • SVN: VisualSVN Server
  • Tomcat : Sysdeo Tomcat
eclipse的參數可以看這裡
http://cloudtu.blogspot.tw/2007/07/eclipsememo.html
http://developer.51cto.com/art/200906/127163.htm
http://blog.163.com/fushaolin@126/blog/static/163417242201148102452497/

其實還有許多功能,比方說remote debug mode、CVS、GUI、Remote Debug、Android開發,我就不再多談了

eclipse -- JUnit

eclipse一般內建JUnit,所以很方便建立Unit Test,這裡探討JUnit 4以後,在3.0以前,都要小心翼翼的寫名稱testMethodName(),一定要寫setUp()跟tearDown(),現在全部被@Before, @After, @Test取代了
先簡單建立一個Caculator,跟著新增UnitTest檔案,介面詢問使用哪一JUnit版本,當然選4.0,在最下面填入待測試的類別
跟著eclipse很貼心的問你要測試那些方法,勾選一下就可以搞定
跟著就是把沒有的程式碼補齊
這裡看到@Before取代了setUp(),而@After取代了tearDown,@Test也是取代了test這個prefix word,所以即使不命名為testAdd()也無妨,只是我懶著更動
另外一個可以注意到的是package name,把package name跟應用程式的程式碼分開可以避免檔案混雜的問題,除非有特殊必要,不然實在沒必要把test case跟待測試的class放在一起
故意在caculator埋下了一個錯誤,在這裡就可以看到有個測試沒有通過

一般有幾種assert

  • assertEquals(expected, actual)
  • assertEuqals(expected, actual, delta)
  • assertNotNull(actual)
  • assertNull(actual)
  • assertSame(excepted,actual)
  • assertTrue(actual)

大多望文生義,第二個用於floating point計算,畢竟floating point不是連續的,如果要測試例外處理,可以使用fail() function,junit會在引發處記錄錯誤

eclipse -- 安裝web套件

最方便的應該就是直接下載含有J2EE support的eclipse,沒有的話就是自己裝囉,[help]->[install new software],跳出如下圖的介面,先選擇資料來源,eclipse有預設幾個source,先copy url,跟著按下add的時候會有詢問名稱跟url,名稱就自行填寫就可以
過一陣子,就會從網路上下載清單,有好幾個大類,找到"Web, XML, Java EE ...",然後展開,我選了底下幾個plug-in(s),另外又回頭選了幾個兩個server adapter跟web develop tools
按下下一步,他就會自行計算相依性,在按下下一步就會開始安裝,安裝完畢之後會提示重新開啟eclipse

跟著需要一個JSP/Servlet Container,當然選最一般的Tomcat 7.x,其實已經有一段時間沒有使用了,還好差不多,抓回zip檔案解壓縮,新增CATALINA_HOME(之前JAVA_HOME跟CLASSPATH已經設定過了,如果需要參考這個網址),跟著在瀏覽器打入localhost:8080,就會跳出熟悉的畫面
複習一下tomact目錄結構
  • bin Tomcat程式相關指令
  • conf Tomcat設定檔
  • lib Tomcat jar函式庫
  • logs 日誌檔
  • temp 存放暫存檔
  • webapps 網頁程式存放目錄
  • work 存放編譯好的Servlet

跟著就是建立一個新的web project,選擇dynamic web project
跟著會跳出下面的畫面,請使用者設定web container,這也就是為何在之前要安裝一些server adapter plug-in的原因,之後根據指示設定web container的環境

完成後就可以用eclipse來管理tomcat的啟動或者關閉
最後把目前的專案加入到server上去

接下來就是試著新增一個jsp file試驗看看囉,就已index.jsp為範例
比較詭異的是,他竟然不會自行publish到tomcat的目錄,必須我按下run的按鈕才可以,按下run之後會產生一個瀏覽器,要注意是,即使是更新了.jsp檔案,可能也不會即時publish,再算publish上去,也不表示會即時編譯,這可能是我設定的問題
最後可以看到右上角已經變成了Java EE


2012年11月7日 星期三

Ajax

簡單的ajax物件

var xmlHttp;
function createXMLHttpRequest(){
  if(window.ActiveXObject){
    xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
  }else if (window.XMLHttpReqeust){
    xmlHttp=new XMLHttpRequest();
  }
}
基本的屬性跟方法有
abort()
getAllResponseHeaders()
getResponseHeader("header")
open("method","url", asynch, username, password)
send(content)
setRequestHeader("header","value")
<script type="text/javascript" language="javascript">
  // 修改自 AJAX: Getting Started - MDC
  function makeRequest(url) {
    var http_request = false;

    if (window.XMLHttpRequest) { // Mozilla, Safari,...
      http_request = new XMLHttpRequest();
    } else if (window.ActiveXObject) { // IE
      try {
        http_request = new ActiveXObject("Msxml2.XMLHTTP");
      } catch (e) {
        try {
          http_request = new ActiveXObject("Microsoft.XMLHTTP");
        } catch (e) {}
      }
    }

    if (!http_request) {
      alert('Giving up :( Cannot create an XMLHTTP instance');
      return false;
    }
    // 定義事件處理函數為 alterContents()
    http_request.onreadystatechange = function() { 
                                      alertContents(http_request); };
    http_request.open('GET', url, true);
    http_request.send(null);
  }

  function alertContents(http_request) {
    if (http_request.readyState == 4) {
      if (http_request.status == 200) {
        var xmldoc = http_request.responseXML;
        var nodes = xmldoc.getElementsByTagName('area');
        var mesg = "";
        for(var i=0; i<nodes.length; i  ) {
          mesg  = nodes[i].firstChild.nodeValue   "\n";
        }
        //alert(mesg);
        document.getElementById("taichung").innerHTML = mesg;
      } else {
        alert('There was a problem with the request.');
      }
    }
  }
</script>
參考資料:
  http://web.nchu.edu.tw/~jlu/classes/xml/ajax/example1.shtml

2012年11月5日 星期一

Eclipse -- java editor shortcut keys

紀錄一些有用的快捷鍵
ctrl+/ 所選的lines加上comments符號//
alt+/ 跳出補完的建議
ctrl+shift+/ 新增區塊註解/*~*/
ctrl+shift+\ 移除區塊註解/*~*/
ctrl+| 將選取的數行,全部對齊
ctrl+shift+f 格式化程式碼

format(格式化)包含了縮排的風格等等,其他還有一些快速的source code撰寫方式,真的是很方便

getter/setter是為了一些java bean或者value object設定的,不然寫起來還真累人,另外refactoring的工具就不說了,如果看懂refactoring,自然就會用,如果IDE沒有這樣的工具,我覺得refactoring執行起來的困難度真的很高

另外eclipse提供一些有關source code的提示,比方說繼承tree的展示,繼承的members的展示





Eclipse -- package explorer and the setting of jar files

package explorer一般被用來管理檔案跟packages等等設定,但是有時候太多的資訊很繁雜,有filter可以幫忙搞定這些事情
可以看到有許多可以選擇,如果只要專心於java相關檔案,不想要看到project設定的相關檔案只要把Non-java-element勾選起來,他們就會被排除掉

如果需要只專注於某一類檔案,如原始檔案(.java),只要在上面按下滑鼠右鍵,然後選擇Go-Into,那麼一來,該節點就會變成root節點了

另外一個需要設定的往往就是library,絕大多數的library其實是包裝成jar file的形式,只要在project點選滑鼠右鍵,然後選擇Properties,進入java build path選項,就可以新增jar file了







2012年11月4日 星期日

eclipse--view & perspective

打開eclispe之後,看到的樣子大概是這樣吧
整體是工作臺,而view是各種子視窗的統稱,每個view有其特殊功能,如果不小心把某個view關閉了,可以從[windows]=>[show views]=>...找回來

最近.....

其實自己最近看了一堆,寫得很少,也已經不侷限在資訊的東西了,又加上迷上evernote,幾乎所有的東西都往那邊寫了,可能會整理出來的機會就更渺茫了XD畢竟維持兩邊的同步有些困難性在

再者,有些即使是資訊的東西,也不單純屬於linux,比方說最近在翻看eclipse,或許會整理一些有關eclipse的資料。其實對很多人來說,這個已經是個很一般的工具,我也用過一陣子,大多我都在使用netbeans,對eclipse的興致來至於他廣泛的支援性,比方說php之類,也因為是java的關係,跨平台也有不錯的特性,所以不管寫android app、java/jsp、php似乎也都可以用得上,我還真的沒有好好正面碰過他

[2012/11/08]
最近eclipse的更新到了一個地步,短時間內應該不會再碰了,畢竟只是短暫的接觸,主要也是寫下一些我認為比較值得紀錄的地方,真的不適合剛剛接觸程式語言的新手,適合對程式語言與一些IDE有經驗的人