2017-11-08 7 views
0

これは、Cocoa Touch Framework内で驚異的なRealmデータベースを使用する際のコードパターン/デザインに関する質問です。具体的には、ココアポッドとして配布されるフレームワーク。Cocoa Touch FrameworkでRealmを使用するときのパターン

は私が今

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 
    } 
} 

これは、このユースケースに適したデザインパターンですか?

第2に、次の問題はオブジェクトを更新することです。すべての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 /コアデータロジックをラップします。私はこのパターンを一般的に改善する提案もしたいと思います。

答えて

1

幸いにも、私はあなたの質問に対する正直で迅速な答えはないと思います。それは本当にあなたがやろうとしていることにかかっています。

まず、デフォルトのレルムまたはデフォルトのレルム設定を改ざんしないことをお勧めします。これは、レルムを直接使用するアプリケーションも同様に操作できる可能性が高いからです。また、モデルタイプのネームスペースを確認し、それらをデフォルトスキーマから除外したい場合もあります。同様に、内部で定義したモデルのスキーマのみを使用して、フレームワークのレルムを開くこともできます。

APIについては、Realmをどのように使用するかによって決まりますあなたのフレームワークのコンテキストで。

Realmが実装の詳細である場合、ユーザーが上記のAPIのようなRealmベースのオブジェクトと対話する方法を制御するのが理にかなっています。そうすれば、ユーザーがモデルオブジェクトでできることを正確に制御し、その状態が無効になるように変更することができないようにすることができます(それが懸念される場合)。

たとえば、独自の前提条件と要件を指定するAPIを使用して、ユーザーのRealmオブジェクトにオブザーバブロックの登録と登録解除を処理することができます。これは、オブジェクトを監視する期間が、フレームワークの一部である他のオブジェクトやシステムと一致するか、または制御される必要がある場合に役立ちます。通知トークンの保存方法を教えず、その背後にあるすべての詳細を処理し、ユーザーがフレームワークのコンテキスト内でRealmを誤用しないようにすることができます。

Realmのタイプをいくつかのプロトコルに適合させ、APIがそのプロトコルタイプを消費して販売することによって、Realmを極端に使用してユーザーに見えないようにすることさえできます。あなたのオブジェクトがレルムオブジェクトであることをユーザーが知らせることはできませんし、レルムにそれらを貼り付けたりコピーしたりするように誘惑されません。

しかし、あなたのAPIでRealmオブジェクトを提供し、おそらくそれらをRealmの独自の使用と一緒に使用することもできます(たとえば、それらを独自のRealmに置くなど)、Realmオブジェクトとしてそれらを明示的に展開するのは理にかなっています。利便性の理由から厳密に記述したものです。この場合、フレームワークがRealmをどのように使用して、消費者のRealmの使用を妨げないようにするかについて考える必要があります。

+1

Thanks AustinZ。私の例では、デフォルトのレルムを使用しています。実際に私のフレームワークでは、私は 'MyFrameworkName.realm'として保存されている別のレルムを使用します。レルムを完全にラッピングするアドバイスをありがとう。私の独自のプロトコルの背後にあるRealmのすばらしい機能をすべて網羅することはたくさんの仕事のようです。私は、私のフレームワークのユーザーにレルムの最高の部分を使用させ、より迷惑な部分をより簡単にすることができます。検証していただきありがとうございます。 –

関連する問題