| At line 1 changed one line |
| ここに書いたのは、2000年~2001年に渡って私が設計・実装したJavaのフレームワーク開発を主に通じて理解したオブジェクト指向の原理原則です。 |
| !!オブジェクト指向を上手に活かすために |
| ここに書いたのは、私が設計・実装したJavaのフレームワーク開発を主に通じて理解したオブジェクト指向の原理原則です。\\ |
| At line 3 changed one line |
| しかし、普段の仕事の中で気付いた合理性のある内容だと考えています。 |
| しかし、普段の仕事の中で気付いた合理性のある内容だと考えています。オブジェクト指向言語を日常使ってはいても、オブジェクト指向そのものをみっちりと学習したことがない人にとって特に役立つ内容だと思います。 |
| At line 11 changed one line |
| これらはオブジェクト指向の特徴を確かに言い表していますが、オブジェクト指向的な設計や実装を初学者が理解するための役に立たないとytpは考えています。少なくとも初心者にとっては百害有って一理無しです。\\ |
| これらはオブジェクト指向の特徴を確かに言い表していますが、オブジェクト指向的な設計や実装を初学者が理解するための役に立たないとytpは考えています。少なくとも初心者にとっては百害有って一利無しです。\\ |
| At line 17 changed one line |
| *パターンは囲碁で言う定石 |
| *パターンは囲碁で言う__定石__ |
| At line 19 changed one line |
| *定石には必ず理由があり、それらの根底には共通する原理原則がある |
| *定石には必ず理由があり、それらの根底には__共通する原理原則__がある |
| At line 24 changed 3 lines |
| これを理解してしまえばパターンに頼ることなく正しい設計にたどり着けると私は考えています。パターンを否定しているのではありません。 |
| *パターンの奥に隠れた本質を理解する |
| ことが大切なのです。\\ |
| これを理解してしまえばパターンのみに頼ることなく正しい設計にたどり着けると私は考えています。しかしパターンを否定しているのでは決してありません。 |
| *パターンの奥に隠れた__本質(原理原則)を理解する__ |
| ことが大切だと考えています。\\ |
|
| !!オブジェクト指向の利点 |
| オブジェクト指向で開発すると何がいいのでしょうか? 一言で言うと、 |
| *1箇所直せばみな直る |
| です。\\ |
| 実はオブジェクト指向は、最初にコードを書く時の生産性は手続き型に較べて低いのです。しかし、 |
| #開発中あるいは開発後に仕様変更または仕様ミスがあって修正する |
| #別のシステムでの部品を流用する |
| ような場合に威力を発揮します。つまり、 |
| #保守性が高い |
| #再利用性が高い |
| という特徴があるのです。\\ |
| そのため、 |
| *徹底したオブジェクト指向で開発されたシステムは総合的な生産性が高い |
| と言えます。\\ |
|
| !!オブジェクト指向はなぜ難しいか |
| 特に最近は関数型指向と言って手続き型へ回帰するほど、オブジェクト指向を回避する傾向が見られます。\\ |
| オブジェクト指向はなぜそれほど難しいのでしょうか?\\ |
| いくつか理由は考えられますが、以下の3点が大きいのではないかと思います。\\ |
| #顧客から要求されるのは処理であってデータ構造ではないため、データ構造を正しく定義出来ないから。 |
| #オブジェクト指向言語は手続き型言語の延長線上にあり、手続き型でも書けてしまうから。(特にJavaの場合は) |
| #RDBとの相性がとても悪く、筋の悪いO/Rマッパーを使うと処理とデータ構造が分離されて結局手続き型になってしまうから。\\ |
| この相性の悪さをインピーダンスミスマッチと言います。どう対応すればいいのかを[関数とユーティリティクラスは禁止]で詳しく書いています。\\ |
|
| オブジェクト指向をきちんと理解できていない人が雑誌やWebなどで誤った説明をしているのを見るのはとても複雑な気持ちです。悪気は無いのでしょうが、うまく使いこなせない人を増やす結果になっています。\\ |
| そのような人たちは次の点をまず理解して欲しいと思います。 |
| *処理ではなく、データ構造をまず共通化する。\\ |
| [privateメソッド禁止]で詳しく書いています。 |
| |
| At line 28 changed 3 lines |
| このサイトでは、UML(Unified Modeling Language)のクラス図(Class Diagrams)がたくさん出て来ます。ご存じない人のためにその読み方を簡単に説明します。次の4つがあります(UMLの定義ではこれ以外もあります)。\\ |
| #集約 |
| #コンポジット集約 |
| このサイトでは、UML(Unified Modeling Language)のクラス図(Class Diagrams)がたくさん出て来ます。ご存じない人のためにその読み方を簡単に説明します。次の3つがあります(UMLの定義ではこれ以外もあります)。\\ |
| #関連 |
| At line 34 changed 3 lines |
| !集約 |
| 「AクラスがBクラスを部分として持っている」という関係を表します。「__has a の関係__」と言われます。「バイク本体とタイヤ」のような関係です。あるタイヤは色々なバイクに取り付けることが可能です。つまりバイク本体とタイヤは独立して存在できます。このような関係です。\\ |
| [aggregation.png] |
| !関連 |
| [association.png]\\ |
| 「独立したAクラスとBクラスがお互い相手を参照する」という関係を表します。「バイク本体とタイヤ」のような関係です。タイヤはバイクの部品ですが、あるタイヤを色々なバイクに取り付けることが可能です。 |
| *このバイクの部品として使っているタイヤ |
| *このタイヤを利用しているバイク |
| という双方向の関係が成立します。\\ |
| 関連を記述する場合は |
| *多重度(カージナリティ:cardinality) |
| を省略してはいけません。これが記述されていないと、そのモデルが扱う業務の目的を理解できないからです。\\ |
| At line 38 removed 4 lines |
| !コンポジット集約 |
| 「AクラスがBクラスを部分として持っている」という関係は上の集約と同じですが、Bクラスインスタンスの生成/消滅/移動の制御をAクラスが行うことが異なります。例えば「木と木の葉」、または「伝票と伝票明細」のような関係です。単に「__コンポジション__」とも呼ばれます。\\ |
| [composite.png] |
|
| At line 43 changed 2 lines |
| 「Mインタフェースの振る舞いをCクラスが具体化(実装)している」という関係を表します。インタフェースでは、振る舞いの型(パラメータと戻り値)だけを定義し、その具体化(実装)はCクラス側に任せます。インタフェースは「役割」と理解すればいいでしょう。\\ |
| [implement.png] |
| [implement.png]\\ |
| 「Mインタフェースの振る舞いをCクラスが具体化(実装)している」という関係を表します。振る舞いの型(呼び出し名、パラメータ、戻り値)だけをインタフェースでは定義し、その具体化(実装)はCクラス側に任せます。 |
| *インタフェースは「役割」 |
| と理解して下さい。\\ |
| 例えば自動車と飛行機の役割は「乗り物」です。この場合、乗り物インタフェースを実現(実装)する形で自動車クラスと飛行機クラスを設計します。 |
| At line 47 changed 2 lines |
| 「EとFの性質の共通部分を抜き出してDとした」関係のことです。例えば「ワゴン車とセダンを自動車と呼ぶ」という関係です。俗に「継承」とも呼ばれ、「__is a の関係__」と言われます( E is a D.)。\\ |
| [generalize.png] |
| [generalize.png]\\ |
| 「EとFの性質の共通部分を抜き出してDとした」関係のことです。例えば「ワゴン車とセダンを自動車と呼ぶ」という関係です。「継承」とも呼ばれます。 |
| *ワゴン車は自動車を継承している。 |
| また「__is a の関係__」とも言われます |
| * E is a D. |
| *ワゴン車は自動車である。(自動車として扱える) |
| At line 50 changed 3 lines |
| !!集約の記述 |
| クラス図で集約を記述する際、「菱形」をどちらに付ければいいのか迷います。「A has B」の場合はA側に菱形を付ける決まりがあります。\\ |
| では、入荷伝票を例に取るとどうでしょうか? |
| !!集約は使わない |
| UMLの産みの親「Three Amigos」の一人であるジム・ランボーは、 |
| *集約はプラセボ(プラシーボ)効果である |
| と言いました。つまりその効果は「気のせい」で、有用性は無いという意味です。\\ |
| 最近まで私は__関連__を使わずに__集約__のみで書いていたのですが、色々迷って考えた結果この逆の結論に至りました。モデルを表現する際、集約は紛らわしさを助長します。\\ |
| 集約は「has a」の関係と言われ、 |
| *AクラスがBクラスを持つのか? |
| *BクラスがAクラスを持つのか? |
| によって菱形を付けるクラスが入れ換わりますが、関連があるクラス同士は双方向で参照するため、 |
| *どちらも相手を持てる(持つ必要がある) |
| という結果になるのです。そのため集約は意味を成しません。 |
| At line 54 removed 16 lines |
| !仕入先 has 入荷伝票 |
| 下の図は、入荷伝票と入荷明細の関係を仕入先と商品と共に表したものです。\\ |
| [aggregation3.png]\\ |
| 集約という言葉を「1つのインスタンスが別クラスのインスタンスを複数を持つ」という意味に取るならば確かにこの図になります。しかし、 |
| *仕入先 has 入荷伝票 |
| *商品 has 入荷明細 |
| と読めてしまい、私にはしっくり来ません。 |
|
| !入荷伝票 has 仕入先 |
| 下の図は、菱形の位置が上とは逆です。「入荷伝票が仕入先を持っている」「入荷明細が商品を持っている」という意図で書いたものです。 |
| [aggregation2.png]\\ |
| こちらの方が私にはしっくりくるため、このサイトではこの書き方で統一しています。\\ |
| なお、菱形を記述しない「関連」という記法もありますが、この関連は意味付けが曖昧になるため、私はモデリング初期段階でしか使いません。最終的には「集約」あるいは「コンポジット集約」に収斂(しゅうれん)させます。\\ |
| \\ |
| 集約・コンポジット集約・関連の__実践的な使い分け__に詳しい方からのご指摘をお待ちしています。(ありきたりで曖昧なサンプルではなく、実際の開発で使用した時のルールです)\\ |
|
| At line 114 added 7 lines |
| [業務シナリオで考える]\\ |
| [インタフェースとは何か]\\ |
| [継承の使いどころ]\\ |
|
| !!ひょっとして出版社の人が居たら |
| このサイトに書いたオブジェクト指向に関しての執筆依頼がもしもあれば喜んでお受けいたします。\\ |
| __田中良浩__: メールアドレスは __tanaka_y__ (ドメインは__ytp.ne.jp__)\\ |