본문 바로가기
iOS

UICollectionView IndexPath 리팩토링

by vapor3965 2021. 8. 28.

목차

     

     

    작년에 만들었던 앱을 리팩토링 하고 있다. 

     

    예전에는 왜 그렇게 짰는지.. 이해할 수 없는 건 아니지만 ㅎㅎ 리팩토링 하는 입장에서는 힘들다. 

    기존 뷰컨트롤러를 작성한 구조도 그렇고, 뷰 구성도 마음에 안 들어서 아예 새롭게 뷰 컨트롤러를 만들어서 작성했다. 

    ( 그래도 신기한건 리팩토링 할 처음 당시에는 그렇게 기존 코드를 보기 싫었는데, 다 완성할 때쯤에는 이제 눈에 어느 정도 익혀졌다는 게 신기하다. )

     

     

    그 과정에서 CollectionView를 사용하게 되었고, 하다보니, section의 수가 7개가 되었다. 

    cellForItemAt과 같은 메서드나, numberOfItemInSection과 같이, indexPath를 통해 구분하여 각각에 맞는 cell 또는 헤더, 푸터 뷰를 제공해야 한다. 

    어느 정도 구현할 때 까지는,  아래처럼 각 섹션에 대해 section 숫자 값을 외우면서 하나씩 다 숫자로 지정했다. ( 끔찍 ) 

    나 아니면 딱 봐도 알아보기 힘들다. 만든 나도 가끔 헷갈린다. 만약 섹션의 수가 더 많다면? 

    정말 개발하면서 이런 사소한거에 머리를 쓰는 것도 체력 소모다.. 

    case 0이 도대체 어떤 섹션을 의미하는 건지? 어떤 모양처럼 생긴 애인지? 이해가 안 간다. 

     

    또, 앱이 더 이상 변화가 생기지 않는다,

    또는 절대 업데이트를 안하겠다.

    또는 이 이후로 앱을 절대 건드리지 않겠다! 가 아닌 이상

    분명 어떤 변화가 생길 수밖에 없고,  ( 예를 들어 추가적으로 섹션을 추가한다거나, 섹션의 위치들을 변경한다거나... )

     

    특히 섹션의 위치를 변경하거나, 섹션들 그 중간에 넣겠다고 가정하면... 이는 나비효과처럼 계속 코드를 고쳐야 한다. 

    indexPath를 통해 구분하는 모든 코드들은 다 고쳐야한다. 정말 매우 불편하고 귀찮은 일이다. 

    OOP에서 원칙 중 하나인 개방 폐쇄의 원칙으로,  지금 이 부분에서는 섹션을 추가로 중간에 넣는 건 자유로워야 하고, 

    섹션을 추가로 넣음으로써 다른 부분들은 수정하지 않아야 한다고 볼 수 있다.

     

    늘 예전부터 숫자로 할당하는 것을 매우 좋아하지 않았는데 그 이상 고민해본 적이 없었다. 

    더 이상 이 불편함을 참지 말자. 이번에는 한번 고민해봤다. 

     

     

    리팩토링 하기 

    접근은 이랬다.

    숫자 대신 가독성 있는 어떤 걸로 표시하면 안 될까? 

    예를 들어 case 0 이 아닌, case SomeSection:처럼. 

     

    특히 이렇게 분기 처리하는, 열거할 수 있는 특징과 더불어 가독성 있게 도와주는 Enum타입이 생각났고,

    Enum타입에는 rawValue를 포함할 수 있는데, 

    이 값에는 Int타입도 가능하므로, 이를 활용하면 되겠다라고 생각이 들었다. 

     

    그래서 다음과 같이 Enum을 만들었고, 

    굳이 **Section을 추가한 이유는, 

    결국 switch 구문에서는 Int타입이 사용되어야 하는데, 

    매번 끝에 .rawValue를 붙이기는 뭔가 별로였다.  그래서 rawValue를 감싸주도록 만들어줬다. 

     

    그래서 만든 Enum을 다음과 같이 적용했다. 

    이게 best라고 생각하지도 않지만, 그래도 이전의 숫자 값으로 부여하는 것보다 훨씬 가독성이 좋다라고 생각한다. 

     

    또 이것의 장점은, 추가적으로 섹션을 중간에 삽입한다고 가정할 때에 있다. 

    기존에는 그런 경우에 하나씩 밀어줘야 했다. 중간 이후부터 숫자 값을 추가해주거나 등 

    그럼 indexPath로 구별하는 모든 코드들을 수정해줘야 했다. 

     

    하지만 이제는 Enum에서 case에 있는 rawValue들만! 수정해주면 된다. 그 외 indexPath에서 사용된 곳들은 다 rawValue를 가리키고 있기 때문에 다른 부분은 전혀 신경 쓰지도, 수정할 필요도 없다. 

     

    사실 이것도 case들도 수정한다는 점에서 개방 폐쇄의 원칙에서 탈락했다고 생각이 들지만,

    그래도 이전 코드보다 훨씬 수정하는 상황이 적기 때문에 나는 조금 괜찮지 않나 생각한다. 

     

    더 좋은 방법이 있겠지만 아직은 떠오르지 않는다. 더 좋은 코드를 살펴봐야겠다. ㅎㅎ 

     

     

     

    ( 이 코드 또한 내년에 보면 왜 이렇게 짰을까... 하겠지? ) 

     

     

     

     

     

     

     

    댓글