今日の役に立たない一言 - Today’s Trifle! -

古い記事ではさまざまなテーマを書いていますが、2007年以降はプログラミング関連の話がほとんどです。

クラス設計の失敗例 - クラスはシンプルにしよう!

昔作ったクラスをひさしぶりに使うことになった。
使ってみると、余計な機能がたくさんある。これってクラス設計に失敗してるよなぁ、と思う。余計な機能が無かったら、そのクラスを継承してちょっとだけ機能追加すれば済むのに、余計な機能があるがために、それに関連するメソッドをオーバーライドして不要な機能を無効化するという、かなり虚しいことをやった。
ひとつのクラスに責任を与えすぎている。初心者にありがちな失敗だなぁ、とつくづく感じる。
クラスってできる限りシンプルにした方がいい。シンプルなほどクラスの責務が自明になる。適切な名前を付けられる。
クラスの数が多少増えようが、そんなことは気にする必要はない。適切に命名しておけばそれらを区別する能力を人間は持っている。
クラス数が増えた結果、同じパッケージ内に複数のコンテキストが形成されたとしたら、リファクタリングして同じレベルのパッケージで分類するか、サブパッケージを構成すればよい。(そのような場合の大半はサブパッケージに分類するのが適切だろう)
クラスの責務を小さくするという目的で、安易に継承を行うのは良くない。継承は責務を追加しているのであって、責務を小さくしたことにはならない。
例えば、継承で失敗する例。機能A・B・Cがあったとして、基底クラスでAを実現したとする。基底クラスを継承して機能Bを追加したとする(A+B)。一方、基底クラスを継承して機能Cを追加したクラスも作ったとする(A+C)。ここでA+B+Cの機能を持つクラスを作るにはどうすればいいだろう?
クラスは一見 is-a 関係があるように感じるので、つい継承してしまいがちだ。でも本当は、機能A・B・Cが独立していることに気がつかないといけない。
つまり基底クラスは何も機能を持たず、委譲により機能を独立に追加できる仕組みを持たせておくべきだろう。
でも、こういうことって、きっとそれなりの経験を積まないと分からないのよね。。。