690 likes | 954 Views
オブジェクト指向とJavaの入門講座. モデリングからテストまで自分自身で体験. 講座の目的. オブジェクト指向の概要をつかみたい Java を勉強する前の予備知識をつけたい いまさら部下に Java について聞けない SIer が言っていることを理解したい Java開発の現場を理解したい. オブジェクト指向と Java が何となくわかる. これだけは覚えよう!. 今回の講座ではいろいろな専門用語が登場しますが、以下に示すものだけは覚えて帰るようにしてください。 クラス インスタンス 属性、インスタンス変数 振る舞い、メソッド 関連、集約、汎化 継承.
E N D
オブジェクト指向とJavaの入門講座 モデリングからテストまで自分自身で体験
講座の目的 • オブジェクト指向の概要をつかみたい • Javaを勉強する前の予備知識をつけたい • いまさら部下にJavaについて聞けない • SIerが言っていることを理解したい • Java開発の現場を理解したい オブジェクト指向とJavaが何となくわかる
これだけは覚えよう! 今回の講座ではいろいろな専門用語が登場しますが、以下に示すものだけは覚えて帰るようにしてください。 • クラス • インスタンス • 属性、インスタンス変数 • 振る舞い、メソッド • 関連、集約、汎化 • 継承 テキストP2
冷蔵庫は見えるか? システムのことは一切忘れて以下に書かれている冷蔵庫を目に見えるようにしてください。 • 冷蔵庫は2ドアで冷凍室と冷蔵室がある。 • 冷凍室にアイスクリームが1つ入っている。 • 冷凍室には製氷皿があり氷ができている。 • 冷蔵室にはチーズが入っている。 • 冷蔵庫にはドアポケットがあり、ビールが3本入っている。 テキストP3
冷蔵庫を書いてみた 冷蔵庫を書くのに苦労したこと。 • 実際に物を入れてみてスケッチ。 • なかなか上手に書けない。 • 書き上げるまでにアイスクリームがとけてしまった。 美的センスに左右される
別の方法で書いてみた 冷蔵庫を書くのに注意したこと。 • 簡単に素早くかける。 • 美的センスを必要としない。 • 実際の物を見なくても書ける。 • アイスクリームをとかさない。 思いを見えるようにすること、 これがモデリング
2つの共通点 • 見ている視点は同じ • 物が最小の単位で書かれる • 物と物の関係が書かれる 物を中心にモデリング=オブジェクト(物)指向
オブジェクト指向とは オブジェクト指向とは、良いシステム作りのアプローチ方法であり、2つの技術要素を持っています。 モデリング 技術 プログラミング 技術 良いシステムを効率よく開発
オブジェクト指向とは 2つの技術は同じ物ではありません、それぞれを構成する要素も異なります。そして、目的にしているのは、汎用機時代に一般的に使用された構造化手法と同じです。 モデリング 技術 見えないシステムを見えるようにする プログラミング技術 保守性の高いプログラムを素早くつくる
モデリングの基本は物と関係 オブジェクト指向で言うところのモデリングの基本はオブジェクト(物)を洗い出し、これに関係線を付ける所から始まります。 例えば「上司は部下に命令して仕事をさせる」ことをモデリングすると以下のようになります。 上司 部下 要件の名詞をオブジェクトとして 抽出し、関係を結ぶ
物と物の関係を示すクラス図 物と物との間の関係を現す図をクラス図と言います。 関係にはいくつかの種類がありますが、3つ知っていれば充分です。 A B B A A B
冷蔵庫をモデリング 説明したクラス図で冷蔵庫をモデリングしてください。 • 冷蔵庫は2ドアで冷凍室と冷蔵室がある。 • 冷凍室にアイスクリームが1つ入っている。 • 冷凍室には製氷皿があり氷ができている。 • 冷蔵室にはチーズが入っている。 • 冷蔵庫にはドアポケットがあり、ビールが3本入っている。 オブジェクトの候補をみつけ関係線をひく テキストP4
冷蔵庫をモデリング クラス図にでてくる四角をクラスと言い、要件の名詞より抽出できます。 • 冷蔵庫は2ドアで冷凍室と冷蔵室がある。 • 冷凍室にアイスクリームが1つ入っている。 • 冷凍室には製氷皿があり氷ができている。 • 冷蔵室にはチーズが入っている。 • 冷蔵庫にはドアポケットがあり、ビールが3本入っている。 オブジェクト候補
冷蔵庫をモデリング 冷蔵庫本体をモデリングする。 冷蔵庫 冷蔵室 ドアポケット 冷凍室 製氷皿 冷蔵庫の部品は集約
冷蔵庫に中身を追加 冷蔵庫本体に中身を追加してみましょう。 冷蔵庫 冷蔵室 ドアポケット 1 1 1 1 1 1 3 1 ビール チーズ 冷凍室 製氷皿 氷 アイス
冷蔵室・冷凍室の取り扱い 冷蔵庫の冷蔵室、冷凍室は冷やす温度が違うだけで概念的には同じもです。 冷蔵庫 冷蔵室 1 冷やす温度が3〜5℃なら冷蔵室 1..* 格納室 冷やす温度が0℃以下なら冷凍室 冷凍室 概念として同じ物は汎化として表現できる
汎化と継承 汎化の状態にあるものを、オブジェクト指向では継承関係にあると言います。 A • Aをスーパークラスと呼ぶ • Bをサブクラスと呼ぶ • BはAが持つ性質をすべて引継ぐ B 継承はオブジェクト指向3大要素の1つ
冷蔵庫のモデル 以上で冷蔵庫のモデリングは終了です。 これは、システム開発では要件定義〜基本設計で目にする業務モデルに相当します。 冷蔵庫 冷蔵室 ドアポケット 1 1 1 1 1 3 1 1 1 1..* ビール チーズ 格納室 冷凍室 製氷皿 氷 アイス
ここまでのまとめ オブジェクト指向モデリングの基本は、機能(処理)に着目するのではなく、問題領域(ドメイン)を構成する物や概念に着目し、その関係を示すことにあります。 • ドメインに対する視点を明確にする。 • ドメインが対象とする物をモデリングの対象とする。 • 書き方ではなく、モデルの質を重視する。 • 処理の流れや順序はいったん忘れる。
三菱電機新型冷蔵庫発表 いよいよ実践、設計からテストまで!
三菱電機新型冷蔵庫とは? 2XXX年、三菱電機は野菜を傷つけることなく野菜の収穫日を測定する新しいセンサーを開発しました。三菱電機は、この新型センサーを利用した「野菜の賞味期限がわかる」野菜室専用冷蔵庫を発表しました。 私たちはこの新型冷蔵庫「MX−2010」のシステム開発を担当することになりました。 テキストP5
要件はユースケースで オブジェクト指向では要件をユースケース図として取りまとめます。 ユースケース図はシステムが持つ機能を、それに関わる外部からの視点で整理したものです。 ユースケース図はオブジェクト指向的考えを必要としません。 システム化対象範囲 ・システムが外部に公開する機能 ・内部的な機能は記載しない ユースケース アクター ・ユースケースに影響を与える物 ・ユースケースの恩恵を受ける物 ・人間である必要はない ・システム化の対象となる範囲 ・枠の外側にユースケースがある場合はシステム化の対象外 テキストP6
新型冷蔵庫のモデル ユースケース図をもとに、新型冷蔵庫に求められる要件を整理して概念クラス図を作成してください。 なお、概念クラス図には冷蔵庫と野菜の関係も記載することとします。 • 新型冷蔵庫は野菜室専用1ドア冷蔵庫 • 野菜の収穫日で賞味期限がわかる • 庫内にはセンサーがあり野菜の情報を読み込む • ディスプレイには消費者の操作で賞味期限が表示される • ディスプレイに表示されるのは野菜の名前、賞味期限 テキストP7
新型冷蔵庫の概念クラス図 野菜室 冷蔵庫 MX-2010 冷蔵庫 MX-2010 野菜室 センサー ディスプレイ 既に存在する冷蔵庫と野菜室を 継承している 野菜
継承を使用した共通化 構造化手法では共通化は共通処理をサブルーチンとして切り出す方法が用いられますが、オブジェクト指向では共通的なクラスに異なる部分を拡張する方法が用いられます。 野菜室 格納室には野菜を出し入れして保持する機能がもとから備わっている。 新型冷蔵庫の野菜室では、センサを保持し、収穫日を読み込めるようにすればよい。 MX-2010 野菜室 継承は共通化には欠かせない
オブジェクトの内部を設計 オブジェクト指向ではオブジェクト(物)が持つ属性(データ)と振る舞い(処理)を「ひな形」として規定し、これの実態をオブジェクトとして取り扱います。 この2つをクラスとインスタンスの関係と呼びます。 ひな形(クラス) 実態(インスタンス) 社員 名前 入社日 仕事をする 山田太郎 2000年4月1日 システム開発をする
クラス内部の表現方法 先ほどの社員の例をクラス図で表すと以下のようになります。 オブジェクト指向では属性と振る舞いを1つのクラスにまとめて管理します。 クラス名 社員 <書き方> <社員の例> 名前 入社日 属性 仕事をする 振る舞い
クラスとカプセル化 クラスに定義されたデータ(属性)と処理(振る舞い)を1つで管理することをカプセル化と言います。 • 属性と振る舞いにはアクセス修飾を付けることができる • 外部に公開する必要のないデータ、処理を保護できる • 外部に公開する範囲を決められる • 安全なプログラムが作成できる カプセル化はオブジェクト指向3大要素の1つ
新型冷蔵庫の詳細クラス図 冷蔵庫と野菜室の関係をクラス図で表すと以下のようになります。 その他の部分の詳細なクラス図を作成しましょう。 野菜室 冷蔵庫 野菜室 冷蔵庫 野菜リスト メーカー 製品名 格納室 MX-2010 冷蔵庫 MX-2010 野菜室 センサー ディスプレイ 入れる(野菜) 取出す(名前) 野菜 ※本講習ではアクセス修飾子は省略しています。 テキストP8
新型冷蔵庫の詳細クラス図 新型冷蔵庫の詳細クラス図を完成させてください。 クラス図を考える テキストP9
新型冷蔵庫の詳細クラス図 詳細クラス図からは徐々に実装が意識されるようになります。 テキストP9
オブジェクトの相互作用 ここまでで作成したクラス図はシステムの静的な状態を表す物であるため、システム全体としての流れを整理する必要があります。 オブジェクト指向ではオブジェクトにメッセージを送ることで、メッセージに即した振る舞いが実行されます。 鳴け ワン <メッセージ> <人クラス> <犬クラス>
シーケンス図 オブジェクト間のメッセージのやり取りを整理するのがシーケンス図です。 犬に鳴けと命令するクラス図とシーケンス図を見てみましょう。 イメージとしては相手の振る舞いを呼び出すことになります。 <クラス図> <シーケンス図> 人 人 犬 メッセージ 鳴く 活性期間 (動いている) 犬 名前 生存期間 (存在する) +鳴く テキストP11
新型冷蔵庫のシーケンス図 シーケンス図は、作成したクラス図全体の整合性を見る上でも役に立ちます。 シーケンス図を考える テキストP12
シーケンス図で表現 テキストP13
Javaプログラムにする ここまでで、クラスの属性(データ)と振る舞い(処理)とそのクラス間のメッセージ(関係)を明確にしたので、詳細設計ができたことになります。 これをJavaプログラムのソースコードに置き換えていけばプログラムは出来上がりです。 • 属性は変数になります。 • 振る舞いはメソッドになります。 • メッセージはメソッドの呼び出しになります。
人間と犬のプログラム 人間と犬のJavaプログラムを見てみます。 人クラスはプログラムの入り口である「main」メソッドを持っています。 <クラス図> <ソースコード> クラスを定義。 public class 人 { /** * プログラムが一番最初に呼び出される main メソッド. * @param args パラメータなし */ public static void main(String[] args) { // 犬クラスの生成(名前を設定) 犬 ポチ = new 犬("ポチ"); // 生成した犬に「鳴く」を指示する。 // 鳴き声が返却されるので、取得する。 String 鳴き声 = ポチ.鳴く(); // 鳴き声変数の値をコンソールに出力する。 System.out.println(鳴き声); } } 人 最初に実行されるメソッドは「main」です。 犬クラスのインスタンスをnewで生成。 犬クラスの鳴くメソッドを呼び出す。 結果をコンソールに表示します。 テキストP14
人間と犬のプログラム 犬クラスは「鳴く」と言うメソッドを持っています。 属性とメソッドの表現に注意してください。 <クラス図> <ソースコード> public class 犬 { /** 犬の名前を保持します。*/ private String 名前; /** 犬の名前を取得します。 * @param 名前引数 犬の名前 */ public 犬(String 名前引数) { this.名前 = 名前引数; } /** 鳴くと指示されたら、鳴き声を返却します。 * @return 犬の鳴き声 */ public String 鳴く() { return "ワン"; } } 属性である名前の定義。 クラス名と同じ名前のメソッドはコンストラクタと呼ばれ、インスタンス生成時に実行されます。 鳴くメソッド 犬 名前 呼び出し元に戻す=return 鳴く テキストP14
冷蔵庫をプログラムで表現 見えなくなっている部分のソースプログラムを考えてみましょう。 テキストP15
隠されたコード(野菜クラス) package 野菜グループ; public class 野菜 { private String 名前; private String 収穫日; public 野菜(String 名前引数, String 収穫日引数) { this.名前 = 名前引数; this.収穫日 = 収穫日引数; } public String 名前を公開する() { return this.名前; } public String 収穫日を公開する() { return this.収穫日; } } ① シーケンス図① 野菜クラスのコンストラクタ 引数を属性にセットする。 ② シーケンス図⑦ 属性である収穫日をメソッドの戻り値として返却する。 テキストP16
隠されたコード(センサークラス) package 冷蔵庫グループ; import 野菜グループ.野菜; public class センサー { protected String 賞味期限を調べる(野菜 野菜引数) { String 収穫日 = 野菜引数.収穫日を公開する(); String 日付 = 収穫日.substring(8,10); int day = Integer.parseInt(日付); day += 10; return 収穫日.substring(0,8) + day; } } ③ シーケンス図⑦ 引数で受け取った野菜クラスのインスタンスの「収穫日を公開する」メソッドを呼び出します。 戻り値は、String(文字列型)で収穫日です。 テキストP16
隠されたコード(人間クラス) import java.util.Calendar; import 冷蔵庫グループ.MX2010冷蔵庫; import 冷蔵庫グループ.MX2010野菜室; import 野菜グループ.野菜; public class 人間 { public static void main(String[] args) { 野菜 かぼちゃ = new 野菜("かぼちゃ", "2010/02/05"); MX2010冷蔵庫 冷蔵庫変数 = new MX2010冷蔵庫("三菱電機", "MX-2010", new MX2010野菜室()); 冷蔵庫変数.格納室.入れる(かぼちゃ); 冷蔵庫変数.賞味期限ボタンを押す(); 冷蔵庫変数.格納室.取り出す("かぼちゃ"); } } ④ シーケンス図⑩ 冷蔵庫が持つ格納室(野菜室のインスタンス)の「取り出す」メソッドを呼び出す。 テキストP16
Javaの開発環境 Javaの開発環境にはEclipseを利用するのが一般的です。 • オープンソース • Java以外の開発にも利用可能(C++,PHP,COBOLなど) • コード編集、デバッガ、バージョン管理など標準装備 • 独自にプラグインを開発することで機能拡張が可能 • UML、DB連携など通常開発に必要なプラグインを提供 開発プロセスに合わせた 独自の開発環境を作り上げることが可能
冷蔵庫プログラムを実行 テキストP17
プログラムのデバッグ 変数の中を覗いてみる。 プログラムを途中で止める。 実機デモ
コードのテスト 作成したプログラムはテスト仕様に基づき開発者(テスター)がテスト仕様書通りに動作することを確認します。 ただし、この方法にはいくつかの問題もあります。 • テスト内容、方法が曖昧になる • プログラムの問題の発見が遅れる • バグなどによる回帰テストに時間がかかる • デグレードを見落としやすい 人間が思い込みでテストすることの限界
テストのためのコード Javaの開発では、このような問題を解決するための「プログラムをテストするプログラム」の作成が一般的となりつつあります。 import junit.framework.TestCase;public class 犬Test extends TestCase { /** * ポチという犬の鳴き声テスト */ public void test鳴く01() { 犬 犬変数 = new 犬("ポチ"); String 鳴き声変数 = 犬変数.鳴く(); assertEquals("ワン", 鳴き声変数); } } テストケースをメソッドとして 定義します。 戻り値が期待通りか評価します。 メソッドの呼び出し結果の期待値を設計し プログラムで評価する テキストP18
テストの実行 テスト結果が表示される。 テキストP19 実機デモ
冷蔵庫のテストコード センサークラスの「賞味期限を調べる」メソッドは野菜を引数にもらうことで、賞味期限を計算します。(シーケンス図⑥) テストコードを作成してください。 public class センサーテスト extends TestCase { public void test01() { // テストに使用する野菜オブジェクトを生成 野菜 テスト野菜 = new 野菜(); テスト野菜.生成("テスト野菜", "2009/12/10"); // センサーテスト センサー センサー変数 = new センサー(); String 賞味期限 = センサー変数.賞味期限を調べる(テスト野菜); // 戻り値の評価 assertEquals("2009/12/20", 賞味期限); } } テストコードを考える テキストP20
冷蔵庫のテストコード public class センサーテスト extends TestCase { public void test01() { // テストに使用する野菜オブジェクトを生成 野菜 テスト野菜 = new 野菜("テスト野菜", "2009/12/10"); // センサーテスト センサー センサー変数 = new センサー(); String 賞味期限 = センサー変数.賞味期限を調べる(テスト野菜); // 戻り値の評価 assertEquals("2009/12/20", 賞味期限); } } 野菜のインスタンスを生成 センサーのインスタンスを生成 賞味期限の取得 10日加算した値となっているか評価 テキストP21