この記事はハワイアンAdvent Calendar 2020 5日目の記事です。4日目の続きなので、4日目も読むと伝わるのかなと思います。ところでですが、オブジェクトデザインは平成に置いていかれた本の中も1、2を争うレベルで影響を受けているし為になる技術書なんですが、電子書籍化もされてないどころかもう出版が止まっており本当に不遇です。同著者が書いた「進化的アーキテクチャ」にエッセンスレベルで僅かに受け継がれているんですが…オブジェクトデザインも電子書籍化されて欲しいんですが…どうかオージス総研様、ご検討の程、宜しくお願い致します。
Contractというと「契約による設計」を思い浮かべるのでしょうか。KotlinのContractを思い浮かべるのでしょうか。人によるんでしょうが、本記事ではオブジェクトデザインにおける「ロール」の集合を指す事にします。もう少し実装に落とし込むとinterfaceの集合というかひとまとまりになるので、そういう理解でも良いと思います。
Model-View-Controller から始まったフレームワークは POSA本やDOOS本でその責務について言及され、その後サーバサイドではMVC2だったり、クライアントサイドではMVPだったりMVVMだったりVIPERだったりFluxだったりReduxだったりMVIだったりと様々な派生パターンが生まれました。その中でも、MVPが出てきた頃にはContractというinterfaceのまとまりを設けようという流れがありました。当時は「ただのinterface programingだよね」というところでそこからあんまり話が発展しなかった(他に技術的な課題がたくさんあったので注目されていなかったんだと思う)のですが、今になってこのContractは再評価されつつあります。というのもMVP(Passive View)からVIPERの流れが自然であった事から、これまでMVCだのMVVMだのFluxだの今まで散々議論されてきましたが、進化的という前提でこれらのフレームワークを洞察した際、各ロールの集合であるContractにスケーラビリティをもたせてはじめてそれらのフレームワークが機能するし、逆にそれがなければそもそもフレームワークとして評価のしようがないので、良い設計でもなんでもなかった、ということが明らかになったのです。やりましたね。もう不毛な議論はやめましょう。
もう少し実装寄りの話を例にすると、ある特定のオブジェクトを用意する際、それ単体の責務を考える上で一貫性をもたせる事は簡単だと思いますが、複数オブジェクトのコラボレーションを考えた際、それぞれの責務の一貫性を保ち続けるというのは、指針だったり評価軸がなければ難しいと思います。Contractにおいても同様に、一貫性のある評価軸を元に漸進的に変更していく必要があります。
Passive ViewからVIPERの流れは、GUIアプリケーション開発においてもはや欠かせない要素となった画面遷移を明示的にする、という点でとても自然な流れでした。Paging処理というのも、画面上でページングが必要になったら、Contractとして現れるのは自然な事だと思います。これらはユースケースを軸にスケーラビリティを確保しています。FluxもReduxもデータフローに注目しているので、データフロー・データパイプラインな考え方を軸に責務を移譲してスケーラビリティを確保する、という方針になるのかなと思います。MVVMやMVIについてはどうでしょうか。考えてもらいたいので、あえて触れないでおきます。どういった評価軸を元にスケールさせればよいのか考えてみましょう。また、皆さんのプロジェクトでソフトウェアアーキテクチャドキュメントをメンテナンスしているのであれば、この評価軸は共有すべき(人によってぶれやすい内容)なので、意図している事をドキュメントに追加しましょう。
というわけで、「Contractにスケーラビリティを」という話でした。現代のソフトウェア開発は複数の次元で漸進的な変更を行いますから、設計パターンやソフトウェアアーキテクチャやフレームワークそのものが進化的であるかという評価軸で評価し直す必要性があると考えています。皆さんが日頃業務上で手癖のように使っている設計パターンだったりコーディングテクニックについて、「進化的」という評価軸から見つめ直すと、新たな発見があるかもしれません。例えば、過去に特定のフレームワークや設計パターンに対する傷を背負っているのであれば、どうすればその傷を回避できたのかを「進化的」という評価軸から振り返ってみましょう。