自分の理解を深めるために投稿します。
第6章:クラスの作成
クラスの基礎:抽象データ型(ADT)
- ADTを理解すると…
- オブジェクト指向プログラミングの理解につながる
- 実装・変更が容易なクラスが作れる
// ADTを使用しない場合
// そのまま変数を設定する
currentFont.size = 16;
// ルーチンをライブラリにまとめる
currentFont.size = PointsToPixels( 12 );
// 属性に具体的な名前をつける
currentFont.sizeInPixels = PointsToPixels( 12 );
問題点
- 仮に
currentFont.sizeInPixels
とcurrentFont.sizeInPoints
があった場合に両方定義できない(currentFontがどちらを利用すればいいかわからないため) - 同じような行がコード内に散らばってしまう
// ADTを使用した場合
// 次のようなフォント制御用ルーチンをいくつか定義する
currentFont.SetSizeInPoints( sizeInPoints );
currentFont.SetSizeInPixels( sizeInPixels );
currentFont.SetBoldOn();
currentFont.SetBoldOff();
...
// 実際の変数定義は上記のルーチン内で行う
利点
- 実装の詳細が隠蔽される
- 変更がプログラム全体に影響しない
- もし他のフォント処理が追加されても、一箇所だけ変更すれば良い
- インターフェイスが提供する情報をより明確にできる
-
16
とはピクセルサイズか?ポイントサイズか?分からなくなりがち - ADTに集めれば、①全体を統一した単位で扱う、②明確に区別するといった方法が取れる
-
- パフォーマンスが改善しやすくなる
- プログラムが正しいか分かりやすくなる
- ADTにまとめておけば、間違いの可能性は呼び出し時のルーチンの名前くらい
- プログラムのあちこちでデータをやり取りする必要がない
- 現実世界のエンティティを扱える
良いクラスインターフェイス
上で述べたADTの概念はクラス設計と深く結びついている
- 良い抽象化
- 一貫性がある
- 関係のある情報だけ集まっている など
- 良いカプセル化
- クラスのメンバへのアクセスを最小限に抑える
- メンバを外に公開しない
- 疎結合 など
- 抽象化とカプセル化は、「どちらも行う」もしくは「どちらも行わない」くらい関係が深い
気をつけるべきこと
- 継承は複雑さを増長させる可能性がある
- 本当に必要な時しか使わないこと
- 「is a」関係にある時だけ使うこと
- クラスのルーチン数は出来るだけ少なく保つ
- クラスが呼び出すルーチン数も出来るだけ少なくする
クラスを作る理由
- 現実世界のオブジェクト・抽象オブジェクトをモデリングする
- 複雑さを緩和・分離する
- 実装の詳細を隠蔽する
- 変更により影響を限定する
- グローバルデータを隠蔽する
- 引数の受け渡しを合理化
- 制御を一元化
- コードの再利用 など