MVCの話もっとしてほしい

昨日バイト先で男子しか参加しない女子会して、開発の仕方どうするかみたいな話合いしたの面白かった。

押し付け合い回避のためにもレイヤ

趣味や価値観をリアルタイムで押し付け合うのはギスギスして良くないが、話し合うべきときを設けてやはり定期的に話し合うべきだと思った。コード内のインターフェースが少ないと、そういう押し付け合いが起こる可能性が多く出てきたり、それを避けるために心理的に間違った方向に実装しそうで良くない。データAPIが薄くてコントローラに書くことが増えると、コントローラ内で押し付け合いやすいみたいなそういう。レイヤ分けて「はい俺バリア〜ここからさき俺の実装〜〜」みたいなのが良さそう。

MVC界隈の知識源

MVC関係の話、まとまった情報源が無くて、Togetterかブログエントリあたりで適当にまとめられていることが多い。PoEAA(Patterns of Enterprise Application)が良いという噂を聞いたことあるけど、同時に邦訳が酷いという話も聞く。まとまった情報源が無くてみんな困ってそう。MVCの話、大体の人がRailsやPHPのDisをしつつMの話をするという感じで、最悪の例に対してしかあまり語られてない気がする。考え方の良し悪しは別に気にしないから、MVCの話もっとしてほしい。世の中にMVCの専門家みたいなひと実はいなさそう。

DataMapper

最近触ってるMVCのプロダクトだと、Model(用に作られたクラス)がDBアクセスを一切しないという形になっていて、テストがしやすいしコードが分かりやすくてすごく良い。なぜコードが分かりやすいのだろうと思ったけど、ごく単純なことしかしてないからだと思う。しかしControllerのコードが膨れ上がって見通しが悪いので、どうにかしたい感も高い。

今まで触ってたORMは全部ActiveRecordパターンのModelだったけど、それだとDBと依存しすぎてテストとか超書きづらそうだし実装も厚くなりそう。純粋なオブジェクトを提供するクラス + includeするだけでDBへのアクセスが可能になる、みたいなものがあれば便利である可能性が高いなとか考えてたけど、結局ActiveRecordと同じことになりそうな不安もある。探していたらDataMapperパターンというのがHitしたので多分こういうのだと思う。上図だと、純粋なオブジェクトを提供するクラスがStoreで、includeするだけでDBへのアクセスが可能になるクラスがStoreMapper。

DBとの接続部分はMapperに追いやって、DBから取得したデータ自体はDBとは無関係のModelに紐付ける、という感じが良さそう。でもModelが別のModelを操作する処理とかを実装するには、結局ModelがMapperのメソッドを叩くしかなくなってModelとDBとの依存性高まりそうだと思ったけど、Mapperが提供すべきPublicメソッドという規約(=JavaのInterfaceみたいなの)があれば、Mapperを違うデータソースに差し替えても動く。でも全体的によく分からないモヤモヤした感じがある。何をしたいのかすらあんまりわかってない。モデルとDB接続が密結合でテストしにくいのを解消したいのか、Controllerのコードが膨れ上がっていて見通しが悪いのを解決したいのか、読むコードを減らしたいのか、どれの優先度を高めればいいのだろう。全部解決しようとして混線している気がする。でも全部解決したい。

DataMapperを採用する利点として、次のような内容を考えた。

  • データソースをDBからKVSに変えるなどの切り替えが容易
  • データソース操作のロジック変更が容易(論理削除実装とか)
  • テスト用Mapperを用意すればテスト中に何度もMockを生成する必要がない
  • DB操作 / モデルの行うべき処理(ロジック) の定義場所やテストが区別される
  • テスト用Mapperに切り替えるなどしてモデルのロジックのテストがDBと独立できる

もう少しDataMapper界隈の良い実装について調べたい。