WEB DB PRESS vol52

ちょいと遅れて入手、まあ北海道だから仕方なし。
今号は良いコードを書く為のJavaの習慣とvimの記事がメインで、とりあえずJavaの方を読んだので感想とツッコミ。
結論から言えば、「新人さんに贈る」と表紙で煽ってますが「文法レベルの理解から先に進みたい人に贈る」という方が正しいかもしれないです。というのも、必ずしも新人が継承や委譲なんかを知っている必要もなく、知らないまま何年も過ぎる人もいるのが現状なので…。むしろ、新人じゃなくても読んで欲しい層はいっぱいいる記事だと思います。
というわけで、継承とかインターフェイスとかそのあたりがまだ理解出来ていない人は必読。

WEB+DB PRESS Vol.52

WEB+DB PRESS Vol.52

感想

約35ページといった記事ですが、内容としては文法レベルは理解している人、もしくはJavaの習慣を知ってみたい人にはちょうど良い分量と内容かと思います。個人的には第2章のイディオムの部分はもっと厚くやって欲しかった気もしますが、継承と委譲、インターフェイスといったJavaの特徴的な部分を上手くカバーしています。

習慣やイディオム

1章2章はJavaに限らず言語特有の習慣があればそれに従うべきで、Java特有の慣習としてはこんなのがある、といった内容です。また、どうしてそんな事をするかといえば、「読みやすいように」という事が強調されている事は好感が持てます。
2章では幾つかの慣習が紹介されています。ジェネリクスや列挙型といった新しい*1手法のなぜ?が書かれていますが、ちょっと物足らないのが残念です。もし、この章の内容をもっと深く勉強したいというならば、こちらがオススメです。

Java 5.0 Tiger (開発者ノートシリーズ)

Java 5.0 Tiger (開発者ノートシリーズ)

継承、委譲、インターフェイス

3章4章は基本であるところの継承やテンプレートメソッドのパターン、さらには委譲とリスナーのパターンなどが紹介されています。このあたりの知識がないと、設計に関する会話をしていても外国人と話しているような錯覚になる箇所です。逆にこのあたりを抑えておけば、例えばデザインパターン1つとっても理解しやすくなりますので、「継承って具体的にはどうやって使うの?」というスタート地点から、「継承より委譲」という部分までの道筋として有用な記事です。
尚、勉強をしながらこの記事を理解していく人は、必ずサンプルコードは入力して試す事をおすすめします。さらに幾つかのコードを書きながら理解を深めるといいと思います。
ただ、インターフェイスに関しては変更はしない方がいいとかその辺は余計だったかなーとも。確かに公開され長く使われるようなAPIならばそうなんですが、一般的な開発の現場で使われる場合はそこまでは気にしない方が多いのかな、とも。ぶっちゃけ、設計にあまり時間をとらせてもらえないので、作りながら変えていくのは結構あることだと思いました。

クラス設計

5章はクラス設計ということで、例外の話や不変オブジェクトの話などTipsといった感じです。3章4章とは話題も違い、どちらかといえば2章のようなイディオムの話です。
例外については1つの見解というのを忘れないと不毛な議論になりますが、こればかりは開発現場毎の習慣に合わせた方がいいですね。自分もバグやあり得ないようなケースでは非チェック例外、状況に応じてはありえる場合はチェック例外という方針は同意です。記事では、どこで補足すべきかという話が抜けてしまっていたのが残念ですが、そこまでやるとたぶん例外だけで特集になりそうな気がします。
ちなみに、例外に関して、自分が教える場合によく言うのは「例外ってのはメソッドの戻り値の一種だ」という事です。正常に値を返すことができなくて、異常を呼び出した側に伝えるという事で、「呼び出し側が意識した方がいいならばチェック例外、意識しなくても良いならば非チェック例外。呼び出し側もさらにそれを呼び出し元に伝えるべきかどうかを考慮して例外処理をするかどうかを決める」というスタンスです。
不変クラスに関してはいらなかったかも・・・。むしろ、クラスの粒度とテストに関してはもっと欲しかったですが、これも1つの特集レベルですね(苦笑

ツッコミ

幾つかツッコミ

P25 equals()とhasCode()のオーバーライド

前提として、equals()とhasCode()はオーバーライドしないでデフォルトの挙動のままにする、という選択肢があり、スーパークラスでオーバーライドしていない場合は、【オーバーライドすべきではない】と思います。
もし、スーパークラスで自分自信と同じクラスのインスタンスの比較に関するコードが含まれていた場合、予期せぬバグになる可能性がありますね。また、フィールドが増えた場合のequalsに関しては問題も多いので、スルーした方がいい話かもしれませんね。
逆にこういう所を起点にして、技術者同士で色々と話ができる事が望ましいことなんですが・・・、勉強会や休憩時間にこういう話を出すだけでおかしい人扱いされる会社がほとんどです

P34 インターフェイスの引数の型が TreeMap だと自由度が高い

TreeMapよりSortedMapの方が望ましいのは同意ですが、ConcurrentSkipListMapなんてまず使いませんwここは単純にArrayList でなくて Listのがいいよ、で良かったような気がします。

リスナ=委譲?

なんとなくそんな風に読めてしまいました、意図はしていないと思いますが。

P41のぬるぽ

NullPointerExceptionよりもIllegalArgumentExceptionというのは同意ですが、「同じ場所でNullPointerExceptionが発生します」は間違いですね。

s.foo(null); // 呼び出しがnull

こちらは確かにここでNullPointerExceptionが発生しますが、

s.foo(null); // 引数がnull

こちらは呼び出し先のメソッドで発生するので、StackTraceは変わりますね。なので、区別は付くでしょう。

おまけ

引数チェックのIllegalArgumentExceptionですが、以下のように書くと例外メッセージを考えなくて済むのでおすすめです。

public void hoge(String str) {
   if (str == null) throw new IllegalArgumentException("str == null");
   // 処理
}

ifの条件式をそのままコピペしてください。手軽で直接的で解りやすいメッセージになります。引数にちゃんと意味のある名前が付いていれば尚よし。

次回勉強会で・・・

せっかくちょうどいい記事だし、次回の札幌Java勉強会の読書会はEffective Javaではなくて、この記事を題材にしようかな?と考えてます。

*1:5年前たってるけど