Search

엑셀 좀 더 쉽게 가져올 수 없을까? (개선)

본 내용은 토비의 스프링을 공부하며 엑셀을 라이브러리를 다룰 때 불편했던 내용을 개선해보고자 했다.
현실적 이야기 나는 아직 학생이다. 그런데 내가 코딩하는 것을 알고 내가 지금 일하는 곳에서 엑셀로 보고서를 만들거나, 엑셀을 이용하여 쉽게 데이터를 뽑거나 이런 걸 부탁 받은 적이 많다. 잠깐 여담이지만 난 엑셀을 어느정도 다루고 배웠기 때문에 가능했다. 그 덕분에 엑셀 자체적으로 무슨 타입이고 어떤 방식으로 사용해야 오류가 없는지 알고 있었다. 본론으로 넘어가서 거기에서 나에게 부탁을 해주시는 분들은 어깨너머 엑셀을 배우신 분들이 많았고, 복사/붙여넣기로 인하여 수식이 제대로 동작하지 않거나 제대로 계산이 되지 않는 경우가 엄~~청나게 많았다(예를 들자면 숫자를 넣어야하는 곳에 숫자처럼 생긴 텍스트를 넣는다거나…). 그래서 이번 개선 목표는 엑셀의 타입을 셀에 현재 들어가 있는 타입으로 읽는 것이 목표였다(왜냐하면 잘못넣는 케이스가 많아지니 내가 감당이 안되더라… 헤). 목표로 했던 것은 다음과 같다. 1. 엑셀에 현재 들어가 있는 값을 타입별로 읽어 오자. 어쨋건 읽어야 뭐 처리를 하던 말던 하니깐… 그리고 처음 목표는 “숫자, 텍스트가 가장 많이 헷갈리고 실수하는 부분이니 그부분만 개선하자” 였다. 2. 다른 타입이 추가될 경우를 생각하여 수정하기 쉽게 만들자. 실제로 사용하지 않더라도 그렇게 만들어야할 것 같았다(늘… 무슨일이 벌어질지 나도 몰랐다).

원리를 적용한 나만의 템플릿 (예제)

이렇듯 템플릿은 오류 없는 코드에서 변하는 부분과 변하지 않는 부분을 나누어 사용하는 형태로 만드는 과정이다. 이러한 맥락에서 나도 평소 자주 사용하는 POI 라이브러리를 변경해보려고 한다.
1년이 넘게 지난 시점에서 다시 돌아보는 나 ㅋㅋㅋㅋ 아니 진묵아 왜 이렇게 쓰니!!!!!! 잘못된게 너무 많어 공부 똑바로 한거니!!!!!!!!!!!!!!!!!!!!!!!!!!!! 일단 코딩에 액션이 너무 많네 이 친구 맞습니다. 전 잘하고 싶어서 어렵게 쓰는 걸 좋아했습니다. 일단 줄일거 줄이고 하다보니 더 좋은 코드가 되었긴 했는데 아래의 예제처럼 어렵고 빙빙 돌아가시면 안됩니다!!!

엑셀 라이브러리? 뭐가 불편해?

바꿔 볼까?

이를 통하여 템플릿이 뭔지 대충 감을 잡을 수 있었다. 템플릿을 통하여 변화에 강하고 확장에 용이한 코드가 어떤 느낌인지 알 수 있었다. 또한 테스트 코드를 통하여 추가나 변경 사항을 바로바로 테스트 할 수 있기 때문에 더 확장 할 때 염려할 것이 없다. 그리고 템플릿을 사용하면 테스트하기가 너무 편해진다.

정리

1.
변경에 강하고 변하지 않는 부분을 따로 독립 시킨다는 템플릿의 개념을 이해할 수 있었다,
2.
템플릿이 만들어지는 계기 또는 개념적인 순서를 이해할 수 있었다.
3.
스프링에서의 템플릿과 자바에서 템플릿이 조금 다르다.
4.
템플릿은 만들 때는 오류없이 정상적으로 동작하는 코드를 변하는 부분과 변하지 않는 부분으로 나누어 다시 리팩토링하는 과정이다.

느낀 점

이번에는 체크리스트 보다는 미흡했던 점과 좋았던 점을 기술해보려고 한다.

미흡한 점

