大部分情況下,我們面臨的背景是:
設(shè)計者高高在上,不食人間煙火,只是提供約束,不要這樣,必須那樣,而不是提供方法和可以復(fù)用的API。
開發(fā)者是處于解決問題的一線,飽嘗重復(fù)造輪子的疾苦,他們最需要的是快速的解決問題,以更恰當(dāng)?shù)姆绞焦ぷ?,尋找更容易?gòu)建系統(tǒng)的技術(shù)和方式。
Jquery給設(shè)計者上了很好的一課。
Jquery就像一個魔法師一樣,$()就像魔法棒一樣,隨手一指,一個木偶變復(fù)活了,一瞬間具備了各種各樣的復(fù)雜的能力。
1)分離和粘合
在jquery的身上得到淋漓的體現(xiàn)。不僅是分離結(jié)構(gòu)(structure)和行為功能(behaviour),在強調(diào)分離的同事,提供了強大的連接、粘合的能力。
1.結(jié)構(gòu) <div id="div_portlet"></div>
2.功能 function tooltip(){}
3.粘合 $("#div_portlet" ).tooltip(); //對于開發(fā)者,一行代碼就達(dá)到設(shè)計上的分層分離和功能實現(xiàn)兩個目標(biāo)了。
同樣是使用傳統(tǒng)的javacript library, 所謂OO的做法如下:
<script> var tootip = new Tooltip(); //創(chuàng)建OO對象</script>
<div id="div_portlet" onmouseover="tooltip.display();" onmouseout="tooltip.hide();" ></div>
兩者對比,可以看出,Jquery非常非常的體貼開發(fā)者,通過強內(nèi)聚的API的設(shè)計,封裝,再封裝,一個方法包辦了onmouseover和onmouseout兩個事件,擦屁股的事情也解決了。
想象以前,是怎么給一個table或DIV做圓角的,很多的方案是CSS+圓角圖片,很麻煩,圖片的背景還要符合頁面環(huán)境的顏色。
jquery是怎么做的:$("#div_portlet" ).corner(); //搞定,不需要CSS,不需要圖片。
2)封裝,封裝,再封裝
Write less. Do more, 是Jquery的口號。
也應(yīng)當(dāng)是每個設(shè)計者設(shè)計API牢記的,API的設(shè)計宗旨就是要,苦了我一個,幸福無數(shù)人的精神。參見【好事要做到底,我們需要full stack的API設(shè)計 】。
有人說,Jquery的代碼太亂,真是有閑工夫,我還在Javaeye論壇上,見過別人說Spring的代碼亂,還有人說JBPM的代碼像一托屎。這些偉大的框架,都是自己封裝了復(fù)雜度,竭力把最簡潔的API留給使用者,讓你專注于自己該做的事情。換來的卻是責(zé)難。
可惜的是,我們用別人的庫是,總是要做一大堆的事情,才完成一個復(fù)雜的功能。
例如我們在顯示Flash Object時,使用swfObject.js 需要完成的代碼是:
<script type="text/javascript">
var so = new SWFObject("../open-flash-chart/open-flash-chart.swf", "ofc", "250", "200", "9", "#FFFFFF");
so.addVariable("data-file", "../data-files/data-60.txt");
so.addParam("allowScriptAccess", "always" );//"sameDomain");
so.write("my_chart");
</script>
同樣使用JQuery jQuery Flash Plugin,一條代碼就搞定了。
$('#hello').flash(
{ src: 'hello.swf' },
{ expressInstall: true }
);
3) 充分利用倒鉤(hook)、回調(diào)(callback) 定制行為
在API的默認(rèn)behaviour不能滿足要求的前提下,使用hook、callback,可以讓API的調(diào)用者,可以盡最大程度的定制自己、添加自己的特殊行為。Jquery的core、Plug-in,都大量的使用了這種技巧。
如:$("div_content").toggle(); // 默認(rèn)是切換hide 和 dispaly 兩者行為。
如果你想在切換時,做一點其他的事情。如通知另一個控件。
可以:$("div_content").toggle(function(){
//可以發(fā)送消息,或出發(fā)事件。
});
4) 減少代碼的行數(shù)是降低復(fù)雜度的最有效方式
http://www.netvibes.com
是一個portal網(wǎng)站,它的portal使用了Mootool的javascript框架, javascript的總行數(shù)將近6萬行。Mootool的OO確實做的很好,號稱適合在大型、復(fù)雜的應(yīng)用中使用,可惜在復(fù)雜的應(yīng)用當(dāng)中,過度的OO,并不能提供簡潔的功能,繼承的濫用反而增加了復(fù)雜度和維護的難度。
我down下來代碼后,看了看,覺得 如果使用Jquery,代碼最少能縮小一半。
如果你一定要堅持你的應(yīng)用是大型的javascript應(yīng)用(盡管沒有標(biāo)準(zhǔn)衡量),你就喜歡Class,看不到這個單詞,你就不爽??纯聪旅娴奈淖?。
5). OO和JQuery的結(jié)合
很多人并不了解OO,對于OO不過是葉公好龍吧了,以為OO,就是一定要出現(xiàn)個Class, 然后在不斷的new 來new去,這就是OO的編程。本來一個Utility的方法,非要OO,結(jié)果先要new一個Object, 然后在調(diào)用Ojbect的方法。
OO是這樣子嗎?當(dāng)然不是,封裝、繼承、多態(tài),是OO的核心。
OO的編程雖然可以幫助用戶開發(fā)高度有彈性、易擴展、以維護的程序,但前提是要理解OO。
如果我們不滿足于使用Jquery的API、plug-in的功能,我們想用它來作為我們開發(fā)大型OO-based 項目的基礎(chǔ)javascript框架時,我們?nèi)匀豢梢酝ㄟ^plug-in的方式,讓JQuery具有OO編程的基礎(chǔ)框架的功能。
Low Pro for jQuery
是一個模擬prototye OO 的Jquery plug in, 是你可以用Prototype的OO方式編程。
使用插件前的API的調(diào)用方式
$('#example4').draggable({ helper: 'clone', revert: true });
假設(shè)我們遇到了復(fù)雜的情況,想改變draggable的情況,這是只有修改源文件了。
使用插件后,我們可以通過類,繼承類來改變對象的行為。
Draggable = $.klass({
initialize: function(options) { },
onmousedown: function() {}
});
通過繼承來擴展對象的行為:
GhostedDraggable = $.klass(Draggable, {
onmousedown: function($super) {
$super();
//此處可以編寫自定義的行為代碼
}
});
然后通過attach的方法綁定到制定的DIV上:
$('div.product').attach(GhostedDraggable, { anOption: thing });
6).在應(yīng)用中,盡可能的使用一個框架,便于技術(shù)積累。
Jquery可以滿足你大部分的要求,不是做不到,是你不知道, 你不知道Jquery的有這樣的能力罷了。
我做的最近一個Portal項目,javascript全部是基于Jquery的,參見下圖。
使用的插件不多,但都實用。
JTab、Draggable、Selectable、Sortable、Jcorner、Jtip
那個chart也是基于Jquery, 不過是拿過來經(jīng)過經(jīng)過改進的。
至于我們基于jquery的編程風(fēng)格就不用多說了。