寄付窓口はこちら

データレイヤを分離する (LT) | try! Swift Tokyo 2017 #tryswiftconf Day1-9 聞き起こし

twitter.com

真の階層化アーキテクチャ(MVVM, Viper, etc)において、データ層は全てのデータを必要とする他の層よりも下層部に置くべきです。残念ながら、CoreData や Realmなどのような同類の技術において、このレイヤーの実際の実装の詳細(スレッドやコンテクスト)は他のレイヤーやViewのロジックに浸潤する傾向があります。これは、アーキテクチャのスケール化を難しくします。そんな場合は旧来のSwiftオブジェクト(POSOs)を利用すればよいかと。失うものと克服できるものをセットで理解すれば、これを解決する事が可能となります。パフォーマンスを維持しながらPOSOに移行する方法について説明します。

データレイヤを分離する

f:id:niwatako:20170302152753j:plain

これはスイスチーズ。

f:id:niwatako:20170302152754j:plain

スイスに行ってスイスチーズを頼みましたが

全部スイスチーズですね

f:id:niwatako:20170302152801j:plain

f:id:niwatako:20170302152814j:plain

コードにおける誤解をどのように避けるか

f:id:niwatako:20170302152829j:plain

層をきちんと責務別に分ければどのアーキテクチャでもいいと思います。

f:id:niwatako:20170302152844j:plain

私はMVA、必要最小限アーキテクチャに関心があります。

f:id:niwatako:20170302152906j:plain

データ層を切り離す責務が有ります。

f:id:niwatako:20170302152918j:plain

CoreDataやRealmのエラーがUIに出てきたことはないですか?

f:id:niwatako:20170302152934j:plain

データ荘の詳細が漏れているという警告を無視しているのでしょうか

どのスレッドで作られたか、保存すべきか、コンテキストはあるのか、トランザクションや削除のルールは?APIで弾かれているのか?

ORMテクノロジを使うなということではないです。

Objectが何で、モデル窓外でどう使うべきかの混乱は起きないべきです。

f:id:niwatako:20170302153025j:plain

f:id:niwatako:20170302153039j:plain

境界線を超えるデータは、BasicStructを使うべきである。単純なデータ構造が境界を超えるということが重要です。

f:id:niwatako:20170302153109j:plain

ピエロじゃないですよ

f:id:niwatako:20170302153115j:plain

f:id:niwatako:20170302153125j:plain

全てのモデルレイヤオブジェクトがここにあります。シンプルでクリア。

モデルオブジェクトから変換します

f:id:niwatako:20170302153207j:plain

CoreDataからの変換例

f:id:niwatako:20170302153208j:plain

その逆

f:id:niwatako:20170302153226j:plain

f:id:niwatako:20170302153235j:plain

モデルの複雑性が上位層に暴露しなくなります。

デベロッパはとくいなUIやデータそうに集中できます。

f:id:niwatako:20170302153311j:plain

でもモデルの流れをきちんと把握する必要があるし、POSOの相互変換を考える必要がある。

スレッドのバグを追い回すほうが時間がかかると思います。

f:id:niwatako:20170302153345j:plain

データ層のディテールと複雑性を切り離せられる

f:id:niwatako:20170302153402j:plain

DTOではなくてディーツと言わなけれないけないという話でした。

f:id:niwatako:20170302153410j:plain

Q&A

スイスチーズの例があって、名前と何を指すかが一致しない例がありました。そのために役割と名前を明確に分けると、責務が明確になって、チーム開発でわかりやすくなる。 責務を分ける時、そのために新しいオブジェクトやクラスを作ることが過剰になるパターンもあります 過剰になるパターンと、イニシャライザで内包するパターン、どのように使い分けたら良いのか、線引をどこで行われているか

このプレゼンを用意しているときいろいろな例を作りました。基本的に私たちの会社は一人の人には2人両親が居てそれぞれの親に2人両親がいるという設計をしていく。人が指数関数的に広がる場合、非常にデータが早く増大する。では何処で線を引くか。私とメアリーさんが結婚して、私のイベントは他の人につながる。オブジェクトのつながりは増大する。POSO、DTOになると、これが何処まで広がるかを決めなくてはいけない。

通常のデータセットで提供しているもの、先祖や家族のデータを9行か10行ぐらいで示せばよい。

オブジェクトとしてはUIやそれより上位層で仕事をしているとその処理が知るべきスレッドの知るべき範囲があると思う。

自分たちのチームの中でデータを作って格納して、沢山の人がDBにアクセスしていて、CoreDataやRealmでやっているならこれで十分。

しかし多人数のチームで少数の人間だけがモデル層を把握しているなら役割をこのように分離してもいいと思います。

MVP, MVPM, VIPERを使っている時、100%MVPにするのか、それとも、もっと境界線をゆるくするのか、それはチームで判断すべきだと思います。