asatoの技術的な日常日記

「成長に最大の責任をもつ者は、本人であって組織ではない。自らと組織を成長させるためには何に集中すべきかを、自らに問わなければならない」  非営利組織の経営 - ピーター・ドラッカー

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

要求構造 Part5:さらなる分析

要求構造について考えるシリーズの第5弾。精神が病んできたのでそろそろまとまって欲しい。


今回は、「不思議のダンジョンシリーズ」ではお馴染みの、満腹度を、新たな機能仕様として追加する場合を例として、要求構造の変化について考えたい。


まずは、「要求の構造は階層的である」ということから始めたいと思う。ルートの仕様として「システム仕様」があるとする。
req_structure_root.png


一般的に表すと、こんな感じ。
req_structure_root_general.png

要求の追加、削除、あるいは、変更は、「システム仕様」やさらにその下の階層の仕様に対するオペレーションであると考えられる。分かりやすいように、木構造で図を表現するとこうなる。
req_structure_root_diagram_general.png



したがって、要求(仕様)構造の進化の一つは、木構造の変化であると考えられる。ノード(要求)の追加や削除、ノードの内容の変更などが、要求の木構造を変化させる基本的なオペレーションである。

しかし、まだ不足な点がある。それは、ノード間の依存関係の変化。木構造の表現だと、あるノードがあるノードの親や子ノードである、という関係しか表現していない。

要求構造の進化を考える上で必要なのは次の点。
-(1)仕様や要求の種類:機能的要求、非機能的要求など。
-(2)仕様間の依存関係:依存関係仕様間の依存関係の変化と、仕様間の依存関係の種類。
-(3)要求構造の表現方法:木構造的な表現。マトリックスを用いた表現。


さて、具体的な例に戻って、「満腹度仕様」は、次の図の通り。
req_structure_hungry.png


仕様内の依存関係の分析


まず、この仕様内での依存関係を分析してみよう。前回から言っているように、上記の仕様は、ある選択肢から選ばれたものだと見なせる。
req_structure_hungry_dimenion.png


次に、選択肢が変化したときに、他の次元が変化する必要があるかどうかの観点から、依存関係を抽出する。依存関係を表現するために、DSM (Design Structure Matrix) を用いる。
req_structure_hungry_dsm.png


ステータス画面で満腹度表示仕様


次に、「満腹度仕様」をサブ仕様に分割してさらに分析する。
req_structure_hungry_hungry_status_view_sub_spec.png


req_structure_hungry_status_view_dimension.png


仕様内での依存関係を DSM で表す。この場合は、設計次元は一つしかないので依存関係はなし。
req_structure_hungry_status_view_dsm.png


親仕様との依存関係の分析。
req_structure_hungry_status_view_with_parent_dsm.png


通常画面で満腹度表示仕様


同じようにして「通常画面で満足度を%で表示する」というのもサブ仕様化してみる。基本的にはステータス表示と同じ。
req_structure_hungry_hungry_normal_view_sub_spec.png



req_structure_hungry_normal_view_dimension.png


req_structure_hungry_normal_view_dsm.png


req_structure_hungry_normal_view_with_parent_dsm.png


満腹度低下仕様


次に、「プレイヤーが行動するごとに満腹度は低下する」と「「足踏み」行動は、通常の行動よりも満腹度の低下が大きい」の2つを一つのサブ仕様としてまとめたいと思う。
req_structure_hungry_down.png


次にこのサブ仕様をさらに詳細化してみることにする。
req_structure_hungry_down2.png


仕様の変化の可能性を分析する。
req_structure_hungry_down_dimension.png

変化の可能性の分析を基に、変化の依存関係を分析する。
req_structure_hungry_down_dsm.png


ここでの疑問:値の変化と次元変化の違い
うえの満腹度低下仕様では、直接的な依存だけでなく、間接的な依存に対しても「X」をつけている。たとえば、「プレイヤーの満腹度低下」という次元には、他の次元がすべて依存している。これは、もし「プレイヤーの満腹度低下」の仕様が、「低下あり」から「低下なし」に変わったとしたら、残りの5つは、すべて変化しなければならないため。