1.
CellValueTemplate을 테스트 할때 Mock작업이 상당히 많이 존재한다. “이걸 어떻게 해결해야할까?” 또는 “이렇게 Mock을 만들어 테스트 하는 것이 맞는가?”, “Mock을 만들어 테스트 할 수 있는 상황을 만든 것이 잘한 것인가?”에 대한 의문이 든다. 하지만 알지 못했다.
2.
CellValueTemplate라고 만들었지만 솔직히 이름이 잘못된 것 같다(물론 CellRegister도 포함이다).
3.
CellRegister을 만들때 addReader()을 사용한다. 그리고 이를 통하여 구현체를 직접 빈으로 등록해준다. 전에 스프링을 쓸때 이러한 패턴으로 등록하는 Formatter를 보아서 따라 해봤다. 근데 맞는지 의문이 든다.
4.
클라이언트 측에서 ExcelFactoryCellValueTemplate만 받아서 사용하기만 하면 된다. 여기서 의문인 점은 이 둘이 개념상으로 연관 관계를 가진다. 그렇지만 내가 만든 코드에서는 연관 관계가 나타나지 않는다. 이것이 맞는지 의문이다(약간 DB 관점으로 본 것이다. Excel파일이 존재하지 않는데 Cell이 어떻게 존재하는가? 그렇다면 합쳐야 하는 것이 아닌가? 그럼 엄청 규모가 커질텐데? ).
5.
테스트 코드 또는 프로덕션 코드에 주석을 달아 표시하는 방법을 잘모르겠다. 그래서 주저리주저리 적었는데 다음에는 조금 더 알아보고 사용해야 할 것 같다.
6.
테스트 코드를 작성할때 @ExtendWith()을 통하여 원하는 클래스만 등록하여 사용하려고 했었다. 하지만 에러가 많이 발생했다. 이유를 찾아보니 Poi 라이브러리를 사용하고 있어서 거기에 등록되어 있는 Cell이라는 녀석을 못 가져와서 발생한 문제였다. 그렇다면 지금 내 코드가 단위 테스트로의 적합성에 대한 의문이 든다(물론 단위도 정하기 나름이고 내가 만든 application자체가 Poi에 의존적이긴 하지만 그래도 의문이 생긴다.).
7.
CellValueTemplategetValu(Cell cell) 메서드의 구현을 보면 이상한 부분(.findCellReader(cell.getCellType().toString()))이 있다. 솔직히 어떻게 고쳐야 할지 막막하다(Cell타입으로 받아서 String타입으로 변경해줘야 할지, 아니면 지금처럼 둬도 되는지, 이렇게 바꾼 이유는 6번의 맥락에서 오류가 자꾸 나서 고친 거다. Cell에 의존적인데 Mock으로 만들어야 할지 아니면 String으로 변환해서 사용해야 할지 고민하다가 이렇게 바꾸어 주었다). 1년이 지난 시점에서 다시봤는데 이거 고려했구나? 테스트가 안된거였구나 ㅎㅁㅎ….
8.
application.propertiestest.file.path.xls를 만들어 사용했다. 솔직히 아닌 것 같다. 통합 테스트, WorkBookFactory테스트 말고는 쓰임이 없는데 저렇게 만들어도 될지 모르겠다.
9.
CellRegisterboolean addRegistry(String cellType, CellReader cellReader) 메서드에 파라미터 타입이 잘못되었다. 처음에는 단순히 “key로 찾으면 되겠지?” 하면서 cellType을 넣었는데 만들고 바꿀려고 보니 List를 사용하면 저게 필요가 없다. 오히려 index가 필요하다. 그래서 좀 말이 안되는 것 같다.
10.
<T extends Object>를 보면 이상하긴하다. 처음에는 정해진 타입만 반환할 수 있도록 따로 또 상속 구조를 만들려고 하였으나, 실패하고 남겨둔 코드다. 그렇게 할려고 했던 이유가 생각보다 반환형이 많아서 그렇다. 또한 Date 타입이 존재해서 LocalDate 타입으로 변경하려고 하나의 상속 구조를 더 만들려고 했던 거다.
11.
다시 보니 전에 너무 예외처리를 생각없이 했다. 알고는 있는데 안하는게 더 문제다. 고쳐봐야겠다.
12.
중간중간에 보니 Optinal이나 제네릭 타입을 너무 남발했다…. 허허… 요건 좀 많이 잘못된 것같다.수정이 필요하다.
13.
생각보다 코드가 안예쁘다…이건 객관적으로도 그럴것같다…. 너무 추상적인 말이지만 그래도 그 느낌…이 안예쁘다.흐어어엉어어어엉
14.
적용을 바랬지만… 그 이후로 아무도 부탁하지 않았다…. 2022-09-11 기준으로도…. 미리 만들었던 걸 개선하면 되지 않을까? 라는 생각을 했다… 하지만 “바쁘다 담에 설치하자” 하다가 여기까지 와버렸다…. 여담으로 아직도 전에 만든건 잘쓰고 계신다. 🥹

좋았던 점 (물론 남이 보면 아닐 수 있다)

1.
추가, 변경에 내 코드가 변하는 일이 없었다(그렇게 할려고 했으니깐).
2.
진짜 모듈을 만드는 느낌이라 기분 좋았다(이렇게 만들어 본 건 처음이다.).
3.
맞는지 아닌지 모르지만 개인적으로CellRegisteraddRegistry() 메서드는 좋았다(내가 원하는 걸로 만들어서 기분이 너무 좋았다).
4.
추가 및 변경 검증을 시도했을 때 정말 변경되는 사항이 없어서 좋았다.
5.
10트 만에 만들어서 다행이다.
6.
고민을 많이 할 수 있어서 좋았다. “단순한 문제라서 대충 하지 뭐”이렇게 생각하지 않아서 다행이다. 이런 고민이 상당히 재미있었다.
7.
테스트 자체가 내가 만든 코드를 대변해주는 걸 알아서 좋았다. “잘 만든 코드는 테스트 하기 쉽다” 를 알았다.