2017-02-01 1 views
5

저는 소수의 작은 프로젝트에서 Realm을 사용 해왔고 꽤 좋아했습니다. 나는 더 큰 프로젝트에서 그것을 사용하는쪽으로 나아 가기를 바라고 있으며, 나는 더 나은 구조의 데이터 액세스 레이어를 찾고있다.Realm에서 더 나은 데이터 액세스 레이어를 작성하는 방법

나는이 비슷한 question을 발견 했으므로 거기에서 발견 한 정보를 바탕으로 노력했다. 여기서 논의 된 접근법은 DAO 패턴이므로 나는 그것에 대해 설명했다.

이것은 내 모델 클래스입니다.

class Chat: Object { 
    dynamic var id: String = "" 
    dynamic var createdAt: Date = Date() 
    dynamic var creatorId: String = "" 
    dynamic var title: String? 
    let chatMessages = List<ChatMessage>() 

    override static func primaryKey() -> String? { 
     return "id" 
    } 

    convenience init(fromJSON json: JSON) { 
     self.init() 
     // ... 
    } 
} 

그런 다음 모든 편의 헬퍼 메소드를 보유하기 위해 ChatDAOProtocol을 만들었습니다.

protocol ChatDAOProtocol { 
    func addMessage(_ message: ChatMessage) 
    func getChatThumbnail() -> UIImage 
    func getParticipants(includingMe: Bool) -> [Participant]? 
    static func getChat(fromId id: String) -> Chat? 
    static func getChat(fromCreatorId id: String) -> Chat? 
} 

마지막으로 모든 프로토콜을 구현 한 ChatHelper이라는 또 다른 클래스를 만들었습니다.

class ChatHelper: ChatDAOProtocol { 
    func addMessage(_ message: ChatMessage) { 

    } 

    func getChatThumbnail() -> UIImage { 
     return UIImage() 
    } 

    func getParticipants(includingMe: Bool) -> [Participant]? { 
     return nil 
    } 

    static func getChat(fromId id: String) -> Chat? { 
     return nil 
    } 

    static func getChat(fromCreatorId id: String) -> Chat? { 
     return nil 
    } 

} 

이것은 이미 VC와 관련된 모든 데이터베이스 관련 코드를 뿌리는 것보다 낫습니다. 그러나 나는 여전히 의심을 가지고있다.

예를 들어, 채팅 참가자를 모두 얻으려면 이제 ChatHelper 클래스의 메서드를 호출해야한다고 말하십시오. 채팅 제목을 얻고 싶다면 개체의 title 속성을 호출합니다. 매우 통일 된 인터페이스처럼 보이지 않습니다. 도우미의 모든 속성에 대해 getter 및 setter를 포함해야합니까? 따라서 Chat 객체는 직접 호출되지 않습니다 (인스턴스 생성을 제외하고).

또는

은 내가 Chat 객체 자체가 ChatDAOProtocol 프로토콜을 준수하게해야 하는가? 따라서 모든 편의 메서드와 속성은 직접 Chat 개체에서 직접 액세스 할 수 있습니까?

아니면 둘 다 더 좋은 방법이 있습니까?

답변

2

이것은 Realm과 직접 상호 작용하지 않고 얼마나 많이 추상화하고 싶은지, 그리고 Realm의 성능과 어느 정도 타협하고 싶은지에 따라 매우 까다로운 질문입니다.

필자는 개인적으로 쿼리를 추출하고 논리를 작성하지만 Realm 모델 객체에서 직접 읽는 것이 좋다고 생각합니다. 핵심 데이터와 같은 다른 객체 기반 데이터베이스로 이동 한 경우 이러한 객체가 다른 객체 (예 : RLMObject ~ NSManagedObject)에 속한 부모 클래스를 리팩터링하는 동안 비즈니스 로직이 이러한 객체에서 읽는 방식은 변경되지 않습니다 .

당신이 분명히주의해야 할 한 가지는 논리가 매우 비효율적으로 활용되는 방식으로 논리를 추상화하는 것입니다.

내가 볼 수있는 주요 예는 getParticipants 메서드에 있으며, 표준 Swift 배열을 반환합니다. 영역 Results 객체를 그러한 객체로 변환하면 (요청시 지연로드와 달리) 모든 객체가 메모리에 페이징되므로 결과적으로 많은 Realm 성능 이점을 잃을 수 있습니다. 그러나 Results 객체는 표준 배열처럼 동작하므로 직접 반환 한 경우 비즈니스 논리를 변경할 필요가 없습니다.

또 다른 고려 사항 : 개체 배치에서 단일 속성을 업데이트하는 경우 내부적으로 쓰기 트랜잭션을 여는 도우미 클래스 대신 모든 개체가 단일 쓰기 트랜잭션에서 업데이트되도록하는 것이 훨씬 좋습니다 도우미 메서드가 호출 될 때마다

+0

답장을 보내 주셔서 감사합니다. 언급 한 요점을 고려하여 내 코드를 다시 작성합니다. 그렇다면 같은'Chat' 클래스에서 헬퍼 메소드를 갖는 것이 바람직하다고 생각하거나 헬퍼 메소드를위한 별도의'ChatHelper' 클래스를 만드는 것이 더 낫다고 생각합니까? – Isuru

관련 문제