다른 업무 처리하느라 신경쓰지 못했던 코드를 조금 손보았다.
Covnerter 인터페이스 활용하여 중복 코드 제거
프로젝트에서는 엑셀->csv 와 csv->엑셀 변환 메서드를 가진 class가 분리되어 있다.
초기 설계 시 각각을 Converter라는 인터페이스를 상속받은 구현체로 선언해놓긴 했지만, 막상 로직에서는 객체지향의 장점을 살리지 못하고 각각 메서드 자체를 분리한 후 사용자로부터 작업 번호를 받아 switch문을 통해 필요한 메서드가 호출되도록 작성했었다.
public void work(int num){
try {
switch(num) {
case 1 : csvToExcel(); break;
case 2 : excelToCsv(); break;
case 0 : exit(); break;
//TODO work Listup할 때 ts에서의 List랑 switch문 연동되도록
//TODO TaskSelector에서 escape하는데 2중으로 validation을 해야 할지 결정
default : System.out.println("작업 값이 손상되었습니다. 다시 시도해주세요.");
}
} catch (IOException e) {
System.out.println("입출력 오류로 프로그램을 종료합니다.");
System.exit(0);
}
}
그렇게 된 원인을 살펴보면 목표 작업에 따라서 Converter 이외에도 작업 대상파일 list 구성이 달라야 했는데,
두 변환을 각각 별도의 기능으로 한 기능씩 완성하는 것만 생각하며 작성하다 보니 xls/xlsx , csv로 나눠져 있는 작업을 각각의 메서드로 분리하게 되었다.
그러다보니 자연스럽게 중복 코드가 발생했다.
위 코드블럭에서 호출되는 csvToExcel()과 excelToCsv()에서는 모두 작업 대상이 되는 파일을 불러와서 리스트업 한 후, converter에 작업을 지시한다.
public void excelToCsv() throws IOException {
//initial for ExcelToCsv
lm.initialExcelList();
Queue<String> xlsList = lm.getXlsList();
Queue<String> xlsxList = lm.getXlsxList();
//readfile
String[] fileList = fs.readFiles();
lm.makeExcelWorkList(fileList);
int count = lm.getExcelListSize();
if(count==0) {
System.out.println("작업 대상 파일이 없어 프로그램을 종료합니다.");
System.exit(0);
}
System.out.println("총 작업 개수 [ "+count+" ] 개. 작업 시작");
Converter cv = cm.createConverter("excel");
while(!xlsList.isEmpty()) {
String targetName= xlsList.poll();
cv.convert("xls", targetName);
System.out.println(targetName+" 작업 완료. [ " + (count-xlsList.size())+" / "+count+" ]");
}
while(!xlsxList.isEmpty()) {
String targetName = xlsxList.poll();
cv.convert("xlsx", targetName);
System.out.println(targetName+" 작업 완료. [ " + (count-xlsxList.size())+" / "+count+" ]");
}
System.out.println("---전체 작업 완료.---");
}
public void csvToExcel() throws IOException {
//initial for CsvToExcel
lm.initialCsvList();
Queue<String>csvList = lm.getCsvList();
//readfile
String[] fileList = fs.readFiles();
lm.makeCsvWorkList(fileList);
int count=csvList.size();
if(count==0) {
System.out.println("작업 대상 파일이 없어 프로그램을 종료합니다.");
System.exit(0);
}
System.out.println("총 작업 개수 [ "+count+" ] 개. 작업 시작");
Converter cv = cm.createConverter("csv");
while(!lm.csvList.isEmpty()) {
String targetName = csvList.poll();
System.out.println(targetName+" 시작... [ " + (count-csvList.size())+" / "+count+" ]");
cv.convert("csv", targetName);
System.out.println(targetName+" 작업 완료.");
}
System.out.println("---전체 작업 완료.---");
}
초기 코드는 이렇게 구성했었다.
list의 종류와 확장자를 제외하면 거의 대부분의 코드가 중복되어있는 것을 볼 수 있다.
리팩토링 작업
작업대상 list 단일화
기존의 코드에서는 xls / xlsx / csv 각각 별도의 리스트로 작업대상 파일을 저장했었다.
apache의 poi 라이브러리에서 xls는 HSSF, xlsx는 XSSFWorkbook을 사용해야 한다.
작업대상 파일의 확장자에 따라 워크북을 선택하고, 대상 파일의 이름으로 결과 파일을 생성하는 부분에서 별도의 처리를 추가하지 않으려고 위와 같은 구성을 했었다.
리팩토링하려고 찾다보니
org.apache.commons.io.FilenameUtils 에서 String형식의 파일 이름을 기준으로 확장자와 파일명을 추출하는 기능이 있다는 것을 발견하고 기능을 활용하였다.
public void makeWorkLists(String[] fileList, String target) {
for(String name: fileList) {
if(FilenameUtils.getExtension(name).contains(target)) {
targetList.add(FilenameUtils.getBaseName(name));
extensionList.put(FilenameUtils.getBaseName(name), FilenameUtils.getExtension(name));
}
}
}
ex) "파일이름.txt" 라는 String 기준
getBaseName = "파일이름"
getExtensionName = "txt"
xlsx와 xls의 경우 둘 중에 하나인 경우 작업에는 포함돼야 하지만, Workbook 생성 시 구분이 필요했다.
그래서 엑셀파일 대상 작업 시 확장자 매개변수인 target을 xls로 넣어서, equals가 아닌 contains로 조건문을 달아서 해결하였다.
리팩토링 결과
public void work(String extension) {
lm.initialFileList();
lm.makeWorkLists(fs.readFiles(), extension);
int count = lm.getTargetList().size();
if(count==0) {
System.out.println("작업 대상 파일이 없어 프로그램을 종료합니다.");
System.exit(0);
}
System.out.println("총 작업 개수 [ "+count+" ] 개. 작업 시작");
Converter cv = cm.createConverter(extension);
String target;
while(!lm.getTargetList().isEmpty()) {
target = lm.nextTarget();
System.out.println(target+" 시작... ");
try {
cv.convert(lm.getExtension(target), target);
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(target+" 작업 완료. [ " + (count-lm.getTargetList().size())+" / "+count+" ]");
}
System.out.println("---전체 작업 완료.---");
}
'프로젝트 > xls(x)<->csv' 카테고리의 다른 글
xls <-> csv 변환기 - 2 (0) | 2024.02.01 |
---|---|
xls <-> csv 변환기 - 1 (1) | 2024.01.28 |
xls <-> csv 변환기 - 0 (0) | 2024.01.28 |