Processingで学ぶ 実践的プログラミング専門課程

第18回 UML(1) ユースケース図

導入

Java言語が登場して間もない頃だったでしょうか。IT系の雑誌広告に大きく宣伝されているRational ROSEなる製品に関心を持ちました。何やらこのソフトウェアツールを用いると、ソフトウェアの開発が効率化するというのです。その頃の私は図と言えばフローチャートしか知りませんでした。その広告にはフローチャートとは異なる不思議な図面が多数掲載されており、それらがどんな役割を果たすものかも分からず、ただ関心と期待を抱いたのでした。

その後、UMLの存在を知って書籍で学び、手描きながら自分のソフトウェア開発に活用してみると大変便利であることに気づきました。UMLは専用のソフトウェアツールを利用しなくとも、十分に有用な、まさにモデリングのための「言語」なのです。今ではUMLが標準的なモデリング言語として定着しています。

今回から数回に渡ってこのUMLの一部を紹介します。

展開

UMLとは

プログラミングを学習する方が基本的な図法として最初に習うのは「フローチャート」でしょう。ソフトウェアを専門としない学部・学科でのカリキュラムでは、プログラムのミクロな動きを表現するために、このフローチャートを指導する程度で手一杯なのではないでしょうか。

しかしながら、現在のGUIのソフトウェア環境で実用的なソフトウェアを作成しようと思えば、フローチャートだけで仕様や要件の図式部分を表現し、整理することは困難です。

そこで、ソフトウェアの仕様を記述するための便利な図法が考案されました。その図法がUML(Unified Modeling Language)です。その仕様はOMGが管理しています。

UMLに用意されている図の種類

UMLで用意されている図(全13種類)のうち代表的なもの9つを以下に列挙します。

  • ユースケース図
  • 相互作用図(シーケンス図、協調図)
  • 静的構造図(クラス図、オブジェクト図)
  • 振る舞い図(ステートチャート図、アクティビティ図)
  • 実装図(コンポーネント図、配置図)

それぞれの図に特徴と役目があり、目的に応じて使い分けます。まずはこの中から最低限これだけ学習すれば、Processingでのソフトウェア開発に役立つだろうというものを取り上げます。

今回がユースケース図、次回はクラス図、そしてその次の回でシーケンス図と状態遷移図を学習する予定です。これだけ知っているだけでも、プログラミング作業をぐんと効率化できます。

ちょっとした注意点

さて、これからUMLの各図を学ぶにあたって、専用の作図ツールやドローツールは必要ありません。業務としてソフトウェア設計部門に所属しているとか、そんなことでないならば、几帳面に図を仕上げようなどと考えないでください。今回掲載するユースケース図はすべて手描きです。学習する際には、作図ツールできれいに図を仕上げるために時間を費やすことよりも、UMLの活用によってコードをより良くすることを優先しましょう。

そのために用意する道具は大きめの紙と鉛筆で十分です。きれいな図を仕上げようと思わず、どんどん図を描いてください。1つだけお勧めするルールは「1つの紙には1つの図」です。A4サイズの紙に1つ図を、周囲に余裕を持たせて描くようにしましょう。後になってメモや変更、修正を描き込みやすくするためです。

ユースケース図とは

ユースケース図は、ソフトウェアを作成するにあたって考えるべき事項を列挙し整理するために役立ちます。そこにどんな仕事があって、どれをソフトウェアに担当させたいのかを考える助けとなります。ソフトウェアを作成中であれば、そのソフトウェアに実装した機能が有意義かどうかを検討し判断する助けとなります。図にする前には曖昧だった要素や相互作用を明確化できるからです。

ユースケース図と、それに関連する語句の定義は次のとおりです。

  • ユースケース図:アクタとシステムのユースケースとの関係を示す図。
  • ユースケース:システムによって実行される機能。
  • システム:これから我々が取り扱う対象のこと。
  • アクタ:ユースケースと直接相互作用する、システムの外側にある実体や役割。人とは限らないが、人を模した記号「スティックマン」を用いる。

参考文献『オブジェクトモデリング表記法ガイド』より(一部文言を変更)

次にユースケース図の例を示します。学校と生徒の関係を、生徒をアクタ、学校をシステムととらえて簡単に示したものです。この他にもたくさんのユースケースが考えられます。試しに書き加えてみましょう。

ユースケース図の例
画像

[作業]学校というシステムに対して生徒が利用するユースケースを図に書き込んでみましょう。

