EXTJS4官方文檔翻譯系列一:類系統和編碼規范

一,概述



——————————————————————————–


ExtJS4擁有超過300個的類.迄今為止,我們的社區擁有超過20萬來自世界各地,使用不同後臺語言的開發者.要在這種規模的框架上提供具有以下特點的架構,需要面臨巨大的挑戰:


1,簡單易學。2,快速開發、調試簡單、部署容易。3,良好的結構、可擴展性和可維護性。
javascript是一種類無關(原文:classless)、基於原型的語言。因此javascript最強大的特點是靈活。同樣的事情可以使用不同的方式,不同的編碼風格和技巧去完成。這個特點也會帶來一些不可預測的風險。如果沒有統一的編碼規范,javascript代碼將很難理解、維護和復用。


相反的,基於類的編程語言擁有較為流行的面向對象模型,強類型、內建的封裝機制和強制的編碼約束等特點。通過強制開發人員遵守一些大的原則來使代碼的行為更容易被理解,以及提高可擴展性(這裡不明白,javascript這類動態語言不是更容易擴展麼?)和可伸縮性。但是,這類語言沒有javascript的靈活性。


二,命名約定



——————————————————————————–


在所有類、命名空間(namespace)和文件名中使用一致的命名約定,有助於保持代碼的良好結構和可讀性。


1)類


類名隻能包含字母和數字。允許包含數字,但是大部分情況下不建議使用,除非這些數字是專業術語的一部分。不要使用下劃線,連字符等非數字字母符號。例如:


MyCompany.useful_util.Debug_Toolbar 不建議


MyCompany.util.Base64 合適的(雖然包含數字,但是數字是術語的一部分)
類名應該包含在使用點號分隔的命名空間中。至少,要有一個頂級命名空間。例如:


MyCompany.data.CoolProxyMyComp


MyCompany.data.CoolProxyMyCompa
頂級命名空間和實際的類名應使用駝峰命名(CamelCased),其他則為小寫。例如:


MyCompany.form.action.AutoLoad
不是Sencha開發的類(即不是Ext自帶的)不要使用Ext做為頂級命名空間。


縮寫也要遵守以上的駝峰式命名約定。例如:


Ext.data.JsonProxy而不是Ext.data.JSONProxy
MyCompany.util.HtmlParser而不是MyCompary.parser.HTMLParser
MyCompany.server.Http而不是MyCompany.server.HTTP
2)代碼文件


類名對應類所在的文件(包括文件名)。因此,每個文件應該隻包含一個類(類名和文件名一樣)。例如:


Ext.util.Observable 存儲在 path/to/src/Ext/util/Observable.js
Ext.form.action.Submit 存儲在 path/to/src/Ext/form/action/Submit.js
MyCompany.chart.axis.Numeric 存儲在 path/to/src/MyCompany/chart/axis/Numeric.js
path/to/src 是你應用程序所在目錄。所有類都應該在這個通用根目錄下,並且使用適當的命名空間以利於開發、維護和部署。


3)方法和變量


和類命名一樣,方法和變量也隻能包含字母和數字。數字同樣是允許但不建議,除非屬於專業術語。不要使用下劃線,連字符等任何非字母數字符號。


方法和變量名一樣使用駝峰式命名,縮寫也一樣。


舉例


合適的方法名:
                    encodeUsingMd5() getHtml() 代替 getHTML()


                    getJsonResponse() 代替 getJSONResponse()


                    parseXmlContent() 代替parseXMLContent()


合適的變量名:
                    var isGoodName


                    var base64Encoder


                    var xmlReader


                    var httpServer
4)屬性


類屬性名稱遵循以上的變量和方法命名約定.除非是靜態的常量.


類的靜態屬性常量應該全部大寫。例如:


Ext.MessageBox.YES = “Yes”
Ext.MessageBox.NO = “No”
MyCompany.alien.Math.PI = “4.13”
三,動手實踐


1).聲明


1.1) 舊的方式


如果你曾經使用過舊版本的extjs,那麼你肯定熟悉使用Ext.extend來創建一個類:


   1: varMyWindow=Ext.extend(Object,{…});
 


 


 


這個方法很容易從現有的類中繼承創建新的類.相比直接繼承,我們沒有好用的API用於類創建的其他方面,諸如:配置、靜態方法、混入(Mixins)。呆會我們再來詳細的重新審視這些方面。現在,讓我們來看看另一個例子:


   1: My.cool.Window = Ext.extend(Ext.Window, { … });
 


 


在這個例子中,我們創建我們的新類,繼承Ext.Window,放在命名空間中。我們有兩個問題要解決:


1,在我們訪問My.cool的Window屬性之前,My.cool必須是一個已有的對象.


2,Ext.Window必須在引用之前加載.
第一個問題通常使用Ext.namespace(別名Ext.ns)來解決.該方法遞歸創建(如果該對象不存在)這些對象依賴.比較繁瑣枯燥的部分是你必須在Ext.extend之前執行Ext.ns來創建它們.


   1: Ext.ns(My.cool);   2: My.cool.Window = Ext.extend(Ext.Window, { … });
