成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

《代碼整潔之道》讀書筆記

pakolagij / 3266人閱讀

摘要:但大多數(shù)情況下應(yīng)該盡量利用一些機(jī)制將二元函數(shù)轉(zhuǎn)換成一元函數(shù)。應(yīng)該為起一個(gè)更能描述函數(shù)功能的函數(shù)名副作用在于對(duì)這個(gè)調(diào)用函數(shù),顧名思義,就是用來檢查密碼。注釋及其描述的代碼之間的聯(lián)系應(yīng)該顯而易見。受控異常的代價(jià)就是違反開放閉合原則。

大師級(jí)的程序員把系統(tǒng)當(dāng)作故事來講,而不是當(dāng)作程序來寫。

有意義的命名 做有意義的區(qū)分

如果同一作用范圍內(nèi)兩樣不同的東西不能重名,那其意思也應(yīng)該不同才對(duì)。那么這兩樣?xùn)|西應(yīng)該取不同的名字而不是以數(shù)字區(qū)分。如果以下代碼參數(shù)名改為 sourcedestination,這個(gè)函數(shù)就會(huì)像樣許多

public static void copyChars(char a1[], char a2[]){
    for(int i = 0; i < a1.length; i++){
        a2[i] = a1[i];
    }
}

以數(shù)字系列命名(a1、a2、a3...)是依意義命名的對(duì)立面。這樣的名稱完全沒有提供正確的信息

Info和Data就像a、an和the一樣,是意義含糊的廢話。但有時(shí)候只要體現(xiàn)出有意義的區(qū)分,使用a和the這樣的前綴就沒錯(cuò)

廢話都是冗余的。Variable一詞永遠(yuǎn)不應(yīng)當(dāng)出現(xiàn)在變量名中。Table一詞永遠(yuǎn)不應(yīng)該出現(xiàn)在表名中

避免思維映射

例如循環(huán)中的 i、j、k 等單字母名稱不是個(gè)好選擇;讀者必須在腦中將它映射為真實(shí)概念。最好用 filter、map 等方法代替 for循環(huán)

類名與方法名

類名和對(duì)象名應(yīng)該是名稱或名詞短語

方法名應(yīng)該是動(dòng)詞或動(dòng)詞短語

每個(gè)概念對(duì)應(yīng)一個(gè)詞

例如 fetch、retrive、 get 表達(dá)同一個(gè)意思,應(yīng)該選定一個(gè),然后在各個(gè)類中使用相同的方法名。

別用雙關(guān)語

避免將同一單詞用于不同的目的。同一術(shù)語用于不同概念,基本上就是雙關(guān)語了。

使用解決方案領(lǐng)域名稱

記住,只有程序員才會(huì)讀你的代碼。所以,盡管用那些計(jì)算機(jī)科學(xué)(Computer Science,CS)術(shù)語、算法名、模式名等。

動(dòng)詞與關(guān)鍵字

給函數(shù)取個(gè)好名字,能較好地解釋函數(shù)的意圖,以及參數(shù)的順序和意圖。

對(duì)于一元函數(shù),函數(shù)和參數(shù)應(yīng)當(dāng)形成一種非常良好的動(dòng)詞/名詞形式。

// good
write(name)
// better
// 更具體,它告訴我們,"name"是一個(gè)"field"
writeField(name)

函數(shù)名稱的關(guān)鍵字(keyword)形式。使用這種形式,把參數(shù)的名稱編碼成了函數(shù)名

// bad
assertEqual(expected, actual);

// good 
// 這大大減輕了記憶參數(shù)順序的負(fù)擔(dān)
assertExpectedEqualsActual(expected, actual);

函數(shù) 短小

函數(shù)第一條規(guī)則是要短小。第二條規(guī)則不是要短小。越短小越好,20行封頂

if、else、while等語句,其中的代碼應(yīng)該只有一行。該行大抵應(yīng)該是一個(gè)函數(shù)調(diào)用語句。因?yàn)閴K內(nèi)的函數(shù)擁有較具體說明性的名稱,從而增加了文檔上的價(jià)值

