2024. 7. 2. 22:08ㆍWebBack/Software 코드 분석
입출금 내역 분석기 요구 사항 | 경로 |
CSV + 입출금 내역 분석기 요구 사항 | https://ycraah.tistory.com/25 |
모든 거래 내역의 합 계산하기 | https://ycraah.tistory.com/26 |
1월 입출금 내역 합계 계산하기 | https://ycraah.tistory.com/32 |
public class BankTransactionAnalyzerJanuary{
private static final String RESOURCE = "src/main/resources/";
public static void main(String... args) throws IOException {
final Path path = Paths.get(RESOURCE + args[0]);
final List<String> lines = Files.readAllLines(path);
final DateTimeFormatter formatted = DateTimeFormatter.ofPattern("yyyy-MM-dd");
double total = 0d;
for(String line : lines){
String[] columns = line.split(","); //2024-01-30, -10, 교통비
LocalDate date = LocalDate.parse(columns[0], formatted);
if(date.getMonthValue() == 1){
double amount = Double.parseDouble(columns[1]);
total += amount;
}
}
System.out.println("1월달의 은행 입출금 내역의 총합은 " + total +"(만원)입니다.");
} //end of main
}//end of class
이 책에서는 위 코드의 다음과 같은 문제점을 지적한다.
- 특정 기능을 담당하는 코드를 쉽게 찾을 수 없다.
- 코드가 어떤 일을 수행하는지 쉽게 이해할 수 없다.
- 새로운 기능을 추가하거나 제거하기 어렵다.
- 캡슐화가 되어 있지 않다.
그래서 이 책의 저자는 관리와 유지보수를 위해서 '단일 책임 원칙'을 제안한다. 즉, 한 클래스는 한 기능만 책임진다는 것이다. 위 코드는 다음과 같은 기능을 포함하고 있다.
1. 입력 읽기
2. 주어진 형식의 입력 파싱
3. 결과 처리
4. 결과 요약 리포트
2번을 따로 추출한 코드가 다음과 같다.
public class BankStatementCSVParser {
private static final DateTimeFormatter DATE_PATTERN = DateTimeFormatter.ofPattern("yyyy-MM-dd");
private BankTransaction parseFromCSV(final String line){
final String[] columns = line.split(",");
final LocalDate date = LocalDate.parse(columns[0], DATE_PATTERN);
final double amount = Double.parseDouble(columns[1]);
final String description = columns[2];
return new BankTranscation(date, amount, description);
}
public List<BankTransaction> parseLinesFromCSV(final List<String> lines){
final List<BankTransaction> bankTransactions = new ArrayList<>();
for(final String line: lines){
bankTransactions.add(parseFromCSV(line));
}
return bankTransactions;
}
}
위 코드를 하나씩 해석해보자.
private static final DateTimeFormatter DATE_PATTERN = DateTimeFormatter.ofPattern("yyyy-MM-dd");
첫째줄의 코드는 기존의 코드와 똑같다. 연도-월-일 형식으로 지정된 정보를 읽을 수 있도록 돕는다. 클래스가 분리되면서 외부에서의 접근을 막아야 하는 필요성이 생겨서 private를 추가하였다.
private BankTransaction parseFromCSV(final String line)
클래스 내에 있는 parseFromCSV 메서드이다. 반환타입은 BankTransaction인데 아직 코드가 없어서 어떤 의미인지는 알 수 없다. 하지만 매개 변수가 line인 것을 보면 경로에 있는 txt 파일을 한 줄씩 String으로 저장한 내용으로 보인다. 아마 line에 입력되는 내용은 '2024-01-30, -10, 교통비'같은 형식의 내용일 것이다.
final String[] columns = line.split(",");
이 부분은 기존의 코드에서 사용된 것과 똑같다. ','을 분리자로 삼아서 분리한다.
columns에는 '2024-01-30' '-10' '교통비' 이렇게 나뉘어서 배열로 저장된다.
final LocalDate date = LocalDate.parse(columns[0], DATE_PATTERN);
final double amount = Double.parseDouble(columns[1]);
final String description = columns[2];
return new BankTransaction(date, amount, description);
이렇게 배열로 저장된 값을 각각 저장한다. 그리고 이 값은 서로 관련성이 깊으니 묶어서 관리하는 것이 좋다. 그래서 BankTransaction 객체에 담는다. 아직 BankTransaction 클래스가 등장하지 않았지만 각 값을 저장하기 위한 생성자가 있다는 것을 유추할 수 있다.
그런데 이 코드를 실행할 line은 어디서 가져오는 것일까? 이를 알기 위해서는 아래 코드를 봐야한다.
public List<BankTransaction> parseLinesFromCSV(final List<String> lines){
final List<BankTransaction> bankTransactions = new ArrayList<>();
for(final String line: lines){
bankTransactions.add(parseFromCSV(line));
}
return bankTransactions;
}
아직 무슨 코드인지 모르겠지만 CVS.txt를 한 줄씩 읽어낸 값을 매개변수로 삼고 있는 것을 알 수 있다.
이전에 썼던 코드를 값으로 받았을 것이다.
final Path path = Paths.get(RESOURCES + args[0]);
final List<String> lines = Files.readAllLines(path);
public List<BankTransaction> parseLinesFromCSV(final List<String> lines)
반환 타입이 List<BankTransaction>이라는 것을 통해 parseFromCVS 메서드가 여기서 실행될 것이라는 것을 알 수 있다.
final List<BankTransaction> bankTransactions = new ArrayList<>();
그러면 bankTransactions는 parseFromCVS에서 반환한 bankTransaction을 반환하는 객체를 저장하는 List가 된다.
List에 저장하기 위한 반복문이 아래의 내용이다.
for(final String line: lines){
bankTransactions.add(parseFromCSV(line));
}
향상된 for문을 사용하였다. 그리고 List를 반환한다.
return bankTransactions;
'WebBack > Software 코드 분석' 카테고리의 다른 글
1월 입출금 내역 합계 계산하기 (0) | 2024.06.25 |
---|---|
모든 거래 내역의 합 계산하기 (0) | 2024.06.21 |
CSV + 입출금 내역 분석기 요구 사항 (0) | 2024.06.21 |