誰にも見えないブログ

雑なメモ。まとまってない文章等

メイヤー オブジェクト指向入門読書ノート5

Javaしか触ってないのでかなり狭いオブジェクト指向にしか触れられていない気がする。ジェネリクスがかなり初期のうちに出てきたのが意外。Javaに入ったのも1.5?だっけ?かなり遅かったので最近の概念だと思っていたけど、本書のような古典でも扱われるような概念だったようだ。次回はポリモーフィズムが出てくるので楽しみ。

オブジェクト指向入門 第2版 原則・コンセプト (IT Architect’Archive クラシックモダン・コンピューティング)

オブジェクト指向入門 第2版 原則・コンセプト (IT Architect’Archive クラシックモダン・コンピューティング)

「2.2.3 表明」から「2.2.14 制約付き総称性」まで読んだ。次回は「2.2.15 再定義」から

2.1 基準について

2.2 方法論と言語

2.2.3 表明

  • 表明:形式的に記述された抽象データ型の特性をクラスに反映する

    • 事前条件(routine precondition)
    • 事後条件(routine postcondition)
    • クラス不変表明(class invariant)
  • 役割

    • 信頼性の高いソフトウェアの生産を助ける
    • 系統的なドキュメントを提供する
    • オブジェクト指向的ソフトウェアのテストとデバッグのための中心的なツールとなる

2.2.4 モジュールとしてのクラス

  • クラスは型だけでなく、モジュール単位も表す
  • クラスが唯一のモジュールでなければならない

2.2.5 型としてのクラス

  • クラスで型を表現する
  • 全ての型はクラスに基づいていなければならない。

2.2.6 特性に基づく計算(Feature-based computation)

  • オブジェクト試行における基本的な計算メカニズム
    • なんらかのインスタンスが与えられる。
    • そのクラスの特性(feature)を呼び出す(必要ならば引数付きで)
      • 例:Windowクラスのdisplayという特定

特性呼び出しが第一の計算メカニズムでなければならない

  • クライアント(client):クラス特性呼び出しを含むクラスのこと
  • メッセージパッシング(message passing)特性呼び出しのこと
    • 例:nとdを引数としてeに対して特性raise(昇給させる)
      • e.rise(n,d)
      • dとnを引数として、メッセージ「あなたを昇給させなさい」をeに渡すと表現する

2.2.7 情報隠蔽(information hiding)

  • クラスが内部で使用するための属性はクラス実装の一部ではあるが、インターフェースには含めない。
    • クライアントによって呼び出される特性経由で呼び出されることはあってもクライアントの直接呼び出しを禁止する

特定の特性を顧客から呼び出せないようにするメカニズムを情報隠蔽と呼ぶ

  • 全てのクライアントに一斉に公開/非公開をサポートするだけでは不十分
    • 特定のクライアントが利用できる・出来ないを実装者が指定できる必要がある
  • クラス間通信は厳しく制限する
  • 良いOOP言語であればグローバル変数という概念を提供すべきではない。
  • クラスが情報を交換する方法は、特徴呼び出しと継承に限定する

2.2.8 例外処理(exception handling)

異常をさけろ!的な?特にここはコメントなし。

2,2.9 静的型付け(static typing)

  • オブジェクトに何ができるかの情報が必要
  • 次の規則を強制する
    • 全てのエンティ(オブジェクトを指す名前が何らかのクラスの派生した特定の型であると明示的に宣言されていること*1
    • 全ての特性呼び出しが対応するクラスの特性であること(かつ適切な情報隠蔽規則が適応されていること)
    • 代入、引数渡しが適合規則(conformance rules)に従っていること。source型がtarget型に互換性があること。
  • 静的チェックでプログラムで実行時に不正な特性呼び出しを防ぐことができる

よく定義された型システムならば、幾つかの型宣言や互換性規則を矯正することによって、受け入れたシステムの実行時の型の安全性を保証しなければならない。

2.2.10 総称性(Genericity)

型をパラメータとして与えられるクラスを定義できる必要がある。

  • 仮総称パラメータ(formal generic parameter):総称型クラスの引数として定義される型
  • 実総称パラメータ(actual generic parameter):型パラメータ化するために与える型(INTEGER,WINDOW等)

仮総称パラメータを伴うクラスを書いて任意の方を表すことができなければならない。

  • 制約なし総称性(unconstrained genericity):上記のような型パラメータ化を
  • 他には制約付き総称性(constarained genericity)や継承(inheritance)などがある

2.2.11 単一継承(single inheritance)

  • 多くのクラスは別のクラスの変形である
  • 継承と呼ばれる分類の仕組みが必要。
  • 他のクラスと同じ特性を持つクラスは他のクラスの後継者(heir)である。
    • 子孫(descendant):直接的・間接的な後継者
      • 先祖(ancstor):子孫の逆の概念

他のクラスを継承するクラスを定義出来なければならない。

2.2.12 多重継承(multiple inheritance)

  • 多重継承:複数のクラスの特性を持つ場合、任意の数のクラスから継承することを保証する。
    • 問題
      • 名前の衝突(name clash)
        • 本書では後継者クラスの仲の競合する特性をrenameして対処する
      • 紹介されていないが他にも2,3あるっぽい

クラスは任意の数のクラス空継承できなければあならない。その場合、名前の衝突を意味的、文法的に解決する適切な仕組みが必要である。

メモ:C++はどう解決しているか?要確認

2.2.13 反復継承(Repeated inheritance)

  • Class A

    • Class B extends A
    • Class C extends A
      • Class D extends B,C
  • ClassDはB,Cの多重継承経由でクラスAを2つ以上の経路で継承している。これをどう扱うか

    • 対処
      • 共有(sharing):Aの特性を1つだけ定義する
      • 複製(replication):Aの特性を2つ定義する

反復継承の場合の特性がどうなるかは、厳密な規則いよって管理されなければならない。反復して継承された個々の特性に対し、個別に共有か複製かを選択できなければならない。

  • コメント:多重継承を使える言語を本格的に暑かったことがないのでこの辺は間隔がつかめない。
    • 特性を2つ持つ、の意味がよくわからない。
    • Javaでも継承しているinterfaceの多重implementsで似たようなことを起こせる気がする

2.2.14 制約付き総称性(constrained genericity)

  • 総称性と継承を組み合わせる
  • 任意の総称パラメータを受け入れずに、与えたクラスのサブクラスに限定した総称パラメータのみ受け入れる

    • コメント:Javagenericsである<T extend Base>的なやつか。
  • 例:特性sortを持つSORTABLE_LIST

    • SORTABLE_LISTに与えられる型パラメータに任意の型は使えない。
    • 順序関係を定義できる型である必要がある。
      • 順序関係を備えたクラスCOMPARABLEの子孫であることを制約付き総称性で記述する
  • コメント:ざっと探した限り、JavaだとDelayQueueなんかが制約付き総称を使っている?

    • https://docs.oracle.com/javase/jp/9/docs/api/java/util/concurrent/DelayQueue.html
    • public class DelayQueue<E extends Delayed>
      • Delayedインタフェースを継承(Javaの文脈だと実装だが)したクラスでしか型パラメータ化出来ない。
    • DelayedインターフェースのgetDelayメソッドが0以下を返す要素のみ取得できるQueue
      • 使ったこと無いのであんまり詳しいことはわかりません。

*1:原書も眺めたけど、このエンティティの指す意味がよく分からなかった。インスタンス?変数?が違いと思うが。