方法名中的add和set
瀏覽Java的API文檔是很有意思的事情,比如說:HttpServletResponse。在HttpServletResponse里有三個比較有意思的方法:
public void setHeader(java.lang.String name, java.lang.String value)
public void addHeader(java.lang.String name, java.lang.String value)
先看addCookie,為什么這個方法叫addCookie呢?如果換到PHP里,很多都是定義為:
setCookie($name, $value, array $options)
那么到底是addCookie好?還是setCookie好呢?從閱讀者的直覺上來看,一個set方法往往意味著給某個鍵設置某個值,在這里,鍵就是$name,值就是$value。既然是鍵,就說明其有唯一性,但對Cookie而言,$name是不具備唯一性的,比如說不同域下可以共存同名的Cookie,所以說單就名字而言,addCookie比setCookie更合理,以后大家起名時,不要set,add想用什么就用什么,多思考一下是有好處的。
再看看addHeader和setHeader,為什么會有兩個看似一樣的方法呢?不過換到PHP里,很多都是定義為:
setHeader($name, $value, $replace = true)
那么到底是一個方法好,還是分成兩個方法好?這里先看看如果用一個方法的話,一般如何使用:
setHeader($name, $value, true)
setHeader($name, $value, false)
其中true表示重置先前同名header,false則不是重置,而是追加(用逗號分割,詳見header函數)。
再看看如果用兩個方法的話,情況如何:
setHeader 對應 setHeader($name, $value, true)
addHeader 對應 setHeader($name, $value, false)
對比二者的區別,如果單純使用一個setHeader方法,方法參數里會出現一個布爾型參數,而使用兩個方法的話,則是通過set,add這樣的動詞來區分方法含義的。從閱讀者的角度看,任何時候,布爾型參數都是讓人費解的,不能準確的用直覺去判斷其含義,相對而言,用明確的詞匯來描述方法意圖更好。
Javascript中給select添加option
最容易想到方法是通過innerHTML來添加,代碼如下:
<button id="button">Add</button>
<script>
document.getElementById("button").onclick = function() {
document.getElementById("select").innerHTML = "<option value="bar">foo</option>";
};
</script>
innerHTML使用起來非常方便,可惜這段代碼雖然在Firefox里無恙,但是在IE里卻不會正常運行,解決:
document.getElementById("select").options.add(new Option("foo", "bar"));
new Option([text], [value], [defaultSelected], [selected])
如果你想選中某項,應該使用selected,至于defaultSelected,它表示的是是否缺省選中,如果你使用reset重置功能的話,則有用。
如此一來,就兼容了Firefox和IE了。為了照顧IE這個差等生,習慣用Firefox的我們不得不多考慮一下。
順手記錄options常用的幾種操作:
刪除所有選項:<select>.options.length = 0;
刪除當前選項:<select>.options.remove(<select>.selectedIndex);
獲取當前值 :<select>.options[<select>.selectedIndex].value;
獲取當前文本:<select>.options[<select>.selectedIndex].text;
修改當前節點:<select>.options[index] = new Option("Text", "Value");
PHP領域對象都應該實現ArrayAccess
PHP里,領域對象是否值得使用,存爭議,有的人認為在PHP里,使用數組是最佳實戰;還有的人則認為隨著復雜性的提高,領域對象是救命稻草。拋開細節,先看看兩種方式調用時的最初印象,舉個一般的例子:
數組:<h1><?php echo $article['title']; ?></h1>
對象:<h1><?php echo $article->getTitle(); ?></h1>
數組和對象的選擇,不一定非得是二選一的結果,在項目開發初期,復雜度較低,此時更注重開發效率,使用數組是更好的選擇,但是隨著項目的演化,復雜度越來越高,此時更注重維護效率,使用對象是更好的選擇。所以我們要是能夠在二者之間自由切換就最好不過了。但從上面的代碼可以看到,二者的使用方式存在較大差異,一旦切換,很多調用代碼都要重寫,所以,我們說PHP領域對象都應該實現ArrayAccess,如此一來,你可以通過數組方式來訪問對象,切換就簡單多了。
CRON環境變量問題
使用CRON,基本都遇到過環境變量問題,比如說某個命令沒有找到,一般來說,都是建議使用完整的路徑,以避免依賴系統的PATH環境變量,但其實重新設 置一下PATH之類的環境變量是很簡單的,請看:
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/
寫代碼要細心
看一段PHP代碼,設想一下它的輸出結果,可以用來做面試題:
邏輯的層次劃分
這個問題我印象中已經說過幾次了,不過鑒于其重要性,再說一次也不嫌多。
在MVC中,單就M而言,邏輯分為兩種:應用邏輯和領馭邏輯,不同的邏輯應該放在不同的層次,這樣結構才清晰,比如說這個例子:我的CMS有個功能,有網友回復文章的話,則給文章作者發一封電子郵件通知他一下,同時因為有回復,說明文章受歡迎,就要給文章作者加適當的積分,以資鼓勵。
上面的邏輯不算太復雜,但是編碼時還是應該考慮邏輯分層,如果我們不分層的話,比如說,所有的邏輯都在控制器中完成,會有什么問題呢?假如現在我新加一個邏輯,如果用戶使用手機上網,回復了文章的話,則不使用電子郵件通知,而使用手機短信通知作者,同時給文章作者加積分。由于我們把所有的邏輯都在控制器中實現了,所以其中的積分邏輯被重復實現了,把它單獨劃分成領域邏輯就會避免這個問題了。