Search
⚙️

템플릿 어떻게 만들어? 209p~277p

생성일
2022/03/09 22:12
태그

템플릿 어떻게 만들어?(서론 및 주제)

템플릿? 템플릿? 뭘까? 고민을 엄청 엄청 많이 했다. 코딩 할 때 “템플릿을 만들어 사용해야지!” 라는 생각보다는 “실행만 되도록 만들어보자..” 라고 생각했던 지난 날들이 많이 생각났다. 그래서 내가 느끼고 내가 생각하는 템플릿? 그것이 무엇인지 설명하려고 한다.
토비의 스프링에서 템플릿에 관련한 주제들

템플릿이 뭘까?(개념)

토비의 스프링에서는 템플릿을 설명할 때 바뀌는 성질이 다른 코드 중에서 변경이 거의 일어나지 않으며 일정한 패턴으로 유지되는 특성을 가진 부분을 자유롭게 변경되는 성질을 가진 부분으로부터 독립시켜서 효과적으로 활용할 수 있도록 하는 방법이라고 설명한다.

그렇다면 템플릿이 왜 좋아?(개념 장점)

Template은 일정한 틀, 형식을 의미한다. 이것은 우리도 모두 다 아는 사실이다. 그리고 템플릿을 활용하면 좋은 점도 알고 있다. 1. 일정한 형식을 가지면 실수를 줄일 수 있다. 2. 재활용 가능하다. 등의 장점을 알 수 있다. 그런데 이 장점 외에도 프로그래밍 관점으로 본다면 템플릿은 또 다른 장점을 가진다. 3. 테스트가 매우 쉬워진다. 4. 문제를 파악하고 수정하기 쉬워진다. 5. 변경에 강해진다.

그렇다면 템플릿이 안 좋을 수 있을까?(개념 단점)

Template은 일정한 틀, 형식을 의미한다. 그만큼 자유롭게 만드는 것이 제한된다. 하지만 여기서 제일 중요한 점은 모든 것을 전부 템플릿으로 만드는 것이 아니다. 바뀌지 않는 부분만 뽑아내어 템플릿을 만들어야 한다. 만약 내가 템플릿을 만들때 바뀌는 부분을 고려하지 않는다면 안 좋을 수 밖에 없는 템플릿이다. 하지만 변하지 않는 부분을 템플릿으로 만든다면 템플릿의 장점을 100% 활용할 수 있다. 그렇다면 이러한 템플릿을 만드는 과정을 토비의 스프링 예제로 살펴보자.

토비의 스프링에서 보는 템플릿(방법)

토비의 스프링의 템플릿에서 가장 강조 되는 내용은 확장에는 자유롭고, 변경에는 닫힐 수 있는 OCP(개방-폐쇄 원칙)원리를 생각하여 템플릿을 만들어야 한다고 한다.

다시보는 초난감 DAO? (템플릿이 나오게 된 계기)

템플릿을 바라보기 시작한 단계

위의 예제를 통하여 템플릿이 성장했다. 또한 스프링이 생겨나고 더 이상 전략의 선택에 있어서 직접적인 선택이 아닌 의존관계 주입이라는 기술이 탄생하며 템플릿의 활용도는 무궁무진하게 상승했다. 여기서 잠깐 정리를 해보자. 1. 템플릿이라는 개념적 생각은 먼저 코드를 오류 없이 잘 만들고 나서 시작한다. 2. 다 잘 만들어진 코드를 기반으로 변하지 않는 부분과 변하는 부분을 생각한다. 3. 변하지 않는 부분을 따로 제작하고 이를 받아서 사용하는 형태로 만든다. 1) 처음에는 클래스 상속을 통하여 2) 인터페이스를 사용한 전략 패턴을 사용한다. 4. 의존성 주입이라는 개념 덕분에 전략을 넣어주기 더 쉬워졌다.

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

이렇듯 템플릿은 오류 없는 코드에서 변하는 부분과 변하지 않는 부분을 나누어 사용하는 형태로 만드는 과정이다. 이러한 맥락에서 나도 평소 자주 사용하는 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.
테스트 자체가 내가 만든 코드를 대변해주는 걸 알아서 좋았다. “잘 만든 코드는 테스트 하기 쉽다” 를 알았다.

인용 및 참고

www.baeldung.com
Mockito 사용법 및 Mockito에서 stream API 사용하기