ただし、変化は、特殊で、次元自体がなくなる、という変化。たとえば「プレイヤーの満腹度低下」の仕様が、「低下なし」になったら、「満腹度低下値」という次元自体が存在しなくなる。

まとめると、仕様の変化には、少なくとも二つの変化がある。
-(1)値の変化:ドメイン内での値(デシジョン)の変化。たとえば、「満腹度低下値」の値が10から20に変化するようなケース。
-(2)次元の変化:次元自体が存在したり、しなくなってしまうような変化。

2の場合の依存を、階層的な依存という意味で「H」で表すことにする。
req_structure_hungry_down_dsm2.png

興味深いことに、すべて「H」になった。各設計次元について次のような質問を繰り返して依存関係を考えた。

「もし、あの次元の値が変化したら、この次元の値は変化するか?」
-Yes なら X の依存関係。

「もし、あの次元の値が変化したら、他の次元は存在する/しなくなるか?」
-Yes なら H の依存関係。


空腹ペナルティ仕様


最後に、「空腹ペナルティ仕様」のサブ仕様について同様に考えてみよう。
req_structure_hungry_penalty.png

設計次元はこうなる。
req_structure_hungry_penalty_dimension.png


依存関係はこう。
req_structure_hungry_penalty_dsm.png



やり残したことと今後の予定


-(1)仕様間の依存関係の分析:他の仕様を横断するような依存関係の分析は行わなかった。

-(2)要求構造の変化の分析方法:この記事を含む今までの記事では、分析方法はアドホックだった。けれど、そろそろ分析の手順が見えてきた気がする。(1)まず、ラフに仕様を定義する。(2)サブ仕様に分割する。(3)設計空間を分析する。(4)設計空間の分析結果を基に、仕様の依存関係を分析する。

-(3)次元の分類:設計次元として要求を表した場合、いくつかのタイプに分類できると思う。たとえば、なんらかの出力を行うアルゴリズムに関する次元、なんらかの処理を行う次元、アルゴリズムの種類を決める次元、次元の階層化を決める次元などなど。
スポンサーサイト

要求構造 Part4: 局所的変更

「要求構造の変化」を考えるテーマのパート4。

今回は、さらに実例を基に、要求構造の変化を考えたい。

今回は「ダメージの計算方法」を例にしたい。仕様の変更として、計算方法を対象とする。

まず、通常攻撃仕様を考えてみる。基本的にはこんな感じ。
req_structure_attack.png


前回書いたように、仕様は、ある設計空間のおける状態の一つであると考えられる。
現在の「通常攻撃仕様」の設計空間は次の通り。
design_space_attack.png


仕様変化による依存関係はないと考えられる。たとえば、計算式が他のものに変わっても、効果音やダメージを表示することに影響しない。

req_structure_attack_dsm.png


ここで、「通常攻撃仕様の設計空間」におけるサブ仕様での依存関係がないので、「ダメージ値計算」の仕様(設計次元)だけを取り上げて、他の仕様との関係をさらに分析してみようと思う。
req_structure_attack_damage.png


現在の計算式は攻撃力から防御力を引いた値をダメージとしている。これは、「ステータス仕様」に依存していることを意味する。
req_structure_attack_damage_status.png


「ステータス仕様」の設計空間は次の通り。
design_space_status.png


もし、現実的にはありえないとはいえ、「攻撃力」と「防御力」がステータスからなくなってしまったら、現在のダメージ計算式は変更されなければならない。

Cai の Constraint Network を使って表現するならこうなる:

scalar damage: (orig, other) // orig は「攻撃力 - 防御力」
scalar attack_point: (yes, no) // 攻撃力
scalar guard_point: (yes, no) // 防御力

damage = orig => attack_point = yes && guard_point = yes; //「攻撃力 - 防御力」の計算式が有効なのは、「攻撃力」と「防御力」のステータス項目が存在するときのみ



ここまでがまえおき。

さて、ここでダメージの計算式が「攻撃力 - 防御力」から他の計算式に変化したらどうなるのか。

