Ajax 板


LINE

GWT 一直处在一个很尴尬的角色 我一直不知道该放在 Java 版还是在 Ajax 版讨论 之前都是在介绍 or 教学,跟 JavaScript 还没啥关系 所以就都放在 Java 版 这篇因为谈到了 GWT 处理 JavaScript object 的思维 所以就贴在这里 或许对於 JavaScript 感到厌烦的却又不得不写的人 这是一条生路.... [炸] 如果想了解 GWT 的版友,可以到 http://pt2club.blogspot.com/search/label/GWT 有几篇粗劣的入门文章可以稍微略知一二 =============================================================== 网页版: http://pt2club.blogspot.com/2010/02/gwt-part-2javascript-overlay-type.html ==========================[正文开始]=========================== 原文:http://googlewebtoolkit.blogspot.com/ 2008/08/getting-to-really-know-gwt-part-2.html 技术校正、审阅:tkcn 假设你已经在 GWT module 当中,愉快地使用 JSNI 来呼叫某些手写的 JavaScript。一切运作正常,但是 JSNI 只能在独立的 method 下运作。某些整 合性状况需要你彻底地把 JavaScript 跟 Java 的 object 绑在一起——写 DOM 跟 JSON 就是两个好例子——所以我们十分需要可以从 Java 程式码直接与 JavaScript object 互动的方法。换句话说,我们想要 JavaScript 的 object 看起来就像我们写的 Java object。 GWT 1.5 引入了 JavaScript overlay type,这让 GWT 程式整合各种 JavaScript object 变得容易许多。这个技术有很多好处,像是让你能用 Java IDE 的 code completion 跟 refactoring 功能,即使你写的是 untype 的 JavaScript object。 范例:简单、有效率的 JSON 用一个范例来了解 overlay type 是最简单的方法。假设我们要存取一组「 customer」数据,底层是用 JSON object。在 JavaScript 中的资料结构可能像 这样: void jsonData = [ { "FirstName" : "Ps", "LastName" : "Monkey" }, { "FirstName" : "痞子", "LastName" : "猴" }, { "FirstName" : "Pt2", "LastName" : "Club" }, { "FirstName" : "STO", "LastName" : "Orz" }, ]; 要把一个 Java type 加到上述的资料结构,要从建立一个 JavaScriptObject 的 subclass 开始,这在 GWT 表示是一个 JavaScript 的 object。接着增加一 些 getter。 // An overlay type class Customer extends JavaScriptObject { // Overlay types always have protected, zero-arg ctors protected Customer() { } // Typically, methods on overlay types are JSNI public final native String getFirstName() /*-{ return this.FirstName; }-*/ public final native String getLastName() /*-{ return this.LastName; }-*/ // Note, though, that methods aren't required to be JSNI public final String getFullName() { return getFirstName() + " " + getLastName(); } } 如此一来,GWT 就会了解所有 Customer 的 instance 实际上是来自 GWT module 以外的 JavaScript object。这包含了很多意义。举例来说,看到 getFirstName() 跟 getLastName() 里头的 this reference。它实质上是代表 一个 JavaScript object,所以你操作这个 this 就像在 JavaScript 里头一样 。在这个例子中,我们可以直接存取 JSON 中那些我们已知的 field: this.FirstName 跟 this.LastName。 那麽,你要如何才能真正得到一个被包装成 Java type 的 JavaScript object 呢?你不能用 new Customer() 来建构它,因为重点是把一个既有的 JavaScript object 包装成 Java type。因此,我们必须使用 JSNI 来得到这样 一个 object: class MyModuleEntryPoint implements EntryPoint { public void onModuleLoad() { Customer c = getFirstCustomer(); // Yay! Now I have a JS object that appears to be a Customer Window.alert("Hello, " + c.getFirstName()); } // Use JSNI to grab the JSON object we care about // The JSON object gets its Java type implicitly // based on the method's return type private native Customer getFirstCustomer() /*-{ // Get a reference to the first customer in the JSON array from earlier return $wnd.jsonData[0]; }-*/; } 现在来搞清楚我们做了啥。我们拿到了一个 plain old JSON object(译注:源 自於 POJO)并且建立一个看起来很正常的 Java type,让 GWT 程式码中能够使 用它。於是你就有了 code completion、refactoring、compile 阶段的检查—— 这些写 Java 时所拥有的好处。然而,你还是可以灵活地操作任何 JavaScript object,这使得存取 JSON service(使用 RequestBuilder)变得很轻而易举。 为一些 compiler 强者岔题一下。overlay type 另一个美妙的事情是你可以增 加 Java 的 type,但是却不用影响底层的 JavaScript object。注意到上面例 子中,我们加入的 getFullName() 这个 method。它是纯粹的 Java 程式码(并 不存在於底层的 JavaScript object),但却是依照底层 JavaScript object 所写的。也就是说,处理同一个 JavaScript object,以 Java 的角度会比用 JavaScript 功能丰富得多;而且不用动到底层的 JavaScript object——无论 是 instance 或是 prototype。 (接续上一段的题外话)在 overlay type 增加 method 这个很酷的怪招是可行 的,因为 overlay type 的设计规则是不允许 polymorphic 呼叫,所有的 method 必须是 final 且/或 private。因此,compiler 是静态地解读每一个 overlay type 的 method,所以不需要在 runtime 的时候动态 dispatch。这是 为甚麽我们不用拘泥在 object 的 function pointer;compiler 可以直接对 method 呼叫,就好像是 global function、独立於 object 之外。很明显的, 直接呼叫 function 会比间接快得多。更棒的是,因为呼叫 overlay type 的 method 是静态解读的,这些动作会尝试自动 inline;这在为了 script 语言的 效率而奋战时,是非常强大的火力支援。接下来我们会重新来一遍,展示给你看 这个方法有多成功。 范例:lightweight collection 我们在上面的例子当中掩盖了某些事情。getFirstCustomer() 这个 method 是 非常不切实际的。你一定会希望存取全部的 customer 阵列。所以,我们需要一 个 overlay type 来表示这个 JavaScript 阵列。幸运的是,这很简单: //泛型在 overlay type 里头也运作正常! class JsArray<E extends JavaScriptObject> extends JavaScriptObject { protected JsArray() { } public final native int length() /*-{ return this.length; }-*/; public final native E get(int i) /*-{ return this[i]; }-*/; } 现在我们可以写出更有趣的程式了: class MyModuleEntryPoint implements EntryPoint { public void onModuleLoad() { JsArray<Customer> cs = getCustomers(); for (int i = 0, n = cs.length(); i < n; ++i) { Window.alert("Hello, " + cs.get(i).getFullName()); } } // Return the whole JSON array, as is private final native JsArray<Customer> getCustomers() /*-{ return $wnd.jsonData; }-*/; } 这是一个很乾净的程式码,尤其是以建立灵活配置的角度来看。正如上头提到的 ,compiler 可以作一些十分 fancy 的事情,让它相当有效率。看一下 onModuleLoad() 这个 method 在没有 obfuscate 的 compile 结果: function $onModuleLoad(){ var cs, i, n; cs = $wnd.jsonData; for (i = 0, n = cs.length; i < n; ++i) { $wnd.alert('Hello, ' + (cs[i].FirstName + ' ' + cs[i].LastName)); } } 这个最佳化真的是 xx 的好。即使是 getFullName() 这个 method 的 overhead 也没了。事实上, 所有 Java method 的呼叫动作都不见了。当我们说:「GWT 给你可负担的 abstraction」,这就是其中之一。不仅 inline 的程式码执行速 度明显变快、我们不再需要定义 function 的内容、也因而得以将 script 简短 化(虽然持平而论,inline 的方式也很容易让 script 量变多,所以我们小心 地在速度与程式码大小之间取得平衡)。现在回顾上头原始的 Java 程式码是十 分有趣的,而试着推导 compiler 最佳化的步骤就展示到这边。不过,我们还是 忍不住要 show 一下对应、obfuscate 过的程式码: function B(){var a,b,c;a=$wnd.jsonData;for(b=0,c=a.length;b<c; ++b){ $wnd.alert(l+(a[b].FirstName+m+a[b].LastName))}} 注意在这个版本当中,唯一没有 obfuscate 的是 JavaScript 当中的识别字, 例如 FirstName、 LastName、jsonData 等。这是为甚麽即使 GWT 努力让大量 JavaScript 交互沟通的操作变得容易,但我们还是努力说服别人尽量用纯 Java 来写程式、而不是混着 JavaScript 写。希望你听到我们讲这些之後,你会明白 我们不是要打击 JavaScript——只是我们不能对它们最佳化,这会让我们很沮 丧。 掺在一起作撒尿牛丸 overlay type 是 GWT 1.5 的重要特性。这个技术让直接与 JavaScript library 互相沟通变得相当容易。希望在读完这篇文章之後,你可以想像如何以 一组 Java type 直接导入任何 JavaScript library 到 GWT 里头,进而使用 Java IDE 来进行高效率的开发跟 debug,却不会因为任何类型的 GWT overhead 而影响程式码大小或执行速度。同时,overlay type 作为一个强大的 abstraction 工具,提供更优雅的低阶 API,例如新的 GWT DOM package 。 -- 钱锺书: 说出来的话 http://www.psmonkey.org 比不上不说出来的话 Java 版 cookcomic 版 只影射着说不出来的话 and more...... --



