プログラミングには「結合度」「凝集度」というものがあり、「各プログラミング要素は、他のプログラミング要素とより疎結合である事」「各プログラミング要素は、より少ない機能を持つ事」が善しとされている。つまり、「低結合」であり「高凝集」であればよい。プログラミング要素とは、例えば変数や関数やクラスの事だ。
※ 個人的には、凝集度の「高い低い」の意味が逆な気がする。凝集という言葉の意味が自分の中で確立していないのか?
低結合プログラミング、高凝集プログラミングを成す為には、「結合度が高い」「凝集度が低い」とされるものが何かを知る事が大事だ。結合度と凝集度にどのようなレベルがあるのかは、Wikipedia でも参照していただくとして、ここではオブジェクト指向における「継承」について考察する。
よく耳にするのが「A クラスと B クラスは共通処理があるからスーパークラスを作って、そこに共通処理を書く。A と B はそれを継承すればよい」という類のものだ。一見、オブジェクト指向の利点を上手く使ったとても良い作法に思える。
しかし、「継承」は高結合である。継承してしまったら、現実世界と同じく、親と子は全く切り離せない状態になる。継承の結合度は殆どトップレベルだ。
さて、先の例をもう一度使う。ここで C クラスが現れた。C も、A と B が使っていた共通処理を使うので、先ほどのスーパークラスを継承する。更に、B と C は他の共通処理も共有するのでスーパークラスにそれを加えた。当然、A の凝集度は著しく下がってしまった。B と C しか使わないであろう処理を A が保有してしまったからだ。
破滅のスメルがぷんぷんしてきた。更にクラスが増えたらどうなるのか。凝集度が低いから切り離したいが、継承しているために結合度が高いから切り離せない…。
「共通化 → 継承」という考えは間違っている、と断言する。こんなものはオブジェクト指向でも何でもない。仮想関数を持たないスーパークラスは要注意だ。