たとえば、ダメージ値を変動させるために、ランダム要素を加えようとしてみる。

ダメージ = 攻撃力 - 防御力 - 1~3の乱数値


req_structure_attack_damage_status2.png


この仕様(要求)の変化の特徴を考察すると以下の通り。
(1)仕様の変化は、他の仕様の変更を要求しない。つまり、仕様間で横断的でない。
(2)仕様の変化は、上位の仕様(例で言えば、「通常攻撃仕様」)の変更を要求しない。
(3)仕様の変化は、他の仕様との依存関係を変更していない。
(4)仕様の変化は、上位の仕様との依存関係を変更していない。


このような特徴を持つ要求(仕様)変化を 局所的な要求(仕様)変化 と呼ぶことにしよう。

まとめ


例を用いて、要求構造の変化の特徴を分析した。

要求の構造を、設計空間の観点から考えた。

局所的な要求(仕様)変化とは、以下を満たすような変化である:
(1)仕様の変化は、他の仕様の変更を要求しない。つまり、仕様間で横断的でない。
(2)仕様の変化は、上位の仕様(例で言えば、「通常攻撃仕様」)の変更を要求しない。
(3)仕様の変化は、他の仕様との依存関係を変更していない。
(4)仕様の変化は、上位の仕様との依存関係を変更していない。


今後の課題



-要求構造変化のパターン化。
-「プロブレムフレーム」との関係性。
-「Design Rules」本における、デザイン階層図との関係性の調査。

要求構造 Part3:仕様依存とタスク依存

前回 は、要求構造の分析ということで、ある仕様の追加が、既存の仕様に構造的にどう影響をするのかを分析した。

今回は、同じ仕様の例をつかって、さらに分析を続けたい。


まずは、前回に例として取り上げた、「クリティカル攻撃仕様」の概要と、その構造。
req_structure_critical.png


この仕様は、以下のサブ仕様から成る。
-キャラクタは、クリティカル率をステータスとして持つ
-クリティカル率を基に,通常攻撃より大きなダメージを与える攻撃を行う
-通常攻撃と異なる効果音を出す
-攻撃ヒット時に「Critical」文字列を表示する
-ステータス画面で、クリティカル率を表示する

サブ仕様間の依存関係を DSM で表すをこんな感じ。
req_structure_critical_dsm.png


DSM からは、少なくとも、次の直接的な依存関係があることが分かる。
req_dep_critical.png


この関係からは、「キャラクタは、クリティカル率をステータスとして持つ 」に依存している二つの仕様を実現するためには、まず、「キャラクタは、クリティカル率をステータスとして持つ 」を実現しなければいけないことが分かる。

「クリティカル率」がなければ、「クリティカル率」を表示するこはできないし、クリティカルかどうかを判断するための計算を行うこともできない。


しかし、残りの二つの仕様はどうか。判断は容易ではない気がする。あえて依存関係を示すなら「クリティカル率を基に,通常攻撃より大きなダメージを与える攻撃を行う」に依存する気がする。
req_dep_critical2.png


DSM を書き直すとこうなる。
req_structure_critical_dsm_revised.png


しかし、これは何の依存か。「クリティカル率を基に,通常攻撃より大きなダメージを与える攻撃を行う」の仕様がどう変化したら、依存している二つの仕様が変化される可能性があるのか。

恐らく、ここで判断が困難になっている理由がいくつかあると思う。
-(1)デザイン次元依存とデザインデシジョン依存の混合

-(2)仕様の依存構造と仕様実現(タスク)依存構造の混合

デザイン次元依存とデザインデシジョン依存の混合


上記のサブ仕様は、それぞれあるデザイン次元から選択されたデシジョンの一つを表すと考えられる。
design_sapce.png


たとえば、「キャラクタは、クリティカル率をステータスとして持つ 」は、あるデザイン次元における一つの選択であると考えられる。たとえば、他のデシジョンとしては「システムは、クリティカルを攻撃を表すためのクリティカル率を持つ(system_level_critical)」が考えられる。