只做一件事

確保函數(shù)不能被再拆分

參數(shù)

最理想的參數(shù)數(shù)量是零,其次是一,再次是二,應(yīng)盡量避免三

不要傳遞標(biāo)識(shí)參數(shù),標(biāo)識(shí)參數(shù)大聲宣布函數(shù)不是做一件事。如果標(biāo)識(shí)為 true 將會(huì)這樣,標(biāo)識(shí)為 false 則會(huì)那樣

二元函數(shù):有些時(shí)候兩個(gè)參數(shù)正好。例如 Point p = new Point(0, 0);因?yàn)辄c(diǎn)天生擁有兩個(gè)參數(shù)。但大多數(shù)情況下應(yīng)該盡量利用一些機(jī)制將二元函數(shù)轉(zhuǎn)換成一元函數(shù)。例如,把writeField 方法寫成outputStream的成員之一

// bad
writeField(outputStream, name);
// good
outputStream.writeFiled(name);

參數(shù)對(duì)象:如果函數(shù)看起來需要兩個(gè)、三個(gè)、或三個(gè)以上參數(shù),就說明其中一些應(yīng)該封裝為類了

// bad
Circle makeCircle(double x, double y, double, radius);
// good
Circle makeCircle(Point center, double radius);

從參數(shù)封裝成對(duì)象,從而減少參數(shù)數(shù)量,看起來像是在作弊,但實(shí)則并非如此。當(dāng)一組參數(shù)被共同傳遞,就像上例中的x和y那樣,往往就是該有自己名稱的某個(gè)概念的一部分

無副作用

確保函數(shù)功能就像函數(shù)名描述的一樣,不要做函數(shù)名描述以外的事情。應(yīng)該為起一個(gè)更能描述函數(shù)功能的函數(shù)名

public UserValidator {
    private Cyptographer cyptographer;
    
    public boolean checkPassword(String userName, String password) {
        User user = UserGateway.findByName(userName);
        if(user != User.NULL) {
            String codePhrase = user.getPhraseEncodedByPassword();
            String phrase = cyptographer.decrypt(codePhrase, password);
            if("Valid Password".equals(phrase)) {
                // 副作用在于對(duì)這個(gè)調(diào)用
                // checkPassword函數(shù),顧名思義,就是用來檢查密碼。該名稱并未暗示它會(huì)
                // 初始化該次會(huì)話??梢灾孛麨?checkPasswordAndIntializeSession
                Session.initialize();
                return true;
            }
        }
        return false;
    }
}

普通而言,應(yīng)該避免使用輸出參數(shù),如果函數(shù)必須要修改某種狀態(tài),就修改所屬對(duì)象的狀態(tài)

// bad
// 讀者會(huì)弄不清s是輸入?yún)?shù)還是輸出參數(shù)
// 也會(huì)弄不清這函數(shù)是把s添加到什么東西后面,還是把什么東西添加到s后面
appendFooter(s); 
// 函數(shù)簽名
public void appendFooter(StringBuffer report){}

// good
report.appendFooter();

分隔指令與詢問

函數(shù)要行做什么事( 例如 user.setName("xxx") )、要么回答什么事( 例如 user.isVip() )。一個(gè)函數(shù)里不要把兩件事都干了。

如何寫出好函數(shù)

分解函數(shù)

修改名稱

消除重復(fù)

注釋 好的注釋

法律信息

警示性注釋

TODO 注釋雖好,但也要定期查看,刪除不再需要的

壞的注釋

循規(guī)式注釋。 例如每個(gè)函數(shù)都要有Javadoc或每個(gè)變量都要有注釋的規(guī)矩全然是愚蠢可笑的。這類注釋徒然讓代碼變得散亂

注釋掉的代碼。 現(xiàn)在已經(jīng)有源代碼控制系統(tǒng),不要的代碼應(yīng)該立即刪掉

不明顯的聯(lián)系。 注釋及其描述的代碼之間的聯(lián)系應(yīng)該顯而易見。注釋的作用是解釋未能自行解釋的代碼。如果注釋本身還需要解釋,就太遺憾了

