「オブジェクト指向でなぜつくるのか 第2版」を読んでみた

Posted by

概要

Kindle Unlimitedに加入してみて良さそうな技術書を探していたところ一番におすすめで出てきた「オブジェクト指向でなぜつくるのか 第2版」を読んでみたのでそのまとめを書きたいと思います。本書ではオブジェクト指向(以降OOPと記載、Object Oriented Programming language)の特徴を大きく「プログミング技術」と「汎用の整理術」の2面からわかりやすく言語化して記載されていました。特に「プログラミング技術」の部分では他の技術書でよくある現実世界に無理やり置き換えた比喩を極力使わずに言語と図を用いて表現されていた部分がよかったと思います。

「オブジェクト指向でなぜつくるのか 第2版」

内容

プログラミングの歴史

  • 機械語→アセンブリ言語→高級言語→構造化言語(GOTOレス)→オブジェクト指向(OOP)
  • 機械語:コンピュータが解釈できる言語
  • アセンブリ言語:アセンブリ言語を使って書いたプログラムは、それをコンパイルするアセンブラと呼ばれるプログラムに読み込ませて機械語を生成
  • 高級言語:FORTRANやCOBOLなどの人がわかりやすい言語。
  • 構造化言語(GOTOレスプログラミング):基本三構造(順次実行、if文による条件分岐、for文やwhile文による繰り返し)。サブルーチンで独立性を高めて、複数サブルーチン間はグローバル変数で共有する。代表的なのはC言語。GOTO文を極力使わないように。
  • オブジェクト指向(OOP):グローバル変数問題、貧弱な再利用の2つの課題を解決させるために登場。Simula67→Smalltalk→Javaの流れ。

オブジェクト指向の特徴整理

3大要素

  • クラス(まとめる、隠す、たくさん作る)
    • 関連性の強いサブルーチン(関数)とグローバル変数を1つにまとめて粒度の大きいソフトウェア部品をつくる仕組み。
    • サブルーチンと変数を「まとめる」、メソッドとインスタンス変数(属性、フィールド)
    • クラスの内部だけで使う変数やサブルーチンを「隠す」、カプセル化
    • 1つのクラスからインスタンスを「たくさん作る」、インスタンス
  • ポリモフィズム(呼び出す側を共通化)
    • 英語で「いろいろな形に変わる、多態性、多相性」
    • 類似したクラスに対するメッセージの送り方を共通にする仕組み
    • 目的は呼び出す側を共通化すること
    • 実装は継承を使う
  • 継承(重複を排除する)
    • モノの種類の共通点と相違点を体系的に整理する仕組み
    • 似たもの同士のクラスの共通点と相違点を整理する仕組み
    • 目的はクラスの共通部分を別クラスにまとめること

進化した仕組み

  • パッケージ
    • クラスをまとめる仕組み
    • クラスの名前の重複を全世界で避ける役割もある
  • 例外
    • 戻り値とが違う形式でメソッドから特別なエラーを返す
  • ガベージコレクション
    • ヒープ領域に作成されて、使われていないインスタンスを自動的に削除する仕組み
    • ガベージコレクタと呼ばれるシステムが用意する専用のプログラムがインスタンスをメモリから削除する

実行方式とメモリの使用

  • コンパイラ方式:プログラムに書かれた命令をコンピュータが理解できる機会に変換したから実行する方式
  • インタプリタ方式:ソースコードに書かれたプログラムの命令をそのばで逐次解釈しながら実行する方式
  • コンパイラ方式とインタプリタ方式コンパイラ方式は実行効率がよく、インタプリタ方式では同じプログラミングを異なる環境で動作させることができる
  • 中間コード方式:ソースコードを特定の機械語に依存しない中間コードに変換し、その中間コードを専用のインタプリタによって解釈して実行する
    • Javaや.NETで採用されている
    • 中間コード方式により同じプログラミングを異なる実行環境で効率良く動かすことができる
  • スレッドとプロセススレッドはプログラムの実行単位で、複数のスレッドでひとまとまりの1つのプロセスとなる
  • 静的領域:プログラムの開始時に確保され、以降プログラムが終了するまで配置が固定される領域
  • ヒープ領域:プログラムの実行時に動的に確保するためのメモリ領域
  • スタック領域:スレッドの制御のために使うメモリ領域。ヒープ領域は複数のスレッドで共用されるが、スタック領域はスレッドに1つずつ用意される。
    • LIFO(Last In First Out)
  • OOPでのメモリ領域クラス情報は静的領域にロードされる
  • OOPのプログラムは、ヒープ領域を大量に使って動く。
  • インスタンスはヒープ領域に作成されるが、変数に格納されるのはメモリの場所を指すポイント。
  • 実装で注意すべて点は、不要になったインスタンスをスタックやメソッドエリアから参照し続けないようにすること