ユースケース図とコード

例えばこんな事例を考えてみます。ある学生が自分の定期テストの合計点と平均点を計算し取得したいとします。この場合のアクタは学生で、自分の定期テストの点(国、数、社、理、英)をシステムに入力します。そして、システムへ合計点を返せと指令すると、合計点を得ます。平均点を返せと指令すると、平均点を得るという具合です。この事例を図にしたものが次の図「学生とテスト成績のユースケース図」てす。

学生とテスト成績のユースケース図
画像

この場合、現実世界にこのような役割のシステムが名称をとって存在しないので、図中では名付けていません。こうして図を書くことで、コードを作成する際にはシステムに対して何かの名前を考える必要があることがわかります。落書きと大差無いように見えますが、こうして図示することで概念を明確化できています。

なお当初、アクターを「生徒」と記述していましたが、⁠学生」という名称の方が良いと思いました。そこで、ユースケース図を書き直しています。こうして変更の履歴を簡単に明確に残すことができるのが、手描き図面の長所です。

ユースケース図をもとにsketchを作る

それではこのユースケース図をもとにsketchを書いてみます。

点数の入力のユースケースを実装する

まずは点数の入力です。アクタにあたるのが次のTestExUsecase.pdeのコードです。TestExUsecase.pde内のtestメソッド内で、ユースケース「点数の入力」を実施しています。

// 点数の入力のユースケースを実装する

Result r = new Result(); // 成績を保持するクラスResultのインスタンス

void setup(){
  test();
}

void test(){
  noLoop();
  println("Test start.");
  //ユースケース「点数の入力」
  assert r.setJapanese(50) == 50 : "Error";
  assert r.setMath(60)     == 60 : "Error";
  assert r.setSocial(70)   == 70 : "Error";
  assert r.setScience(80)  == 80 : "Error";
  assert r.setEnglish(90)  == 90 : "Error";
  println("Test done.");
}

テストの点数を保持するクラスをResultとし、それが書かれたファイルを次のResult.pdeとします。sketch TestExUsecase.pdeResult.pdeはフォルダTestExUsecaseに納めてください。

Result.pde
class Result{
  private int japanese = 0;
  private int math     = 0;
  private int social   = 0;
  private int science  = 0; 
  private int english  = 0;
  
  public int setJapanese(int j){
    japanese = j;
    return j;
  }
  public int getJapanese(){
    return japanese;
  }

  public int setMath(int m){
    math = m;
    return m;
  }
  public int getMath(){
    return math;
  }

  public int setSocial(int v){
    social = v;
    return v;
  }
  public int getSocial(){
    return social;
  }
  
  public int setScience(int v){
    science = v;
    return v;
  }
  public int getScience(){
    return science;
  }
  
  
  public int setEnglish(int e){
    english = e;
    return e;
  }
  public int getEnglish(){
    return english;
  }

}

Resultでは、点数の入力メソッドに加えて、取得メソッドも実装しています。コーディングの方法論として几帳面に考えれば、必要のないコードは作らないほうが良いのですが、後で使うためここで実装を済ませました。それにより点数の取得のユースケースも実装したことになります。このユースケースは、次の「合計点の取得のユースケースを実装する」で使用します。

合計点の取得のユースケースを実装する

合計点を取得するユースケースの実装を行います。合計点を取得するユースケースを、⁠国語の点を取得する」⁠数学の点を取得する」……という個別のユースケースを利用して達成しています。ユースケース間で<<uses>>という関係を持っていると表現できます。

「合計点の取得」ユースケースは「[教科名]の点の取得」ユースケースを使う
画像

sketchは次のTestExUsecase2.pdeのようになります。このスケッチで使用するクラスResultTestExUsecase.pdeに使用したものと同じです。sketchフォルダTestExUsecase2内にResult.pdeのコピーを置いてください。

TestExUsecase2.pde
// 合計点の取得のユースケースを実装する

Result r = new Result(); // 成績を保持するクラスResultのインスタンス

void setup(){
  test();
}

void test(){
  noLoop();
  println("Test start.");
  //ユースケース「点数を入力する」
  setResults(); 
  //ユースケース「合計点を取得する」
  int sum = r.getJapanese() + r.getMath() + r.getSocial()
          + r.getScience() + r.getEnglish();
  assert sum == 350 : "Error";        
  println("Test done.");
}

