Persistance layer 추상화 리팩토링 - Team-HGD/SniffMEET GitHub Wiki

  • ImageManagable와 FileManageable

    • 공통적인 책임이 중복되어 있었음.
    • 데이터를 저장, 가져오기, 삭제하는 메서드가 동일하게 반복되었음.
    protocol ImageManagable {
        func image(forKey: String) throws -> Data?
        func setImage(imageData: Data, forKey: String) throws
        func deleteImage(forKey: String) throws
    }
    
    protocol FileManageable {
        func fetch(forKey: String) throws -> Data?
        func set(data: Data, forKey: String) throws
        func delete(forKey: String) throws
    }
    
    
  • ImageCacheable

    protocol ImageCacheable {
        func save(urlString: String, lastModified: String?, imageData: Data?)
        func image(urlString: String) -> CacheableImage?
    }
    
  • UserDefaultsManagable와 KeychainManagable

    • 데이터 저장/읽기/삭제의 공통적인 책임이 중복
    • Keychain이 String 타입으로 제한
    protocol UserDefaultsManagable {
        func get<T>(forKey: String, type: T.Type) throws -> T where T: Decodable
        func set<T>(value: T, forKey: String) throws where T: Encodable
        func delete(forKey: String) throws
    }
    
    protocol KeychainManagable {
        func get(forKey: String) throws -> String
        func set(value: String, forKey: String) throws
        func delete(forKey: String) throws
    }
    
protocol DataStorageManagable {
    func get<T: Decodable>(forKey key: String, type: T.Type) throws -> T
    func set<T: Encodable>(value: T, forKey key: String) throws
    func delete(forKey key: String) throws
}

// MARK: - 세부 저장소 추상화
protocol ImageManagable: DataStorageManagable {}
protocol FileManageable: DataStorageManagable {}
protocol UserDefaultsManagable: DataStorageManagable {} 
protocol KeychainManagable: DataStorageManagable {} // TokenManageable 
  • DataStorageManagable로 공통화

    저장소와 관련된 기본 동작(getsetdelete)을 단일화하여 중복된 코드 제거.

  • 일관성 강화

    KeychainManager도 Encodable과 Decodable을 지원하도록 개선하여 전체 설계의 일관성을 유지.


고민 내용

  1. FileManager → Data 타입에 대해서 CRUD를 수행한다.
  2. KeyChainManaer → String 타입에 대해서 CRUD를 수행한다.
  3. UserDefaultManager → Encodable 혹은 Decodable을 채택한 모든 타입에 대해서 CURD를 진행한다.

1, 2는 특정 타입에 대해서 CRUD를 수행하는 상위 프로토콜로 추출할 수 있지만 UserDefault는 모든 타입에 대해서 추상화를 하는 타입이어서 그렇지 못하다.

→ 그런데 UserDefault는 여러 메타데이터를 저장하고 여러 역할에 쓰이는데 이게 다른 저장소로 대체될 가능성이 높은가? 그렇지 않다면 굳이 상위 프로토콜로 분리할 필요가 없다.

지금처럼 UserDefaultManageaable로 추상화한게 최선이 아닐까하는 생각이 든다.