前者の場合は、より詳しく書くなら「各キャラクタは、自身のステータスの一つとして、クリティカル率をもつ。また、クリティカル率は、レベルやその他の要素により加減するとする(chara_level_critical)」ことを意味している。

Cai の Constraint Network を使って表現するならこうなる:

scalar critical_rate_spec: (system_level_critical, chara_level_critical, other)


このように、他のサブ仕様も、なんらかのデザイン次元における一つのデシジョンであると考えられる。

たとえば、「ステータス画面で、クリティカル率を表示する(view_yes)」は、「ステータス画面で、クリティカル率を表示する(view_no)」というデシジョンを持つ。


scalar critical_rate_view: (view_yes, view_no)


ここでは二つのデザイン次元があるとした。
-クリティカル率次元
-クリティカル率表示次元

妥当な組み合わせは、次の通り。
(system_level_critical, view_no)
(chara_level_critical, view_yes)
(chara_level_critical, view_no)
enum.png



これからは、もし、chara_level_critical から system_level_critical に変化したときには、critical_rate_view に影響を与える可能性があることが分かる。

もし、view_yes なら、view_no に変化しなければならない。

一方で、system_level_critical から chara_level_critical は、critical_rate_view に影響を与えない。

また、chara_level_critical の時には、view_yes から view_no あるいは、view_no なら、view_yes の変化は他に影響を与えない。
state_transition.png




仕様の依存構造と仕様実現(タスク)依存構造の混合


ある仕様が変化したとき、それに伴って他の仕様も変化する必要がある。上記の例でいえば、キャラクタレベルのクリティカル率から、システムレベルのクリティカル率の仕様の変化は、ステータス表示仕様の変化を要求する。

これは、依存関係の一つの種類だと思う。


もう一つの種類は、タスクの観点からの依存。つまり、どの順番で仕様を実現していかなければならないのか、の依存。

たとえば、「キャラクタは、クリティカル率をステータスとして持つ」と「ステータス画面で、クリティカル率を表示する」の仕様は、実現の順序関係があると思われる。クリティカル率の仕様が実現された後でないと、表示仕様を実現するタスクに取り掛かれない(直感的には)。

同様に、
-クリティカル率を基に,通常攻撃より大きなダメージを与える攻撃を行う
-通常攻撃と異なる効果音を出す
-攻撃ヒット時に「Critical」文字列を表示する
の三つは、順序関係がある。

後者の二つは、「攻撃結果」を入力として受け取り、クリティカル攻撃だった場合に関係する仕様だと言える。

一方前者は、「攻撃結果」がクリティカル攻撃かどうかを決める仕様だと言える。

まとめ:


考察は以下の通り。

-(1)デザイン次元レベルでの仕様依存の分析:仕様間、あるいは、サブ仕様間の依存関係を分析するためには、デザイン次元を考慮したうえでの分析が有効に思える。

-(1)仕様依存とタスク依存の区別:仕様の変更における依存(仕様レベルの設計空間における状態変化)と、仕様を実現する上でのタスク順序の依存の区別が必要に思える。

参考文献:

Yuanfang Cai

Modularity in Design: Formal Modeling and Automated Analysis

PhD Dissertation.

DL: http://www.cs.virginia.edu/~yc7a/Publications.htm

要求構造 Part2: 横断的要求構造

要求構造を考えるトピック、パート2。

前回と同じく、例としてゲーム(「不思議のダンジョン」風ゲーム)を取りあげる。例だけど、実際に作り中のゲームなのでそれなりに本格的。クラス数は、250~300ぐらい。


今回は、「クリティカル攻撃仕様」を基に考えていきたいと思う。この仕様は、図でしめしているようなサブ仕様で構成される。
req_structure_critical.png


クリティカル攻撃仕様:キャラクタの持つクリティカル率に従い繰り出される強力な攻撃
・キャラクタは、クリティカル率をステータスとして持つ
・通常攻撃より大きなダメージを与える
・通常攻撃と異なる効果音を出す
・攻撃ヒット時に「Critical」文字列を表示する
・ステータス画面で、クリティカル率を表示する


