4. 코드는 한 번만 작성하라

가이드 라인

  • 코드를 복사하지 않는다

  • 코드를 재사용 가능한 일반적인 형태로 작성하거나 기존메서드를 대신 호출

  • 유지보수성 개선. 코드 복사는 여러곳에서 버그를 고쳐야하기 때문에 비효율적이고 에러 발생이 쉬움

악취 퍼레이드의 하이라이트는 중복 코드다

-켄트백, 마틴파울러

1. 필요성

  • 중복코드는 코드 수정시 다른 곳도 수정해야하므로 버그의 발생률이 높아진다

  • 이런 중복코드는 분석하기 어렵고, 수정하기가 어려워지게 한다

  • 코드는 무조건 변합니다. 그러니 복사해서 임시방편으로 해결하기 보다 장기적으로 유지보수성을 생각하여 코드를 작성할 줄 알아야함

2. 적용가이드

  • 상위클래스 추출

    • 의미 명확화

    • 클래스의 상세정보 비대증세 제거

    • 공통 부분 추출하여 활용 및 재정의를 통한 다형성 활용

  • 예제 p.92

    • Account

      • CheckingAccount

      • SavingAccount

    • 중복내용 대상 -> makeTransfer 메서드

public class Account {
    public Transfer makeTransfer(String counterAccount, Money amount)
        throws BusinessException {
        if (isValid(counterAccount)) {
            CheckingAccount acct = Accounts.findAcctByNumber(counterAccount);
            return new Transfer(this, acct, amount);
        } else {
            throw new BusinessException("Invalid account number!");
        }
    }

    private boolean isValid(String number) {
        int sum = 0;
        for (int i = 0; i < number.length(); i++) {
            sum = sum + (9 - i) * Character.getNumericValue(number.charAt(i));
        }
        return sum % 11 == 0;
    }
}


public class SavingsAccount extends Account {
    CheckingAccount registeredCounterAccount;

    @Override
    public Transfer makeTransfer(String counterAccount, Money amount)
        throws BusinessException {
        Transfer result = super.makeTransfer(counterAccount, amount);
        if (result.getCounterAccount().equals(this.registeredCounterAccount)) {
            return result;
        } else {
            throw new BusinessException("Counter-account not registered!");
        }
    }
}



public class CheckingAccount extends Account {
    private int transferLimit = 100;

    @Override
    public Transfer makeTransfer(String counterAccount, Money amount)
        throws BusinessException {
        if (amount.greaterThan(this.transferLimit)) {
            throw new BusinessException("Limit exceeded!");
        }
        return super.makeTransfer(counterAccount, amount);
    }
}

Last updated