1. 程式人生 > >可維護性的代碼

可維護性的代碼

innerhtml set 修改 container 返回 enable null 隱藏 方法名

什麽是可維護性代碼

1、可理解性(其他人可以接手代碼並理解它的意圖和一般途徑,而無需原開發人員的完整解釋)
2、直觀性(代碼中的東西一看就能明白,不管其操作過程多麽復雜)
3、可適應性(代碼以一種數據上的變化不要求完全重寫的方法撰寫)
4、可擴展性(在代碼架構上已考慮到在未來允許對核心功能進行拓展)
5、可調試性(當有地方出錯時,代碼可以給予你足夠對信息來盡可能直接地確定問題所在)


代碼約定
1、可讀性

a、函數和方法 —— 每個函數或方法都應該包含一個註釋,描述其目的和用於完成任務所可能使用都算法。陳述事先的假設也非常重要,如參數代表,函數是否有返回值(因為這不能從函數定義中推斷出來)
b、大段代碼 —— 用於單個任務的多行代碼應該在前面放一個描述任務的註釋
c、復雜的算法 —— 如果使用了一種獨特的方式解決某個問題,則要在註釋中解釋你是如何做的。
d、hack —— 因為存在瀏覽器差異,js代碼一般會包含一些hack。不要假設其他人在看代碼的時候能夠理解hack所要應付的瀏覽器問題,清將這些信息放在註釋中。

2、變量和函數命名
由於很多js開發人員最初都只是業余愛好者,所以有一種使用無意義名字的傾向,諸如foo,bar,dosomething這樣的名字。專業的js開發人員必須克服這些惡習以創建可維護性的代碼。

a、變量名應為名詞 如car 或 person
b、函數名應該以動詞開始,如getName()。返回布爾類型值的函數一般以is開頭,如isEnable();
c、變量和函數都應該使用合乎邏輯的名字,不要擔心長度。長度問題可以通過後處理和壓縮來緩解

3、變量類型透明
由於在js中變量是松散類型,很容易忘記變量所應包含的數據類型。初始化的時候,在每一行上使用單行註釋

var
found = false; //布爾型 var count = -1; //數字 var name = ‘‘; //字符串 var person = null; //對象


松散耦合
只要應用的某個部分過分依賴於另一部分,代碼就是耦合過緊,難於維護。典型的問題如:對象直接引用另一個對象,並且當修改其中一個的同時需要修改另外一個。
緊密耦合的軟件難於維護並且需要經常重寫。
1、解耦HTML/JavaScript,html和javascript過於緊密的耦合在一起
a、直接寫在html中對js

<script type=‘text/javascript‘>
    document.write(
‘hello world‘); </script>
<input type=‘button‘ value=‘click me‘ onclick=‘doSomething()‘/>

在這個例子中,可能在doSomething()函數可用之前,就已經按下了按鈕,引發了一個js錯誤。因為任何對按鈕行為對更改要同時觸及html和js,因此影響了可維護性。
而這些本該只在js中進行

b、js中包含了html

function inserMessage(msg){
    var container = document.getElementById(‘container‘);
    container.innerHTML = ‘<div class="msg"><p class="post">‘+msg+‘</p><p>latest message above</p></div>‘
}

避免在js中創建大量html。再一次重申保持層次分離,這樣很容易的確定錯誤來源。當使用上面這個例子的時候,有一個頁面布局的問題,可能和動態創建的html沒有被
正確格式化有關。不過,要定位這個錯誤非常困難,因為你可能一般先看頁面的源代碼來查找那段煩人的html,但是卻沒能找到,因為它是動態生成的。對數據或者布局
的更改也會要求更改js,這表明這兩個層次過於緊密耦合了。
推薦,當js用於插入數據時,盡量不要直接插入標記。一般可以在頁面中直接包含並隱藏標記,然後等整個頁面渲染好之後,就可以用js顯示該標記

2、解耦CSS/javascript
a、js中嵌入css

element.style.color = ‘red‘;
element.style.backgroundColor = ‘blue‘;