次に、いつものように DSM (Design Structure Matrix) を使って要素間の依存を分析してみる。DSM は、要素間の依存関係を表現するための方法。
req_structure_critical_dsm.png


ここでの難しい点は、「(サブ)仕様間の依存関係をどうやって導き出すのか」という点。

少なくとも二つのアプローチが考えられる。
(1)具体的な実装を考慮(想像)して依存関係を導き出す
(2)具体的な実装を考慮(想像)しないで依存関係を導き出す

上の DSM は、(1)のアプローチを採用して、なるべく実装を考慮しないで依存関係を考えてみた。

依存関係を導き出すための基本的な戦略は、「もしこのサブ仕様が変更になったら、他の仕様の変更を考える必要があるのか」という方法。


ここで注目すべき点は、ソフトウェアの構造的なデザインは、まだ 扱っていないけど、ゲームのデザインは扱っている という点。

5つのサブ仕様からなる「クリティカル攻撃仕様」は、ゲームのある設計空間において決定されたデシジョンでもある。

そもそも、「クリティカル攻撃」をゲームの機能として導入すると決めたこと自体が、ゲームのデザインについての決定。

Cai の Constraint Network を用いて表現するならこうなる:
before:

subspace normal_attack: (yes, no);

after:

subspace normal_attack: (yes, no);
subspace critical_attack: (yes, no);

critical_attack_yes [ // クリティカル攻撃が必要な場合の設計空間
scalar critical_rate: (orig, other)
scalar critical_attack_damage: (orig, other)
scalar critical_effect_sound: (orig, other)
scalar critical_effect_image: (orig, other)
scalar critical_rate_draw: (orig, other)
]


次に、他の仕様との関係を考えてみようと思う。

まずは「クリティカル攻撃仕様」が 追加される前 の「ステータス仕様」。
req_structure_status.png


次に、「クリティカル攻撃仕様」が 追加された後 の「ステータス仕様」。
req_structure_status2.png


「クリティカル攻撃仕様」と「ステータス仕様」を組み合わせて図で表すとこんな感じ。
req_structure_status_critical.png


アスペクト指向プログラミングに慣れてる人向けに言うなら、AspectJ でいうところの「イントロダクション(or inter-type 宣言)」の機能に相当する(ただし、次のようにしてプログラミングするのが良いとはいえない):

public class Status {
private int hp;
private int maxhp;

// その他のフィールドとアクセッサメソッド
}

public aspect CriticalAttackFeature {
privtae int Status.criticalRate; // Status クラスへの criticalRate フィールドの導入。
}


次に、DSM を用いて依存関係を分析してみる。「クリティカル攻撃仕様」が追加される前と後のの「ステータス仕様」のDSM:
before:
req_structure_status_dsm.png


after:
req_structure_status_critical_dsm.png


この場合は簡単なので、「クリティカル攻撃仕様」は、単に「ステータス仕様」から見た ビュー を変更するだけで、何か依存関係を導入するわけではない。

仕様レベルでの DSM はこうなる。
req_structure_status_critical_dsm2.png

「ステータス仕様」が「クリティカル攻撃仕様」に依存しているのは、「クリティカル攻撃仕様」がなくなれば、「ステータス仕様」が変わるため。つまり、『キャラクタのステータスには何がありますか?』と聞かれたときに『クリティカル率があるかないか』。


次に、「クリティカル攻撃仕様」の追加が「ステータス画面表示仕様」にどう影響するのかを同じようにして分析したいと思う。

「ステータス画面表示仕様」は次のような感じ:「あるキーが押されたら、プレイヤーのステータスを表示する」
req_structure_status_view.png


「クリティカル攻撃仕様」と「ステータス画面表示仕様」を組み合わせてみるとこうなる。
req_structure_status_view_critical.png



「クリティカル攻撃仕様」が追加される前と後での「ステータス画面表示仕様」の DSM の変化はこうなる。
before:
req_structure_status_view_dsm.png


