torutkのブログ

ソフトウェア・エンジニアのブログ

Java読書会BOF主催「現場で役立つシステム設計」を読む会(第1回)の感想 #javareading

Java読書会BOF主催「現場で役立つシステム設計」を読む会が今月から始まります #javareading - torutkのブログで案内したJava読書会「現場で役立つシステム設計」を読む会(第1回)が8月18日(土)に実施されました。
初回は、「はじめに」から、「CHAPTER 4 ドメインモデルの考え方で設計する」の導入部分(p.102上4行目)まで90ページ弱を読み進めました。

http://www.javareading.com/bof/

議事録は近日Java読書会BOFのWebサイトにアップされるとので、自分の感想をずらずらと記載していきます。

書籍の題名について

書籍の題名「現場で役立つシステム設計の原則」は、最初に題名だけ見たときに「システム設計」とあることから、ソフトウェア設計の前段にあるシステム設計(業務の設計、計算機・ネットワーク等のインフラとソフトウェアの配分)を意図したものと誤解していました。
しかしJava読書会BOFの課題図書投票で推薦本に挙がり、内容を見てみたところソフトウェア設計、しかもオブジェクト指向設計な内容だったので、これはと思いました。(昨年投票時は次点でしたが、今回は1位となって読書会をする運びとなりました)

CHAPTER 1 小さくまとめてわかりやすくする

ここはプログラマーとして苦労する問題を共有(共感)し、ドメインモデルへの導入とするためでしょうか、プログラマーに寄り添った内容となっている、いい導入だなと感じました。

変数名

今まで関与したコーディング規約には、命名は原則フルスペルで、略語を使う場合は略語集(用語集)に登録した上で使うとしてきたので、素直に賛同です。

IDEやプログラミング用のエディタであれば、名前の補完があるので長い変数名でも最初の数文字を入れればあとは補完してくれるので入力の手間もそれほどはないと思います。

いまでも変数名等の名前を省略するコードがあるのか参加者に聞いてみましたが、昔の(10年以上前とか)コードで見かけるが、今書かれているものは省略するものは少ないようでした。
一方で、真面目に業務(問題領域)の用語を英語にすると30文字以上になることもあるといった長すぎる名前をどうするか課題もあるとのことでした。

業務の用語については、対応する英語名を一意に決めないとプログラマーによって異なる英語(類語)が使われるので、プロジェクトで用語集(日英対応まで含めて)を定めるのが重要です。ただしプログラミングが始まってから後追いで用語集を策定しても手戻りが増えて大変(反発も大きい)です。

空白行

長いメソッドは段落(意味的に一続きのコード)ごとに空行を入れて読みやすくするという手法は自分でも実践しているので素直にうなずけます。

ただ、この書籍のサンプルコードは、if文の条件式を囲う丸括弧の内側に空白文字があるところ、ifのキーワードと条件式の丸括弧開きの間に空白がないといったところで慣習的なスタイルと違いがあってそっちが気になってしまいました…。

説明用の変数とメソッドとしての独立

Java読書会でも以前読んだ「リファクタリング」の内容でもあり、違和感なくうなずけます。

値の範囲を制限してプログラムを分かりやすく安全にする

制御系のアプリケーションでは、範囲を定義して範囲外の値を代入できないようにすることが必要でした。必要性はとってもうなずけます。

QuantityやUnitといえば、JavaAPIとしてJSR 363が作られています。JSR 363の簡単な紹介を次に書いています。2018年に入ってJSR 385がAPIのVer.2.0として了承されたようです。
JSR 363 Units of Measurement を調べてみて

範囲を扱うRangeクラスもいくつかのライブラリで使われています。
id:torutk:20110924

値オブジェクトは「不変」にする

この本では言及はありませんが、マルチスレッドプログラミングでスレッド間でオブジェクトを安全に受け渡しする際には「不変」が重要となります。

コレクション型を扱うロジックを専用クラスに閉じ込める

ファーストクラスコレクションというそうですが、これは意識したことがないので有用かどうかは試してみたいところです。

ジェネリックスがJavaに導入される前はコレクションに入れる型を保証するためにコレクションを内部に持ち外部からコレクションへ追加するメソッドで型を規定したことはありました。これの発展形なのかなぁと漠然と思いました。

CHAPTER 2 場合分けのロジックを整理する

判断や処理のロジックをメソッドに独立させる

if文の条件式が複雑になるときは、条件式をメソッド化して整理するのはよく使う手法なので、うなずけます。

else句をなくすと条件分岐が簡単になる

節題がドキッとする内容(elseをなくすとロジックの抜け漏れが発生するんでは?)ですが、読み進めてみるとガード節(早期リターン)の導入でした。これもよく使う手法です。

Javaの列挙型を使えばもっとかんたん

Javaenumいいです。ぜひ活用しましょう。

状態の遷移ルールをわかりやすく記述する

enum導入以前に状態遷移ロジック書いたきりなので、enumで状態遷移ロジックというのは実装したこと、実装しようと思ったことがなかったです。ちょっと目から鱗です。

サンプルコードで、EnumSetを使っていながら、EnumMap使わないでHashMapつかったのは何か意図があるのかなと議論になりました。

CHAPTER 3 業務ロジックを分かりやすく整理する

いろいろな見方があって議論が高まる章となりました。
Java読書会BOFのモットー(自称)は、「脳みそに汗をかこう」*1なので、読書会の本としては成功です。

共通機能ライブラリが失敗する理由

Utilクラス、Commonクラスアプローチではうまくいかないなということは身をもって痛感し、自分ならNGワードとしたい命名です。Commonといいつつ大抵は狭い範囲での共通に過ぎないものばかりでした。

一方で、「データクラスと機能クラスに分ける設計」としては、C++STLライブラリなどがあります。Java 8ではStream APIラムダ式とともに導入されています。

ちょっとしたニーズの違いについては、フラグやオプション引数で対応するのではなく、ラムダ式で違いの部分をコードで利用側から指定するなどの方法もあります。言語仕様、標準APIの進歩でこれまで難しかったことも状況が変わってきています。

このあとまだまだ興味深い内容がつづきますが、日記の方は続き、ということで。