新卒一年目のエンジニアが「現場で役立つシステム設計の原則 〜変更を楽で安全にするオブジェクト指向の実践技法」を読んだ感想を書きます。

この本の趣旨をザックリまとめると、「オブジェクト指向」「ドメイン駆動(domain-driven)」という言葉(得意前者は)よく聞くし、定義としては普通に知ってるけど、

じゃどうすれば“オブジェクト指向らしく”コードを書けるか?ドメインドリブンな開発ができるか?そして、そもそもなんでそうしなきゃいけないのか?をJava(Spring)でMVCのwebアプリケーションを書くことを例に説明することです。

Java(+Spring)のコードが例として挙がっていますが、サンプルコードはそんなにないので、別にPythonでもRubyでもwebアプリケーションを開発する人なら読んで損はないと思います。

 

自分の話をすると、

最初にちゃんと覚えた言語はPythonで、就職したらいきなりJavaをやらされて、配属されたらまたPythonで、最初からオブジェクト指向の言語をやっていたけど、オブジェクト指向の言語でコードを書けばオブジェクト指向の開発ができるわけじゃないよなぁって思うわけです。

そもそも、オブジェクト指向じゃない言語とかじゃないものに触れたことがなくて、とにかくクラスを書いて、インスタンスを作るのはわかるけど何がオブジェクト指向的で、何がオブジェクト指向的でないかわからないという状態です。

これは、spring(javaのwebアプリ向けのフレームワーク)を勉強しているときもずっと感じてて、サンプルのコードを真似したり、周りの人間のコードに合わせてspringを使えばなんとなくwebアプリケーションはできますが、こう書けばオブジェクト指向の恩恵が受けられるみたいなことは一向にわからずじまいです。

 

この本の話に戻ると、

「Pythonとか、Javaみたいな言語でwebアプリを作っているときにオブジェクト指向の恩恵(プログラムが部品化で来てて保守しやすい)を受けるには、MVCの三層モデルに加えてドメインモデルの考え方が必要だよね

それなら、ドメインモデルを適応した、オブジェクト(クラス)のベストな書き方を見てみよう!」

的な流れで最終的にドメイン駆動開発の導入部分も理解できちゃう本でした。

 

 

ややこしいロジックはドメインオブジェクトに閉じ込める

 

ドメインオブジェクトはサービスにおける何らかの実体(ヒト・モノ・コト)を表しているそうです。例えばECサイトを構築しているとしたら、まずは商品がドメインオブジェクトになりえますし、とは買い物カゴとか割引クーポンとかポイントとかもドメインオブジェクトになりますよね・・・。

結局、どこからどこまでをどう切り分けるかはドメイン(領域)をどう設定するかによって変わりそうです。ここのところは練習が必要だなといった感じ。

で、ロジックは関わりが深いクラスに収めていくとオブジェクト指向らしいコードが書けるみたいです。

例えば、割引後の売値を計算するロジックは割引クーポンに計算させるのがよいそう。普通に考えたらクーポンを表すオブジェクトには割引率だけを持たせて、getで値を返させてアプリケーション層で直に計算させそうですが・・・。

こうすることで、何か複雑な割引処理が必要になったとき、割引クーポンのドメインクラスだけ変更を加えればプログラム全体の修正が完了できるそうです。

ドメインオブジェクトにはこのほかにも、シニア・子供といった区分などもあるそうです。後で区分を変えたくなってもこの区分オブジェクトだけいじればよいということでしょうか。

 

ドメインモデルとmvc三層モデル

 

そもそも、JavaのMVCモデルはC言語(手続き型)から来た概念で、書く層でやり取りされるデータクラスはオブジェクト指向的ではないという歴史があるので、ドメインモデルを意識した開発を行わなきゃいけなくなったといういきさつがあるそうです。

こういう流れを知ると理解が深まりますね。

ここら辺のことは、筆者がこの本を書く前にまとめられたスライドにわかりやすく書いてありますので、本書を読むか悩まれている方はまずはそっちのスライドを読んでみてはどうでしょうか。

 

if文は敵(あとfor文も敵)

 

複雑な分岐の入れ子はなるべくさせる。分岐したらそのままreturnしてメソッドを終わらせる(早期リターン・ガード節)。

for文も保守性を下げる原因。

これらはなるべく、ドメインオブジェクトのクラスにシンプルに実装していく。

for文、if文を書きすぎて大変なことになるというのは思い当たる節がありますね。少しだけの変更だからと言って、フロント側のjavascriptに分岐を書き足していたら、再異臭的に3重4重にサイト側で分岐が重なって大変なことになりました(研修だったのでそのまま放置)。

ただ、じゃぁどうすればそういうことを防げるかって話になりますが、具体的な対策は教えてもらえないんですよね。

そんな時は、余計なところにできてしまったif文for文をドメインクラスをリファクタリングすることで整理できるようです。ここも実践してみないとなって感じですね。

 

本の中にはもっと具体的なオブジェクト指向的なプログラムを書くための施策がいくつも載っています。

それに対応した現場でありがちよくないコードをアンチパターンとして示されている感じです。

心当たりがあることも多かったのですが、「そんなこともあるのか・・・」といまいちイメージがつかない箇所もたくさんありました。

例えば、あるリクエストに対して大量のデータを返してくるAPIを”One Size Fit All”なAPIというそうです。

自分もドキュメントが英語しなくて仕様がよくわからないAPIから項目が500を超える膨大なjsonが返ってきてびっくりしたことがありました。知りたい情報はその中のたった一項目、別に全部必要なわけじゃないし、中身を見てみるとかぶっている項目たくさんあるように見える。

こうしておくと一つのAPIで様々な要望に応えられるので作る側は便利ですが、使う側はわけわからなくなります。

だったら、用途別に窓口を分けたほうが使い勝手がいいそうです。

ただ、経験の浅い自分のような人間だと一つにどんどんまとめてしまうのはやってしまいそうことだと思います。

同じように、画面も項目を集めて多機能な画面を作り上げがちですが(これは研修時にやってた)、保守性を下げる原因になるそうです。

本書では関心事ということ言葉を使って、関心事ごとにインターフェースとドメインクラスを分けていって対応させることで、画面とドメインオブジェクトを適切な粒度で分けるということをやっています。

ただ、実務経験が乏しい僕にはこの関心事って概念はイメージがつきずらいですね・・・。

サービスのユーザーがどうやってこのシステムを使うのかちゃんと理解しないと適切な粒度で関心事を切り出せないようです。てことはドメイン(領域)も決められないということになるので、まずは何をプログラムに起こすのかちゃんと理解することから始まるの出ないでしょうか。

そこら辺を考えると、もちろんドメイン駆動開発(DDD)の入門書として読むのもいいんですけど、真にこの本の恩恵を受けられるのはある程度開発の経験を積んでいて、これまでの開発の流れを刷新していきたいと考えている人なんじゃないでしょうか。

まぁ、明らかに著者の方がそこら辺をターゲットにされているし、著者の方が代表を務めてる会社も新人研修というよりは、Java+Springの開発をしていてある程度煮詰まってしまったチームに向けたコンサルティングをメインにやられている用なので、この本が進化を発揮するのはある程度のコーディングに関する技術的な知識(言語とかフレームワークとか)があって、UML、具体的な開発手法(DDDとかRDRAとか?)の基礎的な知識があるけど実践できないって人が読む本かなとおもいました。

もちろん、自分みたいにオブジェクト指向ってて人が読んでもいいと思うんですけどね。


それでは。