切斷代碼間的聯(lián)系

// bad
public class ReportConfig {
    //
    // The class name of the reporter listener
    //
    private String m_className;
    
    //
    //The properties of the reporter listener
    //
    private List m_properties = new ArrayList();
    
    public void addProperty(Property property) {
        m_properties.add(property);
    }
}

// good
public class ReportConfig {
    private String m_className;
    private List m_properties = new ArrayList();
    
    public void addProperty(Property property) {
        m_properties.add(property);
    }
}

格式 垂直距離

變量聲名。 大多數(shù)情況下變量聲名應(yīng)該盡可能靠近其使用的位置。但是在類內(nèi),變量聲名應(yīng)該統(tǒng)一放在頂部,因?yàn)檫@樣讀者可以一眼看出這個(gè)類有什么變量。

相關(guān)函數(shù)。 若某個(gè)函數(shù)調(diào)用了另一個(gè)函數(shù),就應(yīng)該把它們放到一起,而且調(diào)用者應(yīng)該盡可能放在被調(diào)用者上面。這樣程序就有個(gè)自然順序。

概念相關(guān)。 概念相關(guān)的代碼應(yīng)該放到一起。相關(guān)性越強(qiáng),彼此之間的距離就該越短

public    class Assert {
    static public void assertTrue(String message, boolean codition(){}
    static public void assertTrue(boolean codition(){}
    static public void assertFalse(String message, boolean codition(){}
    // .....
}

這些函數(shù)有關(guān)極強(qiáng)的概念相關(guān)性,因?yàn)樗麄儞碛泄餐拿J剑瑘?zhí)行同一基礎(chǔ)任務(wù)的不同變種。互相調(diào)用是第二位的。即便沒有互相調(diào)用。也應(yīng)該放在一起。

更多例子查看 p79 -- 5.25 垂直順序

錯(cuò)誤處理 抽離Try/Catch代碼塊

函數(shù)應(yīng)該只做一件事,錯(cuò)誤處理就是一件事。

// bad
public void delete(Page page) {
    try{
        deletePage(page);
        registery.deleteReference(page.name);
        configKeys.deleteKey(page.name.makeKey();
    }catch(Expection e){
        logError(e);
    }
}

// good
public void delete(Page page) {
    try{
        // 將上例的操作,封裝到一個(gè)方法
        deletePageAndAllReferences(page);
    }catch(Expection e){
        logError(e);
    }
}
使用非受控異常

受控異常:Checked Exception(FileException、SQLException等),這類異常必須寫 try/catch,或者 throw拋出,否則編譯通不過。

非受控異常:Unchecked Exception,這類異常也叫做運(yùn)行時(shí)異常(與非受控異常 字?jǐn)?shù)相等),這類異常不需要 try/catch,也不需要 throw拋出。即使 throw 了,上層調(diào)用函數(shù)也非必須捕獲,編譯能通過。

受控異常的代價(jià)就是違反開放/閉合原則。如果你在方法中拋出受控異常,這意味著每個(gè)調(diào)用該函數(shù)的函數(shù)都要修改,捕獲新異常,或在其簽名中添加合適的throw語句。對(duì)于一般的應(yīng)用開發(fā),受控異常依賴成本要高于收益成本,盡量 try/catch 處理,不要拋出。

給出異常發(fā)生的環(huán)境說明

應(yīng)創(chuàng)建信息充分的錯(cuò)誤信息,并和異常一起傳遞出去。在消息中,包括失敗的操作和失敗類型。如果你的應(yīng)用程序有日志系統(tǒng),傳遞足夠的信息給catch塊,并記錄下來。

依調(diào)用者需要定義異常類
// bad
ACMEPort port = new ACMEPort(12);
try {
    port.open();
} catch(DeviceResponseException e) {
    reportPortError(e);
    logger.log("Device response exception",e);
} catch(ATM1212UnlockedException e) {
    reportPortError(e);
    logger.log("Unlock exception",e);
} catch(GMXError e) {
    reportPortError(e);
    logger.log("Device response exception",e);
} finally {
    // .....
}

