最近良い設計について考えているので,そのメモです.
分けて考えるべきこと
- どれを処理するのかという知識と,実際にそれを選別する処理
- e.g. どのイベントをハンドルするかと,ハンドルするイベントをフィルタする処理
- ハンドラ自体がイベントをフィルタする必要はない
- 車が燃料一覧からガソリンや軽油を選択するのはまちがっている.それはスタンド店員の責務であって,車はガソリンを受理することだけ知っていればよい.
- e.g. どのイベントをハンドルするかと,ハンドルするイベントをフィルタする処理
- 同じ場所で行っている似たような処理
- 実は共通部分として切り出せることがある
- e.g. イベントハンドラで,通常のハンドリングのそばに特殊なイベントを処理する場合を書いているが,実は特殊なイベントの処理はどのハンドラでも共通なので呼び出す側で処理できた
- is-a関係になっていると継承できるが,子クラスが大きくなりすぎてはいけない気がする,子になんでも書いていいというわけではない
- is-a関係にあり,特殊だから継承するのであって,特殊な側が大きくなりすぎているのは健全な状態ではないはず
- あくまで継承される側が大きい必要があると思う
- 実際に行われる処理のありようと,それをどう設計に反映するのかということ
- 例えば,運転免許更新ソフトウェアを書くとして,運転免許センターモジュールに受け付けモジュールと写真撮影モジュールなどを作っていくと破滅するはず
- 問題解決のための固有の概念だけ残していくべき
- 継承できるかということと,実際に継承するべきかということ
- 固有なものだけを残すべき
- 相反する考え方: 継承して,共通するものだけくくりだす
- どっちにも置けるものはいろいろある
- 固有なものがないのであれば,そのクラスは不要なはず
- 固有でなければ親クラスが吸収するべき
自分が書きがちなコード
- ひとまず目についた要素をなんでもクラスにする(運転免許センターモジュールパターン*1 )
- 現実を反映しているが,問題領域は反映していないので,問題を解くことができないソフトウェアになる
- ひとまず紙に四角を書いて矢印を書き始めてしまう
- 概念の抽出は誰にでもできるように見えるが難しい
- 継承を多用する
- 雑な継承になる
- 問題領域は反映していないので(ry
- クソデカ子クラス,ヨワヨワ親クラスになる
- 意外にもクラスにする必要がなくて素朴な設定値を用意してそれを舐めれば終わり,みたいなことがある
- よく考えず呼び出し先に丸投げする
- 呼び出し元から知識が抜けていく
- 呼び出し先が事情を配慮しなければならないようなコードを書いてはいけない(暗黙の結合が増える)
- 関心事が分かれていればこういうことになりにくいはず
*1:勝手に命名