「描画レイアウト」は、プレイヤーのどのステータスを表示するかに依存して変わる必要がある。たとえば、命中率や回避率は、ゲームのユーザに直接表示せずに、内部的なパラメータとして持っておくほうがゲームとして面白いかもしれない。そのようなゲームデザイン上の変化があったときには、「描画レイアウト」は影響を受ける。
after:
req_structure_status_view_dsm2.png

「ステータス仕様」の DSM の場合と違って、「クリティカル攻撃仕様」は、仕様内部での依存関係を導入する。「描画レイアウト」は「ステータス画面で、クリティカル率を表示する」に依存する。もし、「クリティカル攻撃仕様」で「ステータス画面で、クリティカル率を表示 しない」に変更されたら、「描画レイアウト」は影響を受ける。


仕様レベルでの依存関係はこう。
req_structure_status_view_critical_dsm2.png



まとめ:
ゲームを例として取り上げて、機能仕様追加が、既存の仕様に与える影響について、DSM を用いて分析した。ある機能の追加(「クリティカル攻撃仕様」)は、他の仕様(「ステータス仕様」「ステータス表示仕様」)に横断的に影響を与えることが分かった。


まとめとしての考察は以下の点:
(1)設計空間は、変化する:要求変化により、設計空間は変化する。新たな設計次元が追加/削除され、ある設計次元におけるドメインも変化する。

(2)ある仕様の追加は、他の仕様に横断的に影響する:「クリティカル攻撃仕様」の追加は、他の機能仕様「ステータス仕様」「ステータス表示仕様」への追加であった。つまり、ある仕様の追加は、他の仕様に横断的に影響する。

(3)「ビュー依存」と「要素間依存」:依存関係には、「ビュー依存」と「要素間依存」がある。ある仕様の導入は、他の仕様のビューに影響するが、要素の依存関係は導入しない場合がある。一方で、ある仕様の導入は、他の仕様の要素との依存関係は導入する。

要求構造

要求レベルでの依存関係などを分析したい。

図は、今作ってるゲーム(「不思議のダンジョン」みたいなやつ)の、ある機能の仕様。

req_structure.png


図からわかるように「マップ表示機能仕様」は、7つの項目からなる。

そのうち6つは、実際に「表示する」という機能を表す。
残りの一つは、「表示する条件」を表す。

ここでの考察は:
-(1)要求は、より小さな項目(要求 or 仕様 or 問題)に分解できる
req_structure2.png


-(2)分解された要求をすべて満たさなければ、分解前の要求を満たしたことにはらない
req_solution.png





次に、項目間の依存関係を DSM (Design Structure Matrix) で示して考えてみようと思う。DSM は、要素間の依存関係を表現するための方法。

req_structure_dsm.png


DSMからは、『「アイテム」の位置は、位置が分かっている場合のみ表示』『「階段」の位置は、位置が分かっている場合のみ表示』の二つは、『「アイテム」「階段」は、プレイヤーの可視範囲に入れば位置が分かるものとする』の仕様に依存(Xマーク)していることが分かる。

一方他の項目については、互いに依存関係はない。


また、ここで「可視範囲」は、横断的な仕様 であることが分かる。「可視範囲」は、他の機能でも必要な仕様。
req_structure3.png

たとえば、「画面描画機能仕様」では、実際にゲーム画面を描画するときに、この「可視範囲」の仕様に依存している。
req_structure4.png


仕様間の依存関係は、したがって、次のようになる:
req_structure_dsm2.png


「可視範囲」の仕様の変更は、他の二つの仕様の変更に影響する。
req_structure_dsm3.png

req_structure_dsm4.png


ここまでのまとめ:
-(1)横断的な仕様が存在する。
-(2)仕様内の依存関係と、仕様外の依存関係がある。


ここまでのまとめ:
-(1)要求は、より小さな項目(要求 or 仕様 or 問題)に分解できる
-(2)分解された要求をすべて満たさなければ、分解前の要求を満たしたことにならない
-(3)横断的な仕様が存在する。
-(4)仕様内の依存関係と、仕様外の依存関係がある。

やり残したこと:
-(1)デザイン or 実装との関係性:上述の議論は、仕様 or 要求レベルの話だった。デザインとはどうかかわってくるのか。

FC2Ad

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。