關於GWT如何與Application層進行整合一些思考

boommen發表於2008-02-22
大家好!最近在做GWT的專案,對GWT如何同Server端的服務進行整合有一些想法,希望能和大家討論一下。
使用GWT的RPC與Server通訊時,需要定義兩個Service介面,分別代表同步和非同步呼叫。在介面中可以直接定義業務邏輯相關的方法如login, logout,這是是最直接的方式,它的好處是:
1 Client端呼叫時非常簡單,直接;
2 Client端的呼叫如何轉換為Server端的呼叫由GWT負責;
它的缺點是:
1 隨著Client端業務的增加,會不斷的增加新的介面,或者在已有介面中增加新的方法;
2 每一個業務方法都需要在兩個介面中定義;
3 每一個業務方法都需要在Server端實現;
4 Client對Server的每一個呼叫,都要由相應的Application層程式碼完成。由於Application層接受的引數和返回值可能是屬於 Application層的類,如果GWT的程式碼和這些類產生耦合,GWT的編譯器會將大量的Java程式碼轉換成JavaScript程式碼,所以在 Client端的Service介面與Application層提供的介面雖然可能有一致的業務邏輯語義,但卻不能有同樣的簽名。這意味著GWT需要定義一套類似Application層的介面,Server端的介面實現負責將GWT的呼叫轉換成對Application層的呼叫,再將 Application層的返回結果轉換為GWT能夠接受的形式(DTO),這一過程會很繁瑣。比如要實現login業務,需要做的事情包括:
1)在Client端定義LoginService介面及方法;
2)在Client端定義LoginServiceAsync介面及方法;
3)在Server端實現LoginService介面的方法;
4)在介面實現中將引數轉換為Application層的資料(如果需要的話),呼叫Application層的方法,並將返回值轉換成GWT可接受的形式。

另外一個想法是,Client端的Service介面中只定義一個方法:
GWTResponse handleRequest( GWTRequest request);
所有的業務請求都透過這個介面傳送給Server端,Server端根據request中的引數決定如何使用Application層,以及如何將處理返回值。
這種做法的好處是
1 Client端的Serivce介面非常穩定,不需要維護;
2 Server端只需要實現一個介面的一個方法;
3 可以在架構設計上想一些辦法,方便的實現GWT的請求對映為對Application層的請求,包括引數的轉換和返回值的轉換,而不需要程式設計師編碼實現;
缺點是:
1 Client端的呼叫不如上一種方法直觀;
2 有兩種方法定義request和response,一種是對於每一種請求定義不同的類,如LoginRequest,LoginResponse,這種方法的好處是直觀,有編譯檢查,缺點是增加類的數量;另一種方法是使用類似於Map的容器,好處是不需增加類的數量,缺點是沒有編譯檢查,Client端和 Server端的一致性需要程式設計師來保證。對第二種方法可以進行增強,如定義常量類規定引數名稱和返回值名稱,但這樣又要增加類的數量;

第二種想法實質上是模仿了Servlet架構的設計。在Servlet的api中,service方法負責接收瀏覽器的引數,並生成響應結果。在 Servlet中,所有的引數都是String,包括命令也是String,響應結果也是以String的形式傳送給瀏覽器,這實際上是犧牲了Java作為一種強型別語言的特性(型別檢查,方法呼叫),因為發起請求的瀏覽器使用的語言(Html)和協議(Http)並不是專為Java設計,是不得已而為之;而在GWT中,Client端已經將請求的形式轉為Java語言,那為什麼還要轉化為類似Request的方式,而不是直接呼叫相應的方法(LoginService.login())呢?我認為主要是GWT這個框架的限制導致的,GWT實現了Client和Server在語言上的統一(Java),但卻並不見得完全沒有阻抗,比如GWT要求定義兩個介面(同步和非同步),在Server端必須對介面進行實現,為避免轉換太多的Java程式碼而不能直接使用Application的介面定義等等,這些限制使得我們不能像使用Swing一樣得心應手,為了符合規定而書寫大量的程式碼。

相關文章