[실전 자바 소프트웨어 개발]CH3 입출금 내역 분석기 확장판

개방/폐쇄 원칙

개방 폐쇄 원칙을 적용하여 특정 메소드의 코드를 복사하거나 새 파리미터를 추가하지 않고 동작을 확장 할 수 있다.

 

  • 특정 금액 이상의 모든 입출금 내역을 검색하려면?
  • 특정 월의 모든 입출금 내역을 검색하려면?
  • 특정 월 또는 특정 금액으로 입출금 내역을 검색하려면? 

 

여기서는 금액을 구하는 조건을 인터페이스로 만들 수 있다.

public interface BankTransactionFilter {
	boolean test(BankTransactino bankTransaction);
}

...

public List<BankTransaction> findTransactions(final BankTransactionFilter bankTransactionFilter) {
	fianl List<BankTransaction> result = new ArrayList<>();
	for (final BankTransaction bankTransaction: bankTransactions) {
    		if(bankTransactionFilter.test(bankTransaction)) {
        		result.add(bankTransaction);
        	}
        }
        return result
}

 

findTransactions()는 더 이상 특정 필터 구현에 의존하지 않는다. 기존 메서드의 바디를 바꿀 필요 없이 새로운 구현을 인수로 전달하기 때문이다. 따라서 변경 없이도 확장성은 개방 된다.

 

 

인터페이스 람다 표현식

위의 방법을 사용하면 새로운 요구 사항이 있을 때마다 별도의 클래스를 만들어야 한다. 람다 표현식을 사용하면 이름 없이 인터페이스 구현 객체를 코드 블록 형태로 전달 할 수 있다.

 

final List<BankTransaction> transactions = bankStatementProcessor.findTransactions(bankTransaction -> 
	bankTransaction.getDate().getMonth() == Month.FEBRUARY
	&& bankTransaction.getAmount() >= 1_000);

 

갓 인터페이스

  • 자바의 인터페이스는 모든 구현이 지켜야 할 규칙을 정의한다. 즉 구현 클래스는 인터페이스에서 정의한 모든 연산의 구현 코드를 제공해야 한다. 따라서 인터페이스를 바꾸면 이를 구현한 코드도 바귄 내용을 지원하도록 갱신되어야 한다. 더 많은 연산을 추가할수록 더 자주 코드가 바뀌며, 문제가 발생할 수 있는 범위도 넓어진다.
  • 인터페이스는 도메인 객체의 특정 접근자에 종속 되어서는 안된다. 도메인 객체의 세부 내용이 바뀌게 되면 인터페이스도 바뀌어야 하며 결국엔 구현 코드도 바뀌어야 한다.
    • calculateAverageForCategory() 와 같은 경우

 

도메인 클래스 vs 원싯값

원싯값으로는 다양한 결과를 반환할 수 없어 유연성이 떨어진다.

 

원싯값을 포장하면 도메인의 다양한 개념간의 결합을 줄이고, 요구 사항이 바뀔 때 연쇄적으로 코드가 바귀는 일도 최소화 할 수 있다.

 

적절하게 인터페이스를 정의하고 구현하기

  • void 반환 형식은 아무 도움이 되지 않고, 기능을 파악하기도 얿다. 메서드가 무엇을 반환하는지 알 수 없기 때문이다. 인터페이스로 부터 얻을 수 있는 정보가 아무것도 없다.
  • void를 반환하면 어서션으로 결과를 테스트하기도 매우 어렵다. 예상한 값과 실제 결과값을 어떻게 비교할까? 안타깝게도 void를 반환하면 아무 결과도 없다.

 

예외 처리

  • 확인된 예외
    • 자바에서는 메서드가 던질 수 있는 확인된 예외 목록을 선언해야 한다. 아니면 해당 예외를 try/catch로 처리해야 한다.
    • Exception
  • 미확인 예외
    • 프로그램을 실행하면서 언제든 발생할 수 있는 종류의 예외다. 확인된 예외와 달리 메서드 시그니처에 명시적으로 오류를 선언하지 않으면 호출자도 이를 꼭 처리할 필요가 없다.
    • Error, RuntimeException
  • 대다수의 예외를 미확인 예외로 지정하고 꼭 필요한 상황에서만 확인된 예외로 지정해 불필요한 코드를 줄여야 한다.
  • 예외를 던지는 대신 null을 반환하는 방법은 절대 사용하지 말아야 한다.

 

Optional<T>

  • 자바 8에서 값이 없는 상태를 표현하는 내장 데이터 형식인 Optional<T>를 제공
  • 값이 없는 상태를 명시적으로 처리하는 다양한 메서드 집합을 제공하므로 버그의 범위를 줄이는데 큰 도움을 줌

 

 

 

CH3 브랜치 참고하기

 

DWL5/Real-World-Software-Development

Contribute to DWL5/Real-World-Software-Development development by creating an account on GitHub.

github.com

 

댓글



Designed by JB FACTORY