코드 개선 - 전개편 (4)

코드 개선 - 전개편 (4)

드디어 최종 보스전에 돌입하다!

·

3 min read

이번 코드 개선을 시작하게 된 가장 큰 계기인 데이터 관리 코드가 너무 별로였다는 점이다. 말이 좋아서 별로지 이 코드를 봤다면 모두가 한숨을 내쉬었을 정도다.


그런데 여기까지 오기가 꽤 많은 일들을 해치워야했고, 드디어 최종 보스전이다. (마지막 전개편이다.) 이번에는 커밋한 내용이 꽤 많았는데, 그럴만 했다. 준비편에서 계획한 데이터 구조를 기억하는가? 일단 큰 변경 지점이 있었고, 이걸 이전 데이터에도 올바르게 적용했어야했다. 일단은 새로운 테이블 추가, 기존 방식과 다른 모음집 정보 불러오기, 기존 구조의 데이터도 현재에 불러올 수 있도록 코드 추가, 각각의 데이터에 추가 삭제 시 발생 가능한 오류 제거를 해야했다. 그리고 하는 중 문제가 생기면 그것도 해결했다...


우선, 내가 변경한 내용은 다음과 같았다.

  • 부스러기(crumbs)라 부르는 요소가 조각(piece)에 귀속되는데, 이를 조각 파일에 넣어두고 조각의 관리자 클래스인 PieceMO에서 관리했었다. 이를 분리해야 한다.

  • 부스러기를 분리하면서 조각 내에 딕셔너리로 존재하던 값을 구조체로 변경한다.

  • 기존의 객체를 다루는 것과 차이점이 있기에 이전 버전에서 작성된 요소를 불러올 수 있도록 LegacyManager를 구현한다.

  • 카테고리에 대해서 enum으로 작성하고 이에 맞는 string값을 딕셔너리로 구현했었는데, 이를 enum에 String을 상속 받는 것으로 수정한다.

      // 변경 전
      enum Category: String, Codable, Hashable {
          case film, game, music, book, show, photo, flag, airplane, piece
      }
      let categoryIcon: [Category : String] = 
      [Category.film : "film", /*일부 생략*/]
    
      // 변경 후
      enum Category: String, Codable, Hashable, CaseIterable {
         case film = "film" /*일부 생략*/
      }
    
  • 인스턴스를 구분하는 id 항목을 String이 아니라 UUID 객체로 변경한다. Realm에 저장하고 불러올 때만 UUID <-> String 변환을 거치도록 한다.

  • 모음집(Series)와 조각 사이의 관계를 나타내는 Contain이라는 테이블을 신설한다.

  • 데이터 관리 클래스를 별도로 만들어 기존에 뷰 컨트롤러에서 작업하던 데이터 관리 작업을 양도한다. 조각과 모음집 관련으로 생성한다. PieceDataManager와 SeriesDataManager.

  • Realm과 소통하는 RealmManager를 만들어 데이터 처리 과정 단계를 나눈다. 프로그램 내부 클래스에 생긴 수정 사항을 반영하기 용이하게 만드는 데 초점을 둔다. 앞 서 언급한 두 개의 DataManager하고만 데이터를 주고받는다.

  • 각 DataManager와 RealmManager는 싱글톤 객체로 만들어 사용한다.

      class PieceDataManager {
          private let realm: RealmManager = RealmManager.general
          public static let general: PieceDataManager = PieceDataManager()
    
          // 코드 중략
    
          // 함수 Quick Help Information도 작성
          ///신규 조각 하나를 추가합니다.
          func appendPiece(_ newPiece: Piece) {
              self.whole.append(newPiece)
              self.realm.appendNewPieces(newPiece)
          }
          //코드 하략
      }
    

대충 이정도의 변경 사항을 목표로 작업했다.


그리고 발생한 오류들 중에 삭제 후 변경 작업 시 index가 제대로 매치되지 않는 오류가 있었는데 이 오류로 생각한다. 그래서 realmManager에서 작업할 때는 인덱스가 아닌 id로 접근하여 수정과 삭제 등이 이루어지도록 변경했다.

기존 문제 중에 UI 오류 메시지가 뜨는데 (보이는 것도 다 잘 보이고 눌리는 것도 다 잘 눌리는) 동작 문제는 없었다. 이유를 모르고 있었는데 놀랍게도 데이터 코드를 싹 정리하고 나니 멀쩡해졌다.

중간에 잠시 그런 문제가 다시 발생했었는데 시뮬레이터 오류였는지 시뮬레이터 껐다 켜니까 그 뒤로는 멀쩡하게 동작했다. 구글에 검색해봤을 때 이 문제는 UI 오류라고 하는 글이 많았는데 일단 고쳐졌지만, 데이터 문제였을 수도 있을 것 같다.

그리고 좀 어이없는 일이긴 하지만 모음집이 삭제 기능이 없었다... 물론 만들어야 한다는 인지도 있었고 이번 업데이트에서 빼놓을 수 없는 부분이었다. 그래서 만들었고 잘 작동했다.


쉽고 재미없는 결말

데이터 변경 작업이 생각보다 쉬웠다. 일단 이전 단계를 거치면서 구조를 명확하게 파악해둔 것이 큰 역할을 했다. 그리고 미리 싱글톤 등 데이터 관리 클래스를 구성할 방법에 대해 고민했기 때문에 실제 작업에서는 시간이 많이 줄었다.

음, 쓰고 나니까 보스전 치고는 굉장히 쉽게 깨진 느낌이다. 실제로도 큰 장벽은 없었다. 하지만 이게 보스전을 치루기 전에 중간 보스들을 잘 처리한 덕분이라고 생각한다. 다음은 결말편인데... 사실 마무리라고 미뤄둔 세세한 부분을 정리하는 단계다.


여담

이 글을 쓰는 지금은 1.1.1 버전을 준비하고 있다. 학교 프로젝트로 바쁘기도 하고... 어쨌든 이 쉽고 재미없는 전개가 이야기로 본다면 그닥 흥미로운 이야기는 아니지만, 괜찮은 이야기라고 생각한다. 왜냐하면 난 개발자고 보스전을 쉽게 깨기 위해 앞의 작업들을 했기 때문에 목표 달성에 성공한 개발자이기 때문이다. ^^