スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

オブジェクト指向入門 第12回 長~い補足

前回は、オブジェクト指向言語に合わないクラス構成を、パワー型に着目して改善する例を書きました。

今回は、クラス構成、パワー型、言語の3つについて、補足したいと思います。


さて、ラモスの例では、生成後に国籍や職業を変えたいため、クラス構成を見直す必要がありました。しかし、それらを変える必要がなければ、次のような構成も考えられます。

ramos_ng.jpg

しかし、このように組み合わせの数だけクラスを作る構成はオススメしません。
拡張するのが、面倒だからです。

試しに、イギリス人と監督の2要素を追加してみます。

ramos_ng2.jpg

5クラスも追加されました。
次に、新たな要素として、性別(男性/女性)を加えてみます。

ramos_ng3.jpg

省略していますが、12クラスも追加しています。

組み合わせを使った構成では、追加したい要素数と追加するクラス数が一致しなくなります。そして、拡張すればするほど、1要素追加に必要なクラス数が増えていくのです。

前回のクラス構成なら、イギリス人と監督で1クラスずつと、性別/男性/女性の3クラス、先ほどの12クラスに対して5クラスで済みます。常に要件の数だけの追加、つまり一定量の追加で済むのです。

ramos5.jpg

ファウラーの著書リファクタリングの「継承の分割」の章で、もっと詳しく扱っています。
押さえておくと、非常に役立つと思います。


次は、パワー型についてです。
インスタンスが、オブジェクトではなくクラスという、風変わりな型ですが、意外と役立ちます。

パワー型を基本クラスにすると、継承関係を小さく最適化できるからです。
ラモスの例の様な大雑把な継承は、オブジェクトが何クラスに属するかを変えたくなる事態を招きがちです。
これを避けることができます。

また、インスタンスがクラスというのは、身近な考え方でもあります。
典型例は、会社の役職です。
役職のインスタンス(実例)をあげると、部長/課長/主任などがあります。
これらは、それぞれが人を権限などの特性ごとに分類するための集合、つまりクラスです。

なお、このようなクラスには抽象クラスが便利です。

以前のパックマンのプログラムでは、モンスタークラスを抽象クラスで実装しました。なぜなら、モンスターの実例も、赤モンスターや青モンスターなど、自身の派生クラスだからです。

インスタンスがクラスの場合、オブジェクトを生成しないので、抽象クラスがちょうど良いのです。


最後に、オブジェクト指向言語に合わない例を、もう一つ書いてみます。
派生クラスにも似たような事があります。

当たり前ですが、派生クラスが欲しい時は派生クラスのコードを書きます。

この書き足す行為自体も、どうしようもない事ですが、言語向きの派生クラスと、そうではない派生クラスを生み出してしまいます。


言語向きの派生クラスは、基本クラスに機能を付け足す派生クラスです。
自動車にパトライトとサイレンを付けてパトカーにする様に、基本クラスに機能を追加する派生クラスは、言語仕様に非常にマッチします。

逆に、基本クラスの機能を制限するような派生クラスは、慎重な設計を求められがちです。

例えば、箱クラスの派生クラスとして、硬貨しか入らない貯金箱クラスを作る等です。

その時、とりあえず箱クラスに何でも放り込める操作を作り、貯金箱クラスでそれをオーバーライドして、硬貨以外はエラーにする様にしたとしましょう。

この設計はシンプルですが、少々厄介な面があります。

引数で指定した箱オブジェクトに、色々なものを入れる処理を作ったとしましょう。

箱オブジェクトを指定していれば全く問題ありませんが、ポリモーフィズムを利用すると、引数で貯金箱オブジェクトを指定する事もできます。

そうすると、貯金箱に色々入れようとしてエラーしてしまうのです。


貯金箱クラスの設計者は、エラー処理を考慮していない事や、そもそも貯金箱に硬貨以外を入れようとする事自体を非難するかもしれません。
しかし、箱オブジェクトを使用する側からすると、派生クラスを基本クラスとして使えない事、つまりポリモーフィックでは無い事を問題視するでしょう。

いずれにせよ、エラーする時点で、設計が要件や仕様を満たしていないのは明らかです。それを適切に満たす設計になるように、お互いに歩みよる必要があります。

まず、要件や仕様を満たし、その後でポリモーフィックかどうかも確認すれば、トラブルにならないでしょう。


実際のプログラム開発でも、「この時だけ特別に、〇〇処理をしないで!」といった要望は多々あります。
しかし、派生クラスで機能を削ろうとするのは、ポリモーフィズムが破綻しやすいので、避けたほうが無難でしょう。

機能を削りたくなるというのは、基本クラスが大きくなりすぎている事が表面化したと言えます。

拡張性の確保や条件分岐の排除など、ポリモーフィズムの利点だけを継承するように、基本クラスをスリムにするのが良いと思います。


■まとめ
  ・継承は、小さく最適化する。


貯金箱の例のような状況は、曖昧な理由で統一感を求めると起きやすい気がします。
例えば、箱に物を入れる方法を何となく統一するなどです。

具体的なやり方を無理に統一するのは、ジャンケンでいつもグーを出すような危険性があります。
プログラム開発で無理にやり方を統一すると、その方法が有効な処理だけ良く動作し、それ以外はバグに悩まされるプログラムになりかねません。

ジャンケンは、相手の裏をかくという方針でグー/チョキ/パーを使い分けます。開発も、方針を統一して、方法は使い分けると安全です。


次回は、方針について書いてみたいと思います。
スポンサーサイト

テーマ : ソフトウェア開発
ジャンル : コンピュータ

プロフィール

きっぽ

Author:きっぽ

カテゴリ
最新記事
最新コメント
最新トラックバック
月別アーカイブ
FC2カウンター
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QRコード
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。