This is version . It is not the current version, and thus it cannot be edited.
[Back to current version]   [Restore this version]

★このページは書きかけです
ここに書いたのは、2000年~2001年に渡って私が設計・実装したJavaのフレームワーク開発を主に通じて理解したオブジェクト指向の原理原則です。 私は単なるエンジニアであって学者や研究者ではない上に、オブジェクト指向について誰かから教わった経験も無いため、ここに書いてある内容は科学的に吟味されたものではありません。
しかし、普段の仕事の中で気付いた合理性のある内容だと考えています。

オブジェクト指向って?#

オブジェクト指向の最初の説明として良く出てくるのが、
  • 隠蔽
  • 継承
  • 多態性
というものです。 これらはオブジェクト指向の特徴を確かに言い表していますが、オブジェクト指向的な設計や実装を初学者が理解するための役に立たないとytpは考えています。少なくとも初心者にとっては百害有って一理無しです。
これから説明するオブジェクト指向に関する原則は、実際の開発現場で皆さんが実践することを目的に書いています。つまり、
  • 開発現場で役立つオブジェクト指向の本質を解き明かす
ために書きました。

オブジェクト指向設計に関してはデザインパターンという形で様々な本が書かれていますが、パターンは有用ではあるものの全部を一々覚えてはいられません。そもそもパターンというのは、オブジェクト指向の本質を理解した人が設計した有用な常套手段に名前を付けたものです。
  • パターンは囲碁で言う定石
です。しかし、
  • 定石には必ず理由があり、それらの根底には共通する原理原則がある
のです。
このサイトでは、オブジェクト指向設計における原理原則を記述しています。つまり、
  • 定石を産み出すための原理原則
です。囲碁で言えば手筋(てすじ)が近いでしょうか。
これを理解してしまえばパターンに頼ることなく正しい設計にたどり着けると私は考えています。パターンを否定しているのではありません。
  • パターンの奥に隠れた本質を理解する
ことが大切なのです。

クラス図の読み方#

このサイトでは、UML(Unified Modeling Language)のクラス図(Class Diagrams)がたくさん出て来ます。ご存じない人のためにその読み方を簡単に説明します。次の4つがあります(UMLの定義ではこれ以外もあります)。
  1. 関連
  2. コンポジット集約
  3. 実現
  4. 汎化

関連#

「独立したAクラスとBクラスがお互い相手を参照する」という関係を表します。「バイク本体とタイヤ」のような関係です。タイヤはバイクの部品ですが、あるタイヤを色々なバイクに取り付けることが可能です。このような関係です。
association.png

コンポジット集約#

「AクラスがBクラスを部分として持っている」という関係は上の集約と同じですが、Bクラスインスタンスの生成/消滅/移動の制御をAクラスが行うことが異なります。例えば「木と木の葉」、または「伝票と伝票明細」のような関係です。単に「コンポジション」とも呼ばれます。
composite.png

実現#

「Mインタフェースの振る舞いをCクラスが具体化(実装)している」という関係を表します。インタフェースでは、振る舞いの型(パラメータと戻り値)だけを定義し、その具体化(実装)はCクラス側に任せます。インタフェースは「役割」と理解すればいいでしょう。
implement.png

汎化#

「EとFの性質の共通部分を抜き出してDとした」関係のことです。例えば「ワゴン車とセダンを自動車と呼ぶ」という関係です。俗に「継承」とも呼ばれ、「is a の関係」と言われます( E is a D.)。
generalize.png

集約は使わない#

UMLの産みの親「Three amigos」の一人であるジム・ランボーによると、
  • 集約はプラセボ(プラシーボ)効果である
とのことです。つまり、「その効果は気のせい」という意味で、有用性は無いとのことです。
最近まで私は関連を使わずに集約を書いていたのですが、色々迷って考えた結果逆の結論に至りました。モデルを表現する際、集約は紛らわしさを助長します。
「has a」の関係と言われますが、
  • AクラスがBクラスを持つのか?
  • BクラスがAクラスを持つのか?
によって菱形を付けるクラスが換わりますが、双方向で参照するため、
  • どちらも相手を持つ
という結果になるのです。

クラス図で集約を記述する際、「菱形」をどちらに付ければいいのか迷います。「A has B」の場合はA側に菱形を付ける決まりがあります。
では、入荷伝票を例に取るとどうでしょうか?

仕入先 has 入荷伝票#

下の図は、入荷伝票と入荷明細の関係を仕入先と商品と共に表したものです。
aggregation3.png
集約という言葉を「1つのインスタンスが別クラスのインスタンスを複数を持つ」という意味に取るならば確かにこの図になります。しかし、
  • 仕入先 has 入荷伝票
  • 商品 has 入荷明細
と読めてしまい、私にはしっくり来ません。

入荷伝票 has 仕入先#

下の図は、菱形の位置が上とは逆です。「入荷伝票が仕入先を持っている」「入荷明細が商品を持っている」という意図で書いたものです。 aggregation2.png
こちらの方が私にはしっくりくるため、このサイトではこの書き方で統一しています。
なお、菱形を記述しない「関連」という記法もありますが、この関連は意味付けが曖昧になるため、私はモデリング初期段階でしか使いません。最終的には「集約」あるいは「コンポジット集約」に収斂(しゅうれん)させます。

集約・コンポジット集約・関連の実践的な使い分けに詳しい方からのご指摘をお待ちしています。(ありきたりで曖昧なサンプルではなく、実際の開発で使用した時のルールです)

このサイトを読む上での注意点#

このサイトに書いてある内容には、皆さんのこれまでの常識をくつがえすものが多々あります。今までの常識にとらわれずに読んで下さい。可能ならば頭を白紙の状態にして、書いてある内容を純粋に吟味してみて下さい。皆さんの開発にきっと役立つはずです。

それでは次ページから、「本には書いてないオブジェクト指向」の始まりです。

本には書いてないオブジェクト指向のページ一覧#

クラスとはデータ構造
責務はクラスではない
クラスにするもの
小粒クラス
リンゴ一個とリンゴ一山は異なるクラス
関数とユーティリティクラスは禁止
privateメソッド禁止
どのメソッドをどのクラスで実装すべきか

添付ファイルの追加

ログイン済のユーザのみが添付ファイルをアップロード出来ます。

添付ファイル一覧

Kind Attachment Name Size Version Date Modified Author Change note
png
aggregation.png 1.4 kB 2 19-9-2011 00:08 ytp
png
aggregation2.png 3.2 kB 1 18-7-2011 01:13 ytp
png
aggregation3.png 3.2 kB 1 18-7-2011 01:13 ytp
png
association.png 1.0 kB 1 20-9-2011 00:04 ytp
png
composite.png 1.4 kB 1 18-7-2011 01:13 ytp
png
extend.png 1.4 kB 1 18-7-2011 01:13 ytp
png
generalize.png 3.2 kB 1 18-7-2011 02:28 ytp
png
implement.png 1.9 kB 1 18-7-2011 01:13 ytp
« This particular version was published on 19-9-2011 02:19 by ytp.