真の階層化アーキテクチャ(MVVM, Viper, etc)において、データ層は全てのデータを必要とする他の層よりも下層部に置くべきです。残念ながら、CoreData や Realmなどのような同類の技術において、このレイヤーの実際の実装の詳細(スレッドやコンテクスト)は他のレイヤーやViewのロジックに浸潤する傾向があります。これは、アーキテクチャのスケール化を難しくします。そんな場合は旧来のSwiftオブジェクト(POSOs)を利用すればよいかと。失うものと克服できるものをセットで理解すれば、これを解決する事が可能となります。パフォーマンスを維持しながらPOSOに移行する方法について説明します。
データレイヤを分離する
これはスイスチーズ。
スイスに行ってスイスチーズを頼みましたが
全部スイスチーズですね
コードにおける誤解をどのように避けるか
層をきちんと責務別に分ければどのアーキテクチャでもいいと思います。
データ層を切り離す責務が有ります。
CoreDataやRealmのエラーがUIに出てきたことはないですか?
データ荘の詳細が漏れているという警告を無視しているのでしょうか
どのスレッドで作られたか、保存すべきか、コンテキストはあるのか、トランザクションや削除のルールは?APIで弾かれているのか?
ORMテクノロジを使うなということではないです。
Objectが何で、モデル窓外でどう使うべきかの混乱は起きないべきです。
境界線を超えるデータは、BasicStructを使うべきである。単純なデータ構造が境界を超えるということが重要です。
ピエロじゃないですよ
全てのモデルレイヤオブジェクトがここにあります。シンプルでクリア。
モデルオブジェクトから変換します
CoreDataからの変換例
その逆
モデルの複雑性が上位層に暴露しなくなります。
デベロッパはとくいなUIやデータそうに集中できます。
でもモデルの流れをきちんと把握する必要があるし、POSOの相互変換を考える必要がある。
スレッドのバグを追い回すほうが時間がかかると思います。
データ層のディテールと複雑性を切り離せられる
DTOではなくてディーツと言わなけれないけないという話でした。
Q&A
スイスチーズの例があって、名前と何を指すかが一致しない例がありました。そのために役割と名前を明確に分けると、責務が明確になって、チーム開発でわかりやすくなる。 責務を分ける時、そのために新しいオブジェクトやクラスを作ることが過剰になるパターンもあります 過剰になるパターンと、イニシャライザで内包するパターン、どのように使い分けたら良いのか、線引をどこで行われているか
このプレゼンを用意しているときいろいろな例を作りました。基本的に私たちの会社は一人の人には2人両親が居てそれぞれの親に2人両親がいるという設計をしていく。人が指数関数的に広がる場合、非常にデータが早く増大する。では何処で線を引くか。私とメアリーさんが結婚して、私のイベントは他の人につながる。オブジェクトのつながりは増大する。POSO、DTOになると、これが何処まで広がるかを決めなくてはいけない。
通常のデータセットで提供しているもの、先祖や家族のデータを9行か10行ぐらいで示せばよい。
オブジェクトとしてはUIやそれより上位層で仕事をしているとその処理が知るべきスレッドの知るべき範囲があると思う。
自分たちのチームの中でデータを作って格納して、沢山の人がDBにアクセスしていて、CoreDataやRealmでやっているならこれで十分。
しかし多人数のチームで少数の人間だけがモデル層を把握しているなら役割をこのように分離してもいいと思います。
MVP, MVPM, VIPERを使っている時、100%MVPにするのか、それとも、もっと境界線をゆるくするのか、それはチームで判断すべきだと思います。