シリーズものなんですけど、その第一回。
「UMLでバグのないプログラムは作成可能なのか?」ってことを考えます。
でも、これをいきなり考えるのはむずかしいので、2段階に分けます。
1段階目はUMLでプログラム自動生成は可能か
2段階目は自動生成したプログラムが、バグなく正しく動作するか
で、1段階目の「自動生成は可能か」です。
これが、可能なら、MDAは可能ってことです。
ある言語(UMLも言語の一種、さいごにLってついてるでしょ)が自動生成可能というためには、その言語で記述されたものが1通りにしか解釈できない場合です。
逆に、これができれば、自動生成できます。
たとえば
Cなどでは、文法規則により、解釈は基本的に1通りしかないので、コンパイラが、これをやってるしJAVAの場合、機械語まではいかないけど、JAVACで中間言語にします。
では、その1通りに解釈されるためには、どういう内容を記述すればいいのか?っていう問題になります。ここでは、手続き型言語に限りましょう。
その場合、たぶん、こんな条件がいります。
1、すべての利用するクラス、スタティックなメソッド、演算子が記述されている
→クラスは、クラスの属性、クラスのメソッド、メソッドの引数
(引数は、型、スコープを含む)を含みます
→スタティックなメソッドは、関数とおんなじようなものなので、
以下、関数とここでは書きます
2、上記クラス、関数、演算子の引数となる、変数、定数がすべて定義されている
3、上記クラス、関数、演算子の使う手順が明確に記述されている
4、手順中、分岐があるとき、条件分岐の条件が記述されている
→分岐先の手順が書かれているってことは、3に含まれている
UMLで表現した場合、1は、クラス図で表現できます。
2をとばして、3にいきましょう。
3を成立させるためには、手順(時系列条件)を記述できないといけません。
これができるのは、動的モデルを表現できる、シーケンス図、ステートチャート図、コラボレーション図になります。
ただ、4の分岐条件を表現するという意味では、シーケンス図のメッセージのところにガード条件を書いて表現するってするのが、早そうですが。。。
この場合、メソッドの手順は表現できるのですが、メッセージとして引き渡す値の処理加工方法について、記述できません。コメントかなんかでいれるしかない??
しょーがないから、これを実現するとすると、Systemっていうもう、ずーっと死なないクラスを考えて、関数や演算子は、そこにメッセージを送って、実現してもらうように書くしかありません。
たとえば、計算するとすると
クラスA System |compute(256*378/2) | |--------------------->|
かりにcomputeメッセージは、引数を計算するとする。
つまり、ここでは256*378/2という計算をさせたい。
でも、シーケンス図では、これらのメッセージの返り値をどう利用して、つぎのメッセージにいかしていくのかっていう表現は、ないと思います。
なので、この部分ができないとだめっていうことになります。
でも、逆に言うと、シーケンス図で、そのようなものを表現できれば、たとえば、
クラスB クラスA System | |compute(256*378/2) | | |--------------------->| | | a=返り値 | |job2(a) |<----------------------|
|<-------------| |
なんていう感じで表現できれば、これは、プログラムに直せます。
事実、書いてみると、
a=256*378/2;
b.job2(a);
ってことを、上の図は表しています。
ただ、こんなことを、やってたら、果てしなく大変です。
絶対プログラムを書いたほうが早いです。
で、ここで言いたいことは、そーいうことではなく、UMLで自動生成するには、
クラス図を描くだけでなく、動的なシーケンス図が必要で、
さらに、シーケンス図の拡張すら必要ではないか?
ということです。
つまり、クラス図っていうのは、結局静的な状態しか表さないので、そこからの自動生成とか、仕様決めっていうのは、結構危険かと、おもいます。
次回のこのシリーズは(続いたら)、その危険性と、その危険性を減らす手だてについてです。
人間の体を考えたとき、いろんな処理をしているのに、べつに複雑なシーケンス図を描いているわけではありません。なのに、シーケンスの手順ができるのは、たんぱく質(酵素)の基質特異性にもとづいているわけですけど、この基質特異性をプログラム上でも利用して、基本的な小さな処理を組み合わせ、柔軟性を持たせるテクニックがあります。
そのお話についてです。