失敗のないファンクションポイント法
受託開発の見積りをすることがある。

このフェーズにおいてもJUDEを利用しています。
以前はモデリングはともかく数字の部分が「KKD(経験・勘・度胸)」だったのだけど、ここ二年ぐらいはファンクションポイントによる見積りにチャレンジしているのです。
※機能規模と関連の薄い部分(導入とか利用者トレーニングとかバッファ)は相変わらずKKDだけど。

  • ヒアリングしたメモをマインドマップにざらーっと書き出しつつ、思いついたことをちょいちょい書き足す
  • マインドマップを見返しながらアクターとユースケースを並べる
  • ざーっとエンティティを見出す
  • CRUDを埋める
  • FP計数
という感じで。

かなり詳細にシステム像をイメージしないと数字が出せないのが難点といえば難点だけど、どんなものを作るかわからないのに見積り数字が出るってのも変といえば変。
それに計数を重ね記録することで、(組織/チームとしての)生産性が見えることがわかったのは収穫だったと思う。

で、

せっかくJUDEでモデリングしているのだから、これを活かしてFP計数が出来ればなお効率もいいだろう、という話し。
すでにやっておられる方がいるので今更感はあったのだけど、これも理解を深めるため&自分都合の使い易さのためということで。

judeユーティリティ

■実行環境
 OS: CentOS 5.2 i386
   libxml2: 2.6.26-2.1.2.6
   ruby: 1.8.5-5.el5_2.3
     rubygems: 1.2.0
     libxml-ruby: 0.8.3 (gem)
   JRE: Sun Java 1.6.0_07
     jruby: 1.1.4
     JUDE-Pro: 5.4

※注意:プログラムの実行結果について作者はなんら責任を持ちませんので悪しからず。

このFP計数ユーティリティにおける前提条件は以下のとおり。
  • データファンクション(以下DF):
    • JUDEモデルでいうと以下のいずれかで、属性が1つ以上あるものをDFとみなす。
       <<entity>>なclass
       ERエンティティ
  • DFのファイルタイプ(ILF/EIF):
    • CRUD図で当該エンティティに対する操作の有無で判断、または手動付与
       Rのみのエンティティ→EIF扱い
       CUDのいずれかが設定されているエンティティ→ILF扱い
  • DFのDET:
    • 非PKな属性の数をDETとみなす
    • JUDE APIを jrubyから使う その1 」で書いたようにIdentifierを使ったモデリングをするようにしているので、主キーにはユーザ識別可能なデータは出てこない、とみなしています
  • DFのRET:
    • 考えられるグループを@retアノテーションで列挙する。列挙された@retアノテーションの数をRETとする。
    • ここでのアノテーションとはjavaのアレではなく、JUDEにタグ付き値がなかったころに独自データを付与するため作ったオレオレ表記。
      モデルの定義中の「@アノテーション名(空白)値」という記述部分を抜き出してデータとします。
    • とあるエンティティが「xxx種別」の値で意味合いを制御するようなモデリングの場合に、
       @ret xxx種別が講師の場合
       @ret xxx種別が講師以外の場合
      のようにエンティティの定義に記述することでRET=2と計数します
  • トランザクショナルファンクション(以下TF)は、JUDEモデルでいうとユースケース1つに対応するものとします。
  • TFのファイルタイプ(EI/EO/EQ):
    • TFのCRUD操作から判断させるか手動で付与します
      • RのみのTF→EO
        CUDあり→EI
      • ユースケースに対して@tfアノテーションで明示指定
         @tf eo
         @tf ei
         @tf eq
    • 結果的にCRUDからはEQが出てこないのだけども、全く加工のない操作って少ないのではないかと考えたから
  • TFのFTR:
    • 当該ユースケースのCRUDで操作対象となっているエンティティの個数をFTRとします
  • TFのDET:
    • ここはまだ方式を確立しかねている
    • 現状は、当該TF(ユースケース)の直下に「FP-」で始まる名前のシーケンス図を書き、アクターが発するメッセージから計数することにしています
      例:「FP-社員情報を登録する」みたいな感じで。
    • DET=メッセージ(=トリガ)+操作の引数の個数+返り値の個数
      • 「操作」に対して返り値は1つしか指定できないので、返り値にclassを指定した場合はその属性の数を返り値の個数とします
      • あるいは、返り値ではなく「操作」の「out」パラメータとして記述します

FP計数周辺に絞った手順

1. モデリング
  • ユースケースをモデリング
    • TFのDET計数用シーケンス図作成
  • ERモデリング(クラス図でもよい)
  • CRUD表作成してユースケースとエンティティの操作を結びつける
2. 計数元ネタファイル作成
  • judeファイルからAPIを使ってFP計数に必要な情報を抽出→中間XMLファイル
    ※linuxの操作例
    % env CLASSPATH=./jude-pro.jar jruby ./jude_export.rb -o 出力中間.xml 入力.jude
    

  • 中間XMLファイルからFP計数→TSVファイルに出力
    ※linuxの操作例
    % ./calc_fp.rb -e cp932 -o 出力.txt 入力中間.xml
    

  • TSVファイルを雛形xlsに貼り付けて集計
    • TSVファイルをテキストエディタで開いてコピー&ペースト
    • アーカイブにFP-hinagata.xlsというxlsブックが入っています。TSV全体をコピペで[ファンクション]シートに貼り付けます
    • もし既存の表をはみ出たら適宜書式をコピーしておきます
3. FP計数
  • 一般システム特性記入
    • [一般システム特性]シートに数字を入れます
    • この辺が参考になります
  • 雛形xlsのピボットテーブル更新
    • [業務単位FP集計]シート
    • [FP概算法]シート
    • [FP試算法]シート
    • FP概算法、FP試算法についてはこの辺を参考にしました。
    • 個人的な感覚では試算法だと数字が離れるなーという印象。rapidに見積もる必要がある、あるいは画面項目を想定するほど情報が揃っていないときは概算法のほうがいいなという感触。


ファンクションポイント法自体については「失敗のないファンクションポイント法 」という本を参考にしています。
この本は項目説明が網羅されているだけでなく例示が勉強になります。300ページちょいの本ですが、約200ページを「計測実習」に割いており非常に具体的で参考になります。