通過打包調(diào)用API,確保它返回通過用異常類型,從而簡化代碼

// good
LocalPort port = new LocalPort(12);
try {
    port.open();
} catch(PortDeviceFailure e) {
    reportError(e);
    logger.log(e.getMessage(),e);
} finally {
    // .....
}

public class LocalPort{
 private ACMEPort innerPort;
 
 public LocalPort(int portNumber){
     innerPort = new ACMEPort(portNumber);
 }
 
 public open() {
  try {
       innerPort.open();
   } catch(DeviceResponseException e) {
           // 自定義的異常類
       throw new PortDeviceFailure(e);
   } catch(ATM1212UnlockedException e) {
       throw new PortDeviceFailure(e);
   } catch(GMXError e) {
       throw new PortDeviceFailure(e);
   }
 }
}

將第三方API打包是個(gè)良好的實(shí)踐手段。當(dāng)你打包一個(gè)第三方API,你就降低了對(duì)它的依賴。

其他

try catch語句塊的范圍不要太大,這樣不利于對(duì)異常的分析

別返回null值,這樣可以減少調(diào)用者的防御性檢測。與其返回null,不如拋出異常,或是返回特例對(duì)象(特例對(duì)象詳見 p101)

別傳遞null值,傳遞null就要求被調(diào)用函數(shù)需要一系列防御性檢測,也就意味著程序有更大可能出錯(cuò)

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/76718.html

相關(guān)文章

  • 代碼整潔之道讀書筆記

    摘要:看完代碼整潔之道之后我受益匪淺,但等到自己實(shí)踐時(shí)卻很難按照書中給的建議編寫出整潔的代碼。意味著新人除了了解代碼邏輯之外,還需要學(xué)習(xí)這種編碼語言。代碼在演化,注釋卻不總是隨之變動(dòng)。區(qū)隔與靠近空格強(qiáng)調(diào)左右兩邊的分割。 看完《代碼整潔之道》之后我受益匪淺,但等到自己實(shí)踐時(shí)卻很難按照書中給的建議編寫出整潔的代碼。一方面是規(guī)則太多,記不住,另一方面書上引用了大量示例代碼對(duì)這些規(guī)則進(jìn)行佐證,在我記...

    liangzai_cool 評(píng)論0 收藏0
  • 代碼整潔之道

    摘要:在代碼整潔之道,提出一種軟件質(zhì)量,可持續(xù)開發(fā)不僅在于項(xiàng)目架構(gòu)設(shè)計(jì),還與代碼質(zhì)量密切相關(guān),代碼的整潔度和質(zhì)量成正比,一份整潔的代碼在質(zhì)量上是可靠的,為團(tuán)隊(duì)開發(fā),后期維護(hù),重構(gòu)奠定了良好的基礎(chǔ)。 現(xiàn)在的軟件系統(tǒng)開發(fā)難度主要在于其復(fù)雜度和規(guī)模,客戶需求也不再像Winston Royce瀑布模型期望那樣在系統(tǒng)編碼前完成所有的設(shè)計(jì)滿足用戶軟件需求。在這個(gè)信息爆炸技術(shù)日新月異的時(shí)代,需求總是在不停...

    icattlecoder 評(píng)論0 收藏0
  • 代碼整潔之道 - 有意義的命名

    摘要:我們這里再介紹一下,朱重八家族的名字,都很有特點(diǎn)。取這樣的名字不是因?yàn)橹旒沂歉銛?shù)學(xué)的,而是因?yàn)樵谠?,老百姓如果不能上學(xué)和當(dāng)官就沒有名字,只能以父母年齡相加或者出生的日期命名。所以說命名不僅僅是一種科學(xué),更是一種藝術(shù)。 在小朱元璋出生一個(gè)月后,父母為他取了一個(gè)名字(元時(shí)慣例):朱重八,這個(gè)名字也可以叫做朱八八。我們這里再介紹一下,朱重八家族的名字,都很有特點(diǎn)。朱重八高祖名字:朱百六;朱...

    mengbo 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<