ソフトウェア開発方法論 2 情報システム工学特別講義 ( 渕田 )
開発依頼 研究法人 AA 研究所では 構造立体研究の一部として 以下のような図形管理を行うシステムを発注する 名称 : 図形管理システム 機能 : 以下の機能を持つ 1. 画面の何もないところをクリックすることで 図形を画面上に配置することができる 配置できる図形は円 三角 四角の3つを選択でき 大きさは決まっている 2. 図形の色は 赤 青 緑 などいくつかの中から選択できる 3. マウスクリックで図形を選択することができる 4. 図形を選択した状態で色を選ぶと その図形の色が変わる 5. 図形をダブルクリックすると図形から線分が引かれ ラバーバンドでマウスに追従する この状態で別な図形をクリックすることで2つの図形を線分で接続することができる 6. 線分をクリックすると選択することができる 7. マウスドラッグで各図形を移動することができ 接続線も同時に移動する 8. DELキーを押すことで 選択されている図形や線分を削除することができる 9. 作成した図形データをファイルに保存することができる 10. 保存データを読み込むことができる
開発工程 ( 上流工程 ) 要求分析 ユースケース図 スースケース記述 シナリオ システム分析 オブジェクト シーケンス図 初期クラス図 設計 クラス メソッドの名称 詳細シーケンス図 詳細クラス図
要求分析 何を作るのか?
ユースケース図 システムの内と外を明確に システムの持つ機能を書く
スパイラル開発 すべての機能を詰め込まない 小さい仕様から始める 開発工程を繰り返して大きくしていく ( 破壊と創造 ) 小さくした仕様
ユースケース記述 (1) 名称能動アクターメインフロー例外フロー 起動する ユーザ 1. ユーザが図形管理システムを起動する 2. メインウィンドウが作られる 3. 制御パネルが作られる 4. 制御パネルには図形選択者と色選択者が置かれる 5. 描画キャンバスが作られる 6. 図形保持者が作られる 7. 図形追加者が作られる 8. ウィンドウに制御パネルと描画キャンバスが置かれる 9. ウィンドウが表示される 例外は発生しない
ユースケース記述 (2) 名称能動アクターメインフロー例外フロー 終了する ユーザ 1. ユーザがウィンドウの閉じるボタンを押す 2. システムが終了する 例外は発生しない
ユースケース記述 (3) 名称能動アクターメインフロー例外フロー 図形を追加する ユーザ 1. ユーザがキャンバスでクリックする 2. 図形追加者に通知が行く 3. 図形追加者は図形選択者に現在の図形を尋ねる 4. 図形追加者は色選択者に現在の色を尋ねる 5. 図形追加者は新しい図形を生成し 図形保持者に渡す 6. 図形保持者は渡された図形を保持し 描画キャンバスを再描画する 例外は発生しない
シナリオ 起動する 太朗君は図形を管理するために図形管理システムをダブルクリックした メインウィンドウが生成された さらに制御パネルが生成され その上に図形選択者と色選択者が置かれた 描画キャンバスも生成された 図形追加者と図形保持者が生成された 制御パネルと描画キャンバスがウィンドウにおかれ ウィンドウが表示された 終了する 太朗君は図形管理システムのウィンドウの閉じるボタンを押した 閉じるボタンが押されたことがウィンドウに通知され システムが終了した 図形を追加する 太朗君は描画キャンバス上でマウスをクリックした クリックしたことが図形追加者に通知された 図形追加者は図形選択者に現在の図形を尋ね 次に色選択者に現在の色を尋ね その図形を生成した 図形追加者は図形保持者に生成した図形を渡した 図形保持者は渡された図形を保持し 描画キャンバスを再描画した
システム分析 問題領域から解決領域への橋渡し
オブジェクト抽出 (1) 起動する 太朗君は図形を管理するために図形管理システムをダブルクリックした メインウィンドウが生成された さらに制御パネルが生成され その上に図形選択者と色選択者が置かれた 描画キャンバスも生成された 図形追加者と図形保持者が生成された 制御パネルと描画キャンバスがウィンドウにおかれ ウィンドウが表示された 終了する 太朗君は図形管理システムのウィンドウの閉じるボタンを押した 閉じるボタンが押されたことがウィンドウに通知され システムが終了した 図形を追加する 太朗君は描画キャンバス上でマウスをクリックした クリックしたことが図形追加者に通知された 図形追加者は図形選択者に現在の図形を尋ねたら円だった 次に色選択者に現在の色を尋ねたら赤だった そこで赤い円を生成した 図形追加者は図形保持者に生成した円を渡した 図形保持者は渡された円を保持し 描画キャンバスを再描画した ( 三角と四角の場合も同様 )
オブジェクト抽出 (2) 以下のオブジェクトを抽出した 図形 円 三角 四角 図形管理システム (= メインウィンドウ ) 制御パネル 図形選択者 色選択者 描画キャンバス 図形追加者 図形保持者
シーケンス図の作成 (1) 起動する
シーケンス図の作成 (2) 終了する
シーケンス図の作成 (3) 図形を追加する
初期クラス図の作成 (1) シーケンス図から どのオブジェクトからどのオブジェクトにメッセージが飛ぶかがわかる クラスの決定 多くはオブジェクト = クラス 基底クラスを生成したほうが良い場合がある 円 三角 四角はいずれも図形である 図形 クラスから 円 三角 四角 が派生する
初期クラス図の作成 (2) 保持するわけではないが 間接的に使う
設計 どのように作るのか?
クラス名の決定 図形管理システム :ShapeManagementSystem 制御パネル :ControlPanel 図形選択者 :ShapeSelector 色選択者 :ColorSelector 描画キャンバス :DrawingCanvas 図形追加者 :ShapeAdder 図形保持者 :ShapeHolder 図形 :Shape 円 :Circle 三角 :Triangle 四角 :Rectangle
クラス図の精密化 Java 標準クラスを入れる
詳細シーケンス図の作成 (1) 生成する順序が重要後で使うものを先に生成するどれにどれが必要かは クラス図の関連性から判断できる
詳細シーケンス図の作成 (2)
詳細シーケンス図の作成 (3)
詳細クラス図の作成
スケルトンの作成 詳細クラス図からソースコードのスケルトン ( 骨組み ) を作成できる import java.util.*; import java.awt.*; public class ShapeHolder extends ArrayList<Shape> { public void draw(graphics g){ Shape.java import java.awt.*; public abstract class Shape { protected Color color; protected int px,py; public Shape(Color c,int x,int y){ public abstract void draw(graphics g){ ShapeHolder.java import java.awt.*; public class Triangle extends Shape { public static final int code; public Triangle(Color c,int x,int y); public void draw(graphics g){ Triangle.java
その後のプロセス 実装 ( 後述の例を参照 ) テスト プロトタイプ 1 完成 スパイラル 2 へ 少し拡大した仕様を策定 要求分析 システム分析 設計 実装 テスト プロトタイプ 2 完成 スパイラル 3 へ
課題 スパイラル 2 以降を行え 各スパイラルの仕様として何を入れるかは各自で ただし 最低でも 1 つの機能は増やすこと 上流工程のプロダクトをワードに添付して提出すること 最低でもスパイラル 2 までは行うこと スパイラル 3 以降もあれば加点する 提出方法 作成したワード文書をメールで渕田まで送付すること fuchida@ibe.kagoshima-u.ac.jp 提出期限 :2017 年 7 月 31 日 ( 月 ) 24:00
終了
プロトタイプ 1 の実装コード例 ShapeManagementSystem.java ControlPanel.java ShapeSelector.java ColorSelector.java DrawingCanvas.java ShapeAdder.java ShapeHolder.java Shape.java Circle.java Triangle.java Rectangle.java
import java.awt.*; import java.awt.event.*; public class ShapeManagementSystem extends Frame implements WindowListener { // 生成する public ShapeManagementSystem(){ super( 図形管理システム [ プロトタイプ 1]"); setsize(500,500); setlocation(100,30); ControlPanel cp=new ControlPanel(); ShapeSelector ss=cp.getshapeselector(); ColorSelector cs=cp.getcolorselector(); ShapeHolder sh=new ShapeHolder(); ShapeAdder sa=new ShapeAdder(ss,cs,sh); DrawingCanvas dc=new DrawingCanvas(sa,sh); add(cp,borderlayout.north); add(dc); addwindowlistener(this); // ウィンドウリスナー public void windowactivated(windowevent ev){ public void windowdeactivated(windowevent ev){ public void windowopened(windowevent ev){ public void windowclosing(windowevent ev){ System.exit(0); public void windowclosed(windowevent ev){ public void windowiconified(windowevent ev){ public void windowdeiconified(windowevent ev){ // メイン public static void main(string[] args){ (new ShapeManagementSystem()).setVisible(true);
import java.awt.*; public class ControlPanel extends Panel { private ShapeSelector ss; private ColorSelector cs; // 生成する public ControlPanel(){ add(ss=new ShapeSelector()); add(cs=new ColorSelector()); // 図形選択者を得る public ShapeSelector getshapeselector(){ return ss; import java.awt.*; public abstract class Shape { protected Color color; protected int px,py; // 生成 public Shape(Color c,int x,int y){ color=c; px=x; py=y; // 描画する public abstract void draw(graphics g); // 色選択者を得る public ColorSelector getcolorselector(){ return cs; import java.awt.*; public class ShapeSelector extends Choice { // 生成する public ShapeSelector(){ add(" 円 "); add(" 三角 "); add(" 四角 "); // 形状を問い合わせる public int queryshape(){ return getselectedindex(); import java.awt.*; import java.util.*; public class ShapeHolder extends ArrayList<Shape> { // すべての図形を描画する public void draw(graphics g){ for(shape s:this) s.draw(g);
import java.awt.*; import java.awt.event.*; public class DrawingCanvas extends Canvas implements MouseListener { private ShapeAdder adder; private ShapeHolder holder; // 生成する public DrawingCanvas(ShapeAdder sa,shapeholder sh){ adder=sa; holder=sh; addmouselistener(this); // 描画する public void paint(graphics g){ holder.draw(g); // マウスリスナー public void mousepressed(mouseevent ev){ public void mousereleased(mouseevent ev){ public void mouseclicked(mouseevent ev){ adder.addshape(ev.getx(),ev.gety()); repaint(); public void mouseentered(mouseevent ev){ public void mouseexited(mouseevent ev){
import java.awt.*; public class ColorSelector extends Choice { private static String[] color_names={ " 赤 "," 緑 "," 青 "," 黒 "," ピンク "," シアン "," マゼンタ " ; private static Color[] colors={ Color.red,Color.green,Color.blue,Color.black,Color.pink,Color.cyan,Color.magenta ; // 生成する public ColorSelector(){ for(int i=0;i<color_names.length;i++) add(color_names[i]); // 色を問い合わせる public Color querycolor(){ String it=getselecteditem(); for(int i=0;i<colors.length;i++){ if(it.equals(color_names[i])) return colors[i]; return Color.black;
import java.awt.*; public class ShapeAdder { private ShapeSelector sel_shape; private ColorSelector sel_color; private ShapeHolder holder; // 生成する public ShapeAdder(ShapeSelector ss,colorselector cs,shapeholder sh){ sel_shape=ss; sel_color=cs; holder=sh; // 図形の追加 public void addshape(int x,int y){ int s=sel_shape.queryshape(); Color c=sel_color.querycolor(); Shape sh=null; switch(s){ case Circle.code: sh=new Circle(c,x,y); break; case Triangle.code: sh=new Triangle(c,x,y); break; case Rectangle.code: sh=new Rectangle(c,x,y); break; holder.add(sh);
import java.awt.*; public class Circle extends Shape { public static final int code=0; // 生成する public Circle(Color c,int x,int y){ super(c,x,y); import java.awt.*; public class Triangle extends Shape { public static final int code=1; // 生成する public Triangle(Color c,int x,int y){ super(c,x,y); // 描画する public void draw(graphics g){ g.setcolor(color); g.filloval(px-20,py-20,40,40); import java.awt.*; public class Rectangle extends Shape { public static final int code=2; // 生成する public Rectangle(Color c,int x,int y){ super(c,x,y); // 描画する public void draw(graphics g){ g.setcolor(color); g.fillrect(px-20,py-20,40,40); // 描画する public void draw(graphics g){ int[] vx={ px, px-20,px+20 ; int[] vy={ py-20,py+20,py+20 ; g.setcolor(color); g.fillpolygon(vx,vy,3);