한 가지를 하는지 판단하는 방법
- 지정된 함수 이름 아래에서 추상화 수준이 하나인 단계만 수행해야 한다.
 - 의미 있는 이름으로 다른 함수를 추출할 수 있다면 그 함수는 여러 작업을 하는 셈이다.
 
switch 문은 n가지를 처리한다. (다중 if/else 문 포함)public Money calculatePay(Employee e) throws InvalidEmployeeType {
    switch (e.type) {
        case COMMISSIONED: return calculateCommissionedPay(e);
        case HOURLY: return calculateHourlyPay(e);
        case SALARIED: return calculateSalariedPay(e);
        default: throw new InvalidEmployeeType(e.type);
    }
}
switch 문은 작게 만들기 어렵지만, 다형성을 이용하여 switch 문을 추상 팩토리에 숨겨 다형적 객체를 생성하는 코드 안에서만 사용하도록 한다.public abstract class Employee {
    public abstract boolean isPayday();
    public abstract Money calculatePay();
    public abstract void deliverPay(Money pay);
}
public interface EmployeeFactory {
    public Employee makeEmployee(EmployeeRecord r) throws InvalidEmployeeType;
}
public class EmployeeFactoryImpl implements EmployeeFactory {
    public Employee makeEmployee(EmployeeRecord r) throws InvalidEmployeeType {
        switch (r.type) {
            case COMMISSIONED: return new CommissionedEmployee(r);
            case HOURLY: return new HourlyEmployee(r);
            case SALARIED: return new SalariedEmploye(r); 
            default: throw new InvalidEmployeeType(r.type);
        }
    }
}
switch 문은 불가피하게 써야될 상황이 많으므로, 상황에 따라서는 사용 할 수도 있다.최선은 입력 인수가 없는 경우이며, 차선은 입력 인수가 1개뿐인 경우다. 그 이상은 피하는 편이 좋다. 왜냐하면 코드를 읽는 사람이 입력 인수를 이해해야 한다.
또한, 테스트 케이스 작성시에도 인수가 많을수록 테스트 조합이 부담스러워진다.
출력 인수는 입력 인수보다 이해하기 어렵다.
public class UserValidator {
    private Cryptographer cryptographer;
    
    public boolean checkPassword(String userName, String password) {
        User user = UserGateway.findByName(userName);
        if (user != User.NULL) {
            String codedPhrase = user.getPhraseEncodedByPassword();
            String phrase = cryptographer.decrypt(codedPhrase, password);
            if ("Valid Password".equals(phrase)) {
                Session.initialize(); // 함수명을 벗어난 부수효과
                return true;
            }
        }
        return false;
    }
}
// 중첩된 오류 처리 코드
if (deletePage(page) == E_OK) {
    if (registry.deleteReference(page.name) == E_OK) {
        if (configKeys.deleteKey(page.name.makeKey()) == E_OK) {
            logger.log("page deleted");
        } else {
            logger.log("configKey not deleted");
        }
    } else {
        logger.log("deleteReference from registry failed");
    }
} else {
    logger.log("delete failed"); return E_ERROR;
}
// try-catch 문을 이용하여 오류 처리 코드를 분리
try {
    deletePage(page);
    registry.deleteReference(page.name);
    configKeys.deleteKey(page.name.makeKey());
} catch {
    logger.log(e.getMessage());
}
try-catch 문을 별도 함수로 뽑아내는 편이 좋다.// 위 코드를 메소드로 추출
public void delete(Page page) {
    try {
        deletePageAndAllReferences(page);
    } catch (Exception e) {
        logError(e);
    }
}
private void deletePageAndAllReferences(Page page) throws Exception {
    deletePage(page);
    registry.deleteReference(page.name);
    configKeys.deleteKey(page.name.makeKey());
}
private void logError(Exception e) {
    logger.log(e.getMessage());
}
한 가지 작업에 속한다. 그러므로 오류만 처리해야 마땅하다.break나 continue를 사용해선 안되며 goto는 절대로 안된다.모든 시스템은 프로그래머가 설계한 도메인 특화 언어로 만들어진다. 함수는 그 언어에서 동사며, 클래스는 명사다.
위에서 설명한 규칙을 따른다면 길이가 짧고, 이름이 좋고, 체계가 잡힌 함수를 만들 수 있다.