void setResults(){
  assert r.setJapanese(50) == 50 : "Error";
  assert r.setMath(60)     == 60 : "Error";
  assert r.setSocial(70)   == 70 : "Error";
  assert r.setScience(80)  == 80 : "Error";
  assert r.setEnglish(90)  == 90 : "Error";
}

平均点の取得のユースケースを実装する

平均点の取得のユースケースを実装したsketch TestExUsecase3.pdeを次に示します。このスケッチで使用するクラスResultTestExUsecase.pdeに使用したものと同じです。sketchフォルダTestExUsecase3内にResult.pdeのコピーを置いてください。

TestExUsecase3.pde
// 平均点の取得のユースケースを実装する

Result r = new Result(); // 成績を保持するクラスResultのインスタンス

void setup(){
  test();
}

void test(){
  noLoop();
  println("Test start.");
  //ユースケース「点数を入力する」
  setResults(); 
  //ユースケース「合計点を取得する」
  getSum();
  //ユースケース「平均点を取得する」
  float average = ( r.getJapanese() + r.getMath() + r.getSocial()
                   + r.getScience() + r.getEnglish() ) / 5;
  assert average == 350/5 : "Error";
  println("Test done.");
}

void setResults(){
  assert r.setJapanese(50) == 50 : "Error";
  assert r.setMath(60)     == 60 : "Error";
  assert r.setSocial(70)   == 70 : "Error";
  assert r.setScience(80)  == 80 : "Error";
  assert r.setEnglish(90)  == 90 : "Error";
}

void getSum(){
  int sum = r.getJapanese() + r.getMath() + r.getSocial()
          + r.getScience() + r.getEnglish();
  assert sum == 350 : "Error";        
}

ユースケース図を描きながらコーディングしよう

今回のような大変単純なコーディングをする際にユースケース図を几帳面に描くのは無駄な作業のように感じられるかもしれません。しかしながら、どんな場合でもユースケース図を描きながらコーディングすることをお勧めします。多面的に問題を見直すことになり、問題を整理するきっかけや、無駄なコードを書いている事に気付くきっかけにもなるでしょう。そして、少なくともコーディング期間中は手元において、時々見直せるようにしておきましょう。

演習

演習1(難易度:easy)

合計点と平均点はテストの結果の一部と考えることができます。そう考えるならばこれらはクラスResultに組み込むべきです。クラスResultgetSumメソッドとgetAverageメソッドを実装しましょう。Resultクラスのインスタンスを持ち、メソッドをテストするsketchのファイル名をTestExUsecase4.pdeとしてください。Resultクラスのファイル名はそのままResult.pdeとしましょう。

演習2(難易度:easy)

テレビのユースケース図を描きましょう。このテレビはとても単純で、必要最低限の機能しか持ちません。どんな機能が必要最低限かを考えながら図を作成してください。

まとめ

  • ユースケース図の描き方、使い方を学びました。
  • ユースケース図を描くことで、問題を整理し、多面的に考えることができます。

学習の確認

それぞれの項目で、Aを選択できなければ、本文や演習にもう一度取り組みましょう。

  1. ユースケース図とは何かが理解できましたか?
    1. 理解できた。気持ちよく納得した。
    2. 理解できた。しかし、今ひとつスッキリしない。
    3. 理解できない。
  2. ユースケース図のメリットが理解できましたか?
    1. 理解できた。気持ちよく納得した。
    2. 理解できた。しかし、今ひとつスッキリしない。
    3. 理解できない。

参考文献

  • 『これだけでわかる!初歩のUMLモデリング―基礎から各種テクニックまで第一人者が伝授!! (@ITハイブックス)』⁠萩本順三 著、技術評論社
    • UML入門の良書。絶版であるのが残念。古書をあたってください。
  • 『オブジェクトモデリング表記法ガイド―例題で学ぶUML』⁠MISCOオブジェクト指向研究会 編著、今野睦 監修、プレンティスホール出版⁠
    • 私はUMLをこの書籍で学びました。大変分かりやすく記述されています。同じく絶版本。更に出版社は既に無いようです。これもよろしければ古書をあたってください。

演習解答

  1. 以下のファイルをsketchフォルダTestExUsecase4に納めます。
  2. 私にとって最低限必要な機能を持ったテレビのユースケース図を次に示します。皆さんはどんなユースケースを考えたでしょうか。
テレビのユースケース図
画像

おすすめ記事

記事・ニュース一覧