第二個問題不好解決,因為Ext.Window可能直接或間接的依賴於許多其他的類,依賴的類可能還依賴其它類…出於這個原因,在ext4之前,我們通常引入整個ext-all.js,即使是我們隻需要其中的一小部分.


1.2) 新的方式


在Extjs4中,你隻需要使用一個方法就可以解決這些問題:Ext.define.以下是它的基本語法:


   1: Ext.define(className, members, onClassCreated);
className: 類名
members:代表類成員的對象字面量(鍵值對,json)
onClassCreated: 可選的回調函數,在所有依賴都加載完畢,並且類本身建立後觸發.由於類創建的新的異步特性,這個回調函數在很多情況下都很有用.這些在第四節中將進一步討論


例如:


   1: Ext.define(My.sample.Person, {   2:     name: Unknown,   3:     4:     constructor: function(name) {   5:         if (name) {   6:             this.name = name;   7:         }   8:     9:         return this;  10:     },  11:    12:     eat: function(foodType) {  13:         alert(this.name + ” is eating: ” + foodType);  14:    15:         return this;  16:     }  17: });  18:    19: var aaron = Ext.create(My.sample.Person, Aaron);  20:     aaron.eat(“Salad”); // alert(“Aaron is eating: Salad”);
註意我們使用Ext.create()方法創建瞭My.sample.Person類的一個新實例.我們也可以使用新的關鍵字(new My.sample.Person())來創建.然而,建議養成始終用Ext.create來創建類示例的習慣,因為它允許你利用動態加載的優勢.更多關於動態加載信息,請看入門指南:入門指南


2).配置


在ExtJS 4 ,我們引入瞭一個專門的配置屬性,用於提供在類創建前的預處理功能.特性包括:


配置完全封裝其他類成員
getter和setter.如果類沒有定義這些方法,在創建類時將自動生成配置的屬性的getter和setter方法。
同樣的,每個配置的屬性自動生成一個apply方法.自動生成的setter方法內部在設置值之前調用apply方法.如果你要在設置值之前自定義自己的邏輯,那就重載apply方法.如果apply沒有返回值,則setter不會設置值.看下面applyTitle的例子:    1: Ext.define(My.own.Window, {   2:    /** @readonly */   3:     isWindow: true,   4:     5:     config: {   6:         title: Title Here,   7:     8:         bottomBar: {   9:             enabled: true,  10:             height: 50,  11:             resizable: false  12:         }  13:     },  14:    15:     constructor: function(config) {  16:         this.initConfig(config);  17:    18:         return this;  19:     },  20:    21:     applyTitle: function(title) {  22:         if (!Ext.isString(title) || title.length === 0) {  23:             alert(Error: Title must be a valid non-empty string);  24:         }  25:         else {  26:             return title;  27:         }  28:     },  29:    30:     applyBottomBar: function(bottomBar) {  31:         if (bottomBar && bottomBar.enabled) {  32:             if (!this.bottomBar) {  33:                 return Ext.create(My.own.WindowBottomBar, bottomBar);  34:             }  35:             else {  36:                 this.bottomBar.setConfig(bottomBar);  37:             }  38:         }  39:     }  40: });
以下是它的用法:


   1: var myWindow = Ext.create(My.own.Window, {   2:     title: Hello World,   3:     bottomBar: {   4:         height: 60   5:     }   6: });   7:     8: alert(myWindow.getTitle()); // alerts “Hello World”   9:    10: myWindow.setTitle(Something New);  11:    12: alert(myWindow.getTitle()); // alerts “Something New”  13:    14: myWindow.setTitle(null); // alerts “Error: Title must be a valid non-empty string”  15:    16: myWindow.setBottomBar({ height: 100 }); // Bottom bars height is changed to 100
3.Statics


靜態成員可以使用statics配置項來定義


   1: Ext.define(Computer, {   2:     statics: {   3:         instanceCount: 0,   4:         factory: function(brand) {   5:             // this in static methods refer to the class itself   6:             return new this({brand: brand});   7:         }   8:     },   9:    10:     config: {  11:         brand: null  12:     },  13:    14:     constructor: function(config) {  15:         this.initConfig(config);  16:    17:         // the self property of an instance refers to its class  18:         this.self.instanceCount ++;  19:    20:         return this;  21:     }  22: });  23:    24: var dellComputer = Computer.factory(Dell);  25: var appleComputer = Computer.factory(Mac);  26:    27: alert(appleComputer.getBrand()); // using the auto-generated getter to get the value of a config property. Alerts “Mac”  28:    29: alert(Computer.instanceCount); // Alerts “2”
四.錯誤處理&調試


Extjs 4包含一些有用的特性用於調試和錯誤處理.


你可以使用Ext.getDisplayName()來顯示任意方法的名字.這對顯示拋出異常的類和方法非常有用.
   1: throw new Error([+ Ext.getDisplayName(arguments.callee) +] Some message here);
當使用Ext.define()定義的類中的方法拋出異常後.你將在調用堆棧中看到類和方法名(如果你使用webkit).例如,以下是chrome瀏覽器的效果:


Call Stack

You May Also Like