フレームワークやデザインパターン

  • フレームワークには、「包括的なアプリケーション基盤」の意味と「特定の目的のために書かれた再利用部品群」の意味がある
  • フレームワークでのポリモフィズムと継承の役割ハリウッドの法則(Don’t call us, we will call you):基本的な処理はフレームワーク側で用意し、アプリケーション固有の処理はポリモフィズムを利用して呼び出す
  • アプリケーション固有の処理は継承の仕組みを利用してあらかじめデフォルトの機能を用意しておく

GoFデザインパターン(23種)

  • 4人の技術者(Gang of Fourの略)
  • デザインパターンに慣れる
    • Iterator:1つ1つ数えあげる
    • Adapter:一皮被せて再利用
  • サブクラスに任せる
    • Template Method:具体的な処理をサブクラスに任せる
    • Factory Method:インスタンス作成をサブクラスに任せる
  • インスタンスを作る
    • Singleton:たった一つのインスタンス
    • Prototype:コピーしてインスタンスを作る
    • Builder:複雑なインスタンスを組み立てる
    • Abstract Factory:関連する部品を組み合わせて製品を作る
  • 分けて考える
    • Bridge:機能の階層と実装の階層を分ける
    • Strategy:アルゴリズムをごっそり入れ替える
  • 同一視
    • Composite:容器と中身の同一視
    • Decorator:飾り枠と中身の同一視
  • 構造を渡り歩く
    • Visitor:構造を渡り歩きながら仕事をする
    • Chain of Responsibility:責任のたらい回し
  • シンプルにする
    • Facade:シンプルな窓口
    • Mediator:相手は相談役1人だけ
  • 状態を管理する
    • Observer:状態の変化を通知する
    • Memento:状態を保存する
    • State:状態をクラスとして表現する
  • 無駄をなくす
    • Flyweight:同じものを共有して無駄をなくす
    • Proxy:必要になってから作る
  • クラスで表現する
    • Command:命令をクラスにする
    • Interpreter:文法規則をクラスで表現する

UML

  • 13種類
  • クラス図:クラスの仕様とクラス間の関係を表現する
  • 複合構造図:全体 – 部分構造を持つクラスの実行時の構造を表現する
  • コンポーネント図:ファイルやデータベース、プロセスやスレッドのソフトウェアの実装構造を表現する
  • 配置図:ハードウェアやネットワークなど、システムの物理構造を表現する
  • オブジェクト図:インスタンス間の関係を表現する
  • パッケージ図:パッケージ間の関係を表現する
  • アクティビティ図:一連の処理における制御の流れを表現する
  • シーケンス図:インスタンス間の相互作用を時系列に表現する
  • コミュニケーション図:インスタンス間の相互作用を構造中心に表現する
  • 相互作用概要図:条件によって異なる動作をするシーケンス図をアクティビティ図の中に含めることで表現する
  • タイミング図:インスタンス間の状態遷移や相互作用を時間制約つきで表現する
  • ユースケース図:システムが提供する機能と利用者の関係を表現する
  • ステートマシン図:インスタンスの状態変化を表現する

モデリング

  • 業務分析
    • 現実世界の仕事がどういう役割でどのように進めているのかを整理
    • 合わせて、業務を遂行する上での課題を抽出し、コンピュータに任せる仕事を決めるための情報源とする
  • 要求定義
    • 現実世界の仕事の中からコンピュータに任せる仕事を定義する
  • 設計
    • ハードウェアの能力、OSやミドルウェアの特性、プログラミング言語の表現能力などを考慮して、ソフトウェアの構造を決める

開発手法

  • ウォーターフォール
  • RUP(Rational Unified Process)
  • XP(eXtreme Programming)
  • アジャイル
  • TDD(Test Driven Development)
  • リファクタリング
  • CI(Continuous Integration)

関数型言語

  • 関数型言語では、関数の実行を「引数に関数を適用する」と表現する
  • 命令型言語と関数型言語の違い
    • 命令型言語では、命令を実行すると表現するが、関数型言語では数学用語と同様に式を評価すると表現する

まとめ

基礎的な内容が多かったが、初心者にも比較的わかりやすく記載されていた。経験者であっても、改めてオブジェクト指向の概要を幅広く復習できるのでおすすめできる。また、本書の途中に登場したデザインパターンは非常に気になったので次は下記を読みたくなった。

「Java言語で学ぶデザインパターン入門」https://www.amazon.co.jp/dp/B00I8ATHGW