Вопрос:

Шаблон при использовании Realm в Cocoa Touch Framework

swift cocoa-touch design-patterns realm cocoapods

154 просмотра

1 ответ

2838 Репутация автора

Это вопрос кода / дизайна при использовании удивительной базы данных Realm в Cocoa Touch Framework. В частности, рамки, которые будут распространяться как cocoapod.

Допустим, у меня есть некоторые объекты области внутри каркаса, который я строю

public class Dog: Object {
    @objc public private(set) dynamic var name: String?
    public let age = RealmOptional<Int>()
    public private(set) var owner: Person?
}

public class Person: Object {
    @objc public private(set) dynamic var name: String?
    public private(set) var dogs = LinkingObjects(fromType: Dog.self, property: "owner")
}

Теперь я хочу, чтобы потребитель моей платформы мог взаимодействовать с этими объектами. Я не хочу абстрагировать их с помощью шаблона MVVM, потому что я хочу, чтобы пользователь моей инфраструктуры мог использовать некоторые замечательные возможности Realm, такие как запросы, сортировка и, самое главное, уведомления об изменениях Realm.

Итак, первый вопрос. Должен ли я позволить пользователям моей платформы инициализировать объекты напрямую? Они будут иметь эти опции уже с инициализаторами Realm, и если они решат использовать их, они несут ответственность за них. Но мне нравится использовать фабричный шаблон, используя статические методы. Нравится:

extension Dog {
    public static func retreiveManagedDog() throws -> Dog {
        let dog = Dog()
        do{
            let realm = try Realm()
            realm.beginWrite()

            realm.add(dog)
            try realm.commitWrite()
        }catch{
            throw error
        }
        return dog
    }
}

Это хороший шаблон дизайна для этого варианта использования?

Во-вторых, следующая проблема - обновление объектов. Поскольку все объекты Realm должны быть обновлены внутри транзакции записи, я не хочу, чтобы пользователь моей инфраструктуры должен был написать набор шаблонного кода, чтобы просто изменить имя. Итак, я пишу такие функции:

//MARK: Extension that has functions to update properties
extension Dog {
    public func updateName(_ name: String?) throws {
        do{
            let realm = try Realm()
            realm.beginWrite()
            self.name = name
            try realm.commitWrite()
        }catch{
            throw error
        }
    }
}

Обратите внимание на мои определения объектов private(set)только по этой причине. Это поможет заставить пользователя моей платформы использовать мои методы установки.

Вообще, я безумен, пытаясь обернуть Царство таким образом? Другие хорошие структуры, которые сохраняются, обычно оборачивают всю логику SQL Lite / Core Data. Я также хотел бы предложения по улучшению этой модели в целом.

Автор: Jon Vogel Источник Размещён: 08.11.2017 10:29

Ответы (1)


2 плюса

1637 Репутация автора

Решение

К счастью, я не думаю, что есть какие-то твердые правильные ответы на ваши вопросы. Это действительно зависит от того, что вы пытаетесь сделать.

Во-первых, это хорошая идея не вмешиваться в Realm по умолчанию или в конфигурацию Realm по умолчанию, поскольку вполне вероятно, что любое приложение, использующее Realm напрямую, может также манипулировать. Вы также захотите убедиться, что вы используете пространство имен для типов вашей модели и исключаете их из схемы по умолчанию. (Точно так же вы, вероятно, захотите открыть Realms своей структуры, используя только схему моделей, которые вы определяете внутри.)

Что касается вашего API, то, как он будет выглядеть, будет определяться тем, для чего вы хотите использовать Realm в контексте вашей платформы.

Если Realm - это деталь реализации, имеет смысл контролировать, как пользователи взаимодействуют с объектами, основанными на Realm, через API, подобные тем, которые вы описали выше. Таким образом, вы можете точно контролировать, что пользователи могут делать с объектами модели, и гарантировать, что они не могут быть изменены таким образом, что их состояние станет недействительным (если это вызывает озабоченность).

Например, вы можете захотеть обработать регистрацию и отмену регистрации блоков наблюдателей для объекта Realm для пользователя через предоставляемый вами API, который определяет его собственные предварительные условия и требования. Это может быть полезно, если период времени, в течение которого объект должен наблюдаться, должен совпадать или контролироваться каким-либо другим объектом или системой, являющейся частью вашей среды: вместо того, чтобы указывать пользователям, как хранить свои маркеры уведомлений и когда нужно избавившись от них, вы можете позаботиться обо всех этих деталях за кулисами и убедиться, что пользователь не может неправильно использовать Realm в контексте вашей структуры.

Вы даже можете довести это до крайности и сделать использование Realm невидимым для ваших пользователей, приведя типы ваших Realm в соответствие с некоторыми протоколами и сделав так, чтобы ваши API использовали и продавали этот тип протокола. Таким образом, ваши пользователи не смогут сказать, что ваши объекты являются объектами Царства, и у них не будет соблазна вставить их в свои Царства, скопировать их и т. Д.

Однако, если вы хотите, чтобы пользователи знали, что вы предоставляете им объекты Realm в своем API, и, возможно, даже используете их вместе с собственным использованием Realm (например, помещаете их в свои собственные Realm), то имеет смысл явно продавайте их как объекты Realm, возможно, с помощью вспомогательных API, подобных тем, которые вы описали строго по соображениям удобства. В этом случае вы захотите подумать о том, как использование Realm вашей инфраструктурой может не мешать использованию Realm вашим потребителем.

Автор: AustinZ Размещён: 08.11.2017 11:04
Вопросы из категории :
32x32