티스토리 뷰
제네릭을 사용하면 코드의 중복을 제거할 수 있다는 장점이 있습니다. 같은 일을 하는 메소드가 parameter type이 달라서, return type이 달라서 중복 된 코드를 짜야한다면 불필요하게 파일이 길어지겠죠? 이번에 제네릭을 사용해보니까 네트워크 요청을 할 때 유용하게 사용할 수 있더라구요. 그래서 그 경험을 공유해보고자 합니다.
네트워크 통신을 하다보니 비슷한 로직을 가진 서버에 데이터를 요청하여 받아오면 모델에 맞게 decoding을 진행해서 필요에 따라 가공해서 사용하는게 일반적이죠? 예를 들어 Album, Artist, Playlist 모델이 있다면 func fetchAlbum( ), func fetchArtist( ), func fetchPlaylist( )라는 메소드를 통해 그 일련의 과정들을 거칠텐데, 아래와 비슷하게 생겼을 것 같아요.
func fetchAlbum(completion: @escaping (Result<Album, Error> -> ()) {
network.requestData() { result in
switch result {
case .success(let data) :
guard let requestForm = try? JSONDecoder().decode(Album.self, from: data) else {
// decoding error 처리
return
}
completion(.success(requestForm))
case .failure(let error):
compleion(.failure(error))
}
}
}
}
func fetchArtist(completion: @escaping (Result<Artist, Error> -> ()) {
// 같은 로직, decode(Artist.self, from: data)
}
func fetchPlaylist(completion: @escaping (Result<Playlist, Error> -> ()) {
// 같은 로직, decode(Playlist.self, from: data)
}
메소드 내의 로직은 같고, 메소드 내에서 사용되는 model type이 상이한 경우기 때문에 제네릭을 적용해 볼 수 있습니다. 그래서 기존 코드는 아래와 같이 수정해볼 수 있고 사용할 때는 사용할 model type을 지정해주면 됩니다.
func fetchtData<T: Decodable>(completion: @escaping (Result<T, NetworkError>) -> ()) {
endpoint.requestData(params: params) { result in
switch result {
case .success(let data):
guard let requestForm = try? JSONDecoder().decode(T.self, from: data) else {
completion(.failure(.decodingError))
return
}
completion(.success(requestForm))
case .failure(let error):
completion(.failure(error))
}
}
}
// 사용할 때
NetworkManager.fetchData() { [weak self] (result: Result<SearchResult, NetworkError>) in
guard let self = self else { return }
switch result {
case .success(let searchResult):
// 받은 데이터로 처리
case .failure(let error):
// 에러 처리
}
}
그런데 사용하다보니 조금 고민되는 부분이 있더라구요. 메소드 명이 같고, 파라미터나 리턴타입이 다른 경우를 오버로딩이라고 부르는데, 오버로딩을 해야하는 순간과 제네릭으로 묶는게 좋은 순간이 고민됐습니다. 중복 된 코드가 좋지 않다지만, '메소드를 사용할 때 개발자의 실수를 줄일 수 있다면 분명하게 정해진 메소드가 좋지 않나?'라는 생각이 들었습니다. 만약 메소드명이 불분명하여 오버로딩이 부적격하다면 메소드명을 구체적으로 짓고 중복 된 코드가 나쁜가 싶기도 했어요. 정해진 답이 없는 문제다 보니 포럼같은 곳들 돌아다니며 찬찬히 다른 사람들의 의견을 좀 읽어봐야겠어요!
'iOS' 카테고리의 다른 글
[iOS] URL = nil ?? addingPercentEncoding (1) | 2022.09.04 |
---|---|
[Swift] Struct와 Class 비교하기 (2) (0) | 2021.12.08 |
[iOS] UICollectionView와 관련 된 경험들 (2) | 2021.12.05 |
[iOS] URLSession dataTask의 Error (+ Result type) (0) | 2021.11.19 |
[iOS] Multi-threading과 Concurrency(1) : Thread, Queue, Race Condition (0) | 2021.11.07 |
- Total
- Today
- Yesterday
- 소프트웨어역량시험
- SWIFT
- nosql
- C++
- 부스트캠프2020
- 개발자인턴
- 컴공졸작
- 인턴
- 졸업작품
- 운영체제
- 데이터분석
- 부스트캠프
- 알고리즘
- ios
- 삼성소프트웨어아카데미
- 컴과졸작
- 부캠
- 보안
- RxSwift
- firebase
- 코딩테스트
- 코테
- 컴퓨터공학
- OS
- 삼성
- 소프트웨어아카데미
- swacademy
- 커넥트재단
- 프로그래머스
- TableView
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |