-
Swift4: Protocol Oriented Programming - 8.사례 연구POP 2021. 3. 6. 19:48
8장 사례 연구
실제 프로젝트를 통해 언어와 프로그래밍 패러다임을 익혀보자. 디자인 패턴 사용을 적극적으로 고려하자.
- 애플리케이션을 위한 로그 서비스 만들기
- 데이터 접근 계층 만들기
로깅 서비스
로깅 프레임워크는 애플리케이션을 개발하면서 디버깅을 쉽게 도와주는 로그 메세지를 간단하게 작동시킬 수 있도록 해준다.
요구사항
- 여러 가지 로그 레벨을 가져야만 한다. Fatal, Error, Warn, Debug, Info 로그 레벨이 있다.
- 여러 가지 로그 프로파일을 가진다. LoggerNull와 LoggerConsole 두 가지 프로파일이 있고, LoggerNull은 로그 메세지에 할 수 있는 일이 아무 것도 없다. LoggerConsole 프로파일은 콘솔에 로그 메세지를 출력한다.
- 사용자는 자신만의 로깅 프로파일을 추가하는 능력이 있어, 데이터베이스나 UILable 등의 장소에 메세지를 기록할 수 있다.
- 로깅 서비스는 앱을 시작하면, 로깅 프레임워크를 설정하는 능력이 반드시 있으며, 앱 라이프사이클 동안 설정을 유지해야 한다. 로깅 서비스는 프레임워크를 사용하는 사용자가 서비스를 사용해야 할때마다 재설정하도록 강제하길 원치 않는다.
- 로깅 서비스는 사용자에게 여러 프로파일로 로그를 출력하거나 저장하도록 하기 위해 하나의 로그 레벨에 여러 로거 프로파일을 지정할 수 있다.
다이어그램
-
로거 프로파일
LoggerProfile
프로토콜에 프로파일 아이디와 writeLog() 함수르르 정의하고 확장을 이용하여, 현재 날짜와 시간을 형식화한 문자열을 반환하는 함수를 추가해 준다. 해당 프로토콜을 따르는LoggerNull
,LogerConsole
프로파일을 정의한다. -
로거 타입
타입 프로퍼티와 메소드를 가진
Logger
프로토콜을 이용하여 앱 라이프사이클 내내 오직 하나의 인스턴스만 존재하도록 한다. Logger 프레임워크처럼 매우 작은 공간을 차지하는 프레임워크를 만들 때 타입 프로퍼티와 메소드를 사용하면 편리하다.
// 커맨드 패턴 사용 struct MyLogger: Logger { static var loggers = [LogLevels : [LoggerProfile]]() static func writeLog(logLevel: LogLevels, message: String) { guard hasLoaggerForLevel(logLevel: logLevel) else { print("No logger") return } if let logProfiles = loggers[logLevel] { for logProfile in logProfiles { logProfile.writeLog(level: logLevel.rawValue, message: message) } } } } MyLogger.addLogProfileToAllLevels(defaultLoggerProfile: LoggerConsole()) MyLogger.writeLog(logLevel: LogLevels.Debug, message: "Debug Message 1") MyLogger.writeLog(logLevel: LogLevels.Error, message: "Error Message 1")
데이터 접근 계층
애플리케이션에서 일정 데이터를 유지하는 여러 가지 방법이 있을 것이다. 설계 시 비즈니스 로직과 실제 데이터 저장소를 서로 분리하여 비즈니스 로직을 변경하지 않고도 미래에 데이터를 종속시키는 방식을 변경할 수 있다. 이를 데이터 접근 계층 이라고 한다.
요구사항
- 백엔드 데이터 저장소의 모든 접근은 데이터 도우미 타입을 거친다. 이 타입은 저장소의 CRUD를 모두 처리한다.
- 데이터 접근 계층 바깥의 코드는 데이터의 유지 방식에 대해 관심이 없다.
- 야구 선수에 대한 정보를 포함하는 player 타입과 야구 팀에 대한 정보를 포함하는 team 타입이 있다. 야구 선수는 팀 ID와 팀에 대한 정보를 가지고 있다.
다이어그램
데이터 접근 계층을 3 계층으로 나눈다.
최하단의 데이터 도우미 계층은 데이터를 영속시키는데 사용하고, 데이터 모델 계층은 데이터 도우미 계층에 데이터를 저장하는 방식을 유사하게 모델링한
tuple
을 이용하여 데이터 처리를 위한 임시 저장소로 사용한다. 브리지 계층은 비즈니스 로직의 데이터를 데이터 접근 계층의 데이터로 변환한다.var bos = Team(teamId: 0, city: "Boston", nickName: "Red Sox", abbreviation: "BOS") try? TeamBridge.save(&bos) var ortiz = Player(playerId: 0, firstName: "David", lastName: "Ortiz", number: 34, teamId: bos.teamId, position: .designatedHitter) try? PlayerBridge.save(&ortiz) if let team = try? TeamBridge.retrieve(0) { print("--- \(team.city)") } if let player = try? PlayerBridge.retrieve(0) { print("--- \(player.firstName) \(player.lastName) plays for \(player.team?.city)") }
메인 코드에서 사용할 때에는 다음과 같이 Bridge 타입을 사용하여 접근하기 때문에 백엔드 데이터의 처리 방식을 몰라도 사용 가능하며, 변경도 손쉽게 할 수 있다.
코드
참고 문헌
https://book.naver.com/bookdb/book_detail.nhn?bid=14107671
'POP' 카테고리의 다른 글
Swift4: Protocol Oriented Programming - 7.스위프트에서 디자인 패턴 적용 - (3) 행위 패턴 (0) 2021.02.24 Swift4: Protocol Oriented Programming - 7.스위프트에서 디자인 패턴 적용 - (2) 구조 패턴 (0) 2021.02.24 Swift4: Protocol Oriented Programming - 7.스위프트에서 디자인 패턴 적용 - (1) 생성 패턴 (0) 2021.02.19 Swift4: Protocol Oriented Programming - 6.프로토콜지향 프로그래밍 (0) 2021.02.17 Swift4: Protocol Oriented Programming - 5.객체지향 프로그래밍 (0) 2021.02.16