由於css負責頁面的顯示,當顯示出現任何問題時都應該只是查看css文件夾來解決。然而,當使用了js來更改某些樣式的時候,比如顏色,就出現了第二個可能已更改和
必須檢查的地方。結果是js也在某種程度上負責了頁面的顯示,並與css緊密耦合了。如果未來需要更改樣式表,css和js文件可能都需要修改。這就給開發人員造成了維護
上的噩夢。
推薦,現代web應用常常要使用js來更改樣式,所以雖然不可能完全將css和js解耦,但是還是能讓耦合更松散的

element.className=‘edit‘;

通過只修改某個元素的css類,就可以讓大部分樣式信息嚴格保留在css中。js可以更改樣式類,但並不會直接影響到元素的樣式。
b、css中嵌入js(只在ie中出現)

div{
    width:expression(document.body.offsetWidth - 10 + ‘px‘);
}

好的層次劃分非常重要。顯示問題的唯一來源應該是css,行為問題的唯一來源應該是js。在這些層次之間保持松散耦合可以讓整個應用更加易於維護。

編程實踐
1、尊重對象所有權

不要為實例或原型添加屬性
不要為實例或原型添加方法;
不要重定義已存在的方法;

如果某人期望叫做stopEvent()的函數能取消某個事件的默認行為,但是你對其進行了修改,然後它完成了本來的任務,後來還追加了另外的事件處理程序,那肯定會出現問題。
其他開發人員會認為函數還是按照原來的方式執行,所以他們的用法會出錯並有可能造成危害,因為他們並不知道有副作用。

2、避免全局變量

var name = ‘Nicholas‘;
function sayName(){
    alert(name);
}

這段代碼包含了兩個全局量:變量name和函數sayName()。其實可以創建一個包含兩者的對象
eg:

var MyApplication = {
    name:‘Nicholas‘,
    sayName:function(){
        alert(this.name);
    }
}

這段重寫的代碼引入了一個單一的全局對象MyApplication.name和sayName()都附加在其上。這樣做消除了一些存在於前一段代碼中的一些問題。首先,變量name覆蓋了window.name
屬性,可能會與其他功能產生沖突;其次,它有助消除功能作用域之間的混淆。調用MyApplication.sayName()在邏輯上暗示了代碼的任何問題都可以通過MyApplication的代碼來確定。

3、避免與null進行比較

function sortArray(values){
    if(values != null){ //避免
        values.sort(comparator)
    }
}

該函數的目的是根據給定的比較只對一個數組進行排序。為了函數能正確執行,values參數必需是數組,但這裏的if語句僅僅檢查該values是否為null。還有其他的值可以通過if語句,包括
字符串,數字,他們會導致函數拋出錯誤。

function sortArray(values){
    if(Array.isArray(values)){ //推薦
        values.sort(comparator)
    }
}

如果看到了與null比較的代碼,嘗試使用以下技術替換
如果值應為一個引用類型,使用instanceof操作符檢查其構造函數;
如果值應為一個基本類型,使用typeof檢查其類型;
如果是希望對象包含某個特定的方法名,則使用typeof操作符確保指定名字的方法存在於對象上。

4、使用常量

function validate(value){
    if(!value){
    alert(‘Invalid value!‘);
        location.href=‘/errors/invalid.php‘;
    }
}

在這個函數中有兩段數據:要顯示給用戶段信息以及url。顯示在用戶界面上段字符串應該以允許進行語言國際化段方式抽取出來,url也應被抽取出來,因為它們隨著
應用成長而改變的傾向。
eg:

var Constans = {
    INVALID_VALUE_MSG:‘Invalid value!‘,
    INVALID_VALUE_URL:‘/errors/invalid.php‘
}
function validate(value){
    if(!value){
    alert(Constans.INVALID_VALUE_MSG);
        location.href=Constans.INVALID_VALUE_URL;
    }
}

這些設置允許數據在無須接觸使用它的函數的情況下進行變更。

重復值 —— 任何在多處用到的值都應抽取為一個常量。這就限制了當一個值變了而另一個沒變的時候造成的錯誤。這也包含了css類名。
用戶界面字符串 —— 任何用於顯示給用戶的字符串,都應該抽取出來以方便國際化
URLs —— 在web應用中,資源位置很容易變更,所以推薦用一個公共地方存放所有都url.
任意可能會更改的值 —— 每當你在用到字面量的時候,你都要問一下自己這個值在未來是不是會變化。如果是,那麽這個值就應該被提取出來作為一個常量

可維護性的代碼