Clean Code第3章


第三章関数
小さくしろ!
public static String renderPageWithSetupsAndTeardowns(
	PageData pageData, boolean isSuite
) throws Exception {
    boolean isTestPage = pageData.hasAttribute("Test");
    if (isTestPage) {
    	WikiPage testPage = pageData.getWikiPage();
        StringBuffer newPageContent = new StringBuffer();
        includeSetupPages(testPage, newPageContent, isSuite);
        newPageContent.append(pageData.getContent());
        includeTeardownPagea(testPage, newPageContent, isSuite);
        pageData.setContent(newPageContet.toString());
    }
    return pageData.getHtml();
} 
関数は上記のコードより短くなければなりません.下のように!
public static String renderPageWithSetupsAndTeardowns(
	PageData pageData, boolean isSuite
) throws Exception {
    if(isTestPage(pageData)) {
    	includeSetupAndTeardownPages(pageData, isSuite);
    }
    return pageData.getHtml();
} 
文/while文の重複によるインデントは、1セグメントまたは2セグメント以下でなければなりません.
一つだけやろう!
1つの関数は1つの機能しか実行できません.
各関数の抽象レベルは1つです!
.getHtml(), render(), .append("n")はすべて抽象化の程度が異なる.1つの関数では,抽象化レベルを1つの関数に統一することは容易に理解できる.
降格規則
プログラムを上から下へ読むには、関数の後ろの関数に抽象レベルの低い関数が必要です.
スイッチドア
継承関係なので、できるだけ本コードに露出しないでください!
叙述的な名前を使う!
名前が長くても、説明機能の命名法を使います.
ネーミングには一貫性が必要です.
モジュール内では、関数名は同じ文、名詞、動詞を使用します.
例)
  • includeSetupAndTeardownPages
  • includeSetupPages
  • includeSuiteSetupPage
    etc.
  • 関数パラメータ
    関数が受ける因数が小さいほど,試験用例などを考慮しても混同されず,よりよい.
    最良の方法は入力因数がなく、次に入力因数が1つしかないことです.
    関数に出力係数を加えるのは避けるべきであることに注意すべきである.
    また,単項関数の場合,関数と引数は動詞/名詞対でなければならない.
    付随効果は発生しないでください.
    例)
    public class UserValidator {
        private Cryptographer cryptographer;
        
        public boolean checkPassword(String userName, String password) {
        	User user = UserGateway.findByName(userName);
            if (user != User.NULL) {
            	String codePhrase = user.getPhraseEncodedByPassword();
                String phrase = cryptographer.decrypt(codedPhrase, password);
                if ("Valid Password".equals(phrase)) {
                	Session.initialize();
                    return true;
                }
            }
            return false;
        }
    }
    ユーザー名とパスワードを確認する関数でセッションします.initialize()を呼び出すと、checkPasswordという関数名では特定できないセッションが初期化されます.
    コマンドとクエリーを分けて!
    public boolean set(String attribute, String value);
    
    사용 예시
    if (set("name", "Peter"))...
    setという名前の関数はattributeプロパティを検索してvalueに変換する関数です.
    ただし、上記のコードを記述すると、「name」attrが「peter」に設定されているかどうか、または「name」attrの値が「peter」に設定されているかどうかは分かりにくい.
    エラーコードではなく例外を使用します.
    if (deletePage(page) == E_OK) {
        if (registry.deleteReference(page.name) == E_OK) {
        
        } else {
        }
    } else {
    ...
    }
    上記の記述に比べて、エラーを排除するのは簡潔です.
    try {
        deletePage(page);
        registry.deleteReference(page.name);
    } catch (e) {
    	...
    }
    ブロックの試行/キャプチャ
    try {
        deletePage(page);
        registry.deleteReference(page.name);
    } catch (e) {
    	logError(e);
    }
  • エラー処理も作業です.
  • したがって,エラー処理を行う作業も関数に分離することが望ましい.Error.JAva依存磁石
    エラーコードを返すには、エラーコードを定義する場所がありますが、Error enumが変更された場合はクラスを再コンパイルする必要があるため、例外を使用します.例外はExceptionクラスから発生します.
    繰り返さないで!
    異なる関数に重複するアルゴリズムがある場合は、それを外に定義し、includeで記述します.
    これにより、同じコードを複数回変更する手間を減らすことができます.
    構造化プログラミング
    すべての関数と関数のブロックについてentryとexitは1つでなければなりません.
    関数には、breakまたはcontinueをループで使用することはできません.gotoは絶対に使用できません.