- 概要
- 感想
- コンストラクタじゃなくてstaticファクトリーメソッドを使え
- 大量のコンストラクタパラメータに直面したらビルダーパターンを使え
- インスタンス化不可のクラスを作る方法
- 定数を作るなかでなんべんも同じオブジェクトを作ってるならムダだからやめること
- ファイナライザを避けること
- equalsメソッドをオーバーライドするときは気をつけて
- equalsメソッドをオーバーライドするときはhashCodeメソッドもしないとダメ
- すべてのサブクラスはtoStringメソッドをオーバーライドせよ
- うまく設計されたモジュールは、実装の詳細とAPIをハッキリ区別している
- publicのクラスではpublicフィールドじゃなくてアクセッサメソッドを使う
- クラスの可変性を最小限にせよ
- 継承よりコンポジションを選ぶこと
- インタフェースは型を定義するのに使う
- タグ付クラスを使うな
- ジェネリックまわり
- int定数ではなくenumを使うこと
概要
プログラミング言語Javaの技術書。しかも入門編じゃなくて少々上級みたい。知り合いがもってたんで借りて読んだ。Javaとか知らんけれど、まあpythonの知識の応用で読めるんじゃない? って思って。それに読書は雑食に行いたいからね。
「言語」を扱うのに必要なのは、文法、語彙、慣習だ。それはプログラミング言語も同じである。一等高度なのがみっつめの慣習だ。これはよく理解できる。英語も、文法や語彙は簡単にわかるけれど慣習は身につけるのが難しい。プログラミング言語も、基礎的な文法はもうわかってるけれど、所詮ひとりで遊んでるものだから慣習とか書き方の流儀って点では俺のスクリプトはもうきっとめちゃくちゃなのだろう。そしてこの本はまさにその慣習を扱っているようだ。なるほどこれは上級だ。この本ではその慣習を、78項目に整理して書いてある。なんとなーくわかったものについてだけサマリと感想を書く。
感想
コンストラクタじゃなくてstaticファクトリーメソッドを使え
ファクトリーメソッドってのは新しいインスタンスを作って返すメソッドのことみたい。
@staticmethod
def foo():
return Klass('f', 'fo', 'foo')
@staticmethod
def bar():
return Klass('b', 'ba', 'bar', 'barr')
つまりこういうことかな? インスタンスを新しく作るときの面倒くさい初期値設定とかを省略できるようにするみたいな。作成するインスタンスごとにそれを作るファクトリーメソッドに名前をつけられるのがわかりやすくていい。
大量のコンストラクタパラメータに直面したらビルダーパターンを使え
Javaではメソッドのオーバーロードってものがある。pythonでは同じ名前のメソッドって作れないけど、Javaでは引数さえ違えば同じ名前のメソッドをいくつも作れて、それをメソッドのオーバーロードっていうようだ。
で。そのオーバーロードを利用して、コンストラクタを複数用意することができる。でもあんまりにもコンストラクタが多いときはビルダーパターンを使う。確かにこれはすげーなって思ったけど、これpythonでは名前付きオプションパラメータと引数デフォルト値があるからまったく必要なさそう。でも自分自身を return するメソッドっていうのはなるほどと思った。
インスタンス化不可のクラスを作る方法
アクセッサが private のコンストラクタを作り、中に throw new AssertionError();
を書く。
定数を作るなかでなんべんも同じオブジェクトを作ってるならムダだからやめること
そういうときは定数の中身を static {}
の中で埋める。
ファイナライザを避けること
try,finally のことだと思うんだけれど、なんでかよくわからん。なんか、ちゃんと実行される保証がないみたい。
equalsメソッドをオーバーライドするときは気をつけて
Javaのインスタンスにはたいていequalsメソッドがあって、それを使うことでインスタンス同士がイコールかどうかわかるらしい( instance.equals(instance2)
)。クラスを継承するときはつねにこのルールが守られるようにしようねってことみたい。
equalsメソッドをオーバーライドするときはhashCodeメソッドもしないとダメ
ハッシュなるもの(よくわからん)が同一性の確認に1枚噛んでるってことはギリわかった(ギリ)。
すべてのサブクラスはtoStringメソッドをオーバーライドせよ
あー! これはアレでしょpythonでいうところ __repr__
のことでしょう。わかるぜ。
うまく設計されたモジュールは、実装の詳細とAPIをハッキリ区別している
API部分はアクセッサを public にして、その他は全部 private とか protected にせよってことみたい。
publicのクラスではpublicフィールドじゃなくてアクセッサメソッドを使う
public float x
じゃなくて public float getX()
にしとけってことのようだけどよくわからん。まあともかくクラスの中の大事なところはしっかりと隠蔽すべきってことはわかったと思う。
クラスの可変性を最小限にせよ
オブジェクトの状態を変更するメソッドを提供しない、拡張不可にする、全フィールドを final にする、全フィールドを private にする、など。
継承よりコンポジションを選ぶこと
まったくピンとこない。こういうのはピンと来ないときに読んでもダメ。
インタフェースは型を定義するのに使う
間違っても定数の詰め合わせを書くな。それをやりたいなら定数ユーティリティクラスを作り、上述のprivateコンストラクタでインスタンス化を防ぐこと。pythonにインタフェースも型定義もないため、俺が興味をもつべきなのか微妙。
タグ付クラスを使うな
パラメータの値によって、そのインスタンスの役割がまったく変わっちゃうようなもののことをいうようだ。そういうときは継承を使って、別物のクラスにしなさいってこと。わかるぜ、初心者のころよくやっちゃう奴だよね。俺は最近脱却できてるけれど、クラスとかがよくわかってないと、ついつい継承とか使うのを面倒がって、全部ひとつのクラスに収めようとしちゃうんだよね。
ジェネリックまわり
まったくわからんジェネリックてなんぞ。
int定数ではなくenumを使うこと
APPLE = 0
ORANGE = 1
みたいなのは int enum パターンといって、クソ実装らしい。クソw これ俺よくやるわ! そういうのは enum FRUIT { APPLE, ORANGE }
って書くべき。このenumってやつ、便利そう。pythonにもあんのかなあ?
●
わからんところは躊躇なくスキップしてるので、ザクザク進んでる。300ページ級の大判本だから、この調子でサクザクいこう。