※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 61.228.193.140







like.gif 您可能会有兴趣的文章
icon.png[问题/行为] 猫晚上进房间会不会有憋尿问题
icon.pngRe: [闲聊] 选了错误的女孩成为魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一张
icon.png[心得] EMS高领长版毛衣.墨小楼MC1002
icon.png[分享] 丹龙隔热纸GE55+33+22
icon.png[问题] 清洗洗衣机
icon.png[寻物] 窗台下的空间
icon.png[闲聊] 双极の女神1 木魔爵
icon.png[售车] 新竹 1997 march 1297cc 白色 四门
icon.png[讨论] 能从照片感受到摄影者心情吗
icon.png[狂贺] 贺贺贺贺 贺!岛村卯月!总选举NO.1
icon.png[难过] 羡慕白皮肤的女生
icon.png阅读文章
icon.png[黑特]
icon.png[问题] SBK S1安装於安全帽位置
icon.png[分享] 旧woo100绝版开箱!!
icon.pngRe: [无言] 关於小包卫生纸
icon.png[开箱] E5-2683V3 RX480Strix 快睿C1 简单测试
icon.png[心得] 苍の海贼龙 地狱 执行者16PT
icon.png[售车] 1999年Virage iO 1.8EXi
icon.png[心得] 挑战33 LV10 狮子座pt solo
icon.png[闲聊] 手把手教你不被桶之新手主购教学
icon.png[分享] Civic Type R 量产版官方照无预警流出
icon.png[售车] Golf 4 2.0 银色 自排
icon.png[出售] Graco提篮汽座(有底座)2000元诚可议
icon.png[问题] 请问补牙材质掉了还能再补吗?(台中半年内
icon.png[问题] 44th 单曲 生写竟然都给重复的啊啊!
icon.png[心得] 华南红卡/icash 核卡
icon.png[问题] 拔牙矫正这样正常吗
icon.png[赠送] 老莫高业 初业 102年版
icon.png[情报] 三大行动支付 本季掀战火
icon.png[宝宝] 博客来Amos水蜡笔5/1特价五折
icon.pngRe: [心得] 新鲜人一些面试分享
icon.png[心得] 苍の海贼龙 地狱 麒麟25PT
icon.pngRe: [闲聊] (君の名は。雷慎入) 君名二创漫画翻译
icon.pngRe: [闲聊] OGN中场影片:失踪人口局 (英文字幕)
icon.png[问题] 台湾大哥大4G讯号差
icon.png[出售] [全国]全新千寻侘草LED灯, 水草

请输入看板名称,例如:e-shopping站内搜寻

TOP