3章 CommonMPの要素モデルを作成する
3.3 要素モデル スタブを作成する(その1)
@ 各サブルーチンをコーディング/コンパイルの後、サブルーチン単体で動作を確認する。
A @で作成したサブルーチンに対して、テスト(単体テスト)が一通り完了した所で、それらを組み合わせて全体動作を確認(組み合わせテスト)する。
@ フレームワークが提供する親クラスの派生クラスを制作し、必要なメソッドはスタブ(空のメソッド)として実装する。
A スタブが完成した段階で フレームワーク内に組み込んで動作させてみる。
B 上記Aの動作が行われることを確認した後、スタブ内に 順次本番処理を実装して、次第に完成させていく。
この方法を取ると、全体の動きの中で開発部分を絶えず確認することになるため、フレームワークの動作と相容れないコードは実装されません。
(雑談)
日本文化の(強さの)秘密の一つとして「型(カタ)」が有るそうです。 礼儀、作法、武道など 色々な所で「型」が存在しますが、「型」を勉強すると、ゼロからの出発よりも効率的に対処でき、さらに、新しい状況に接しても対応できる「型」を探すことで (完璧とは言わないまでも)対応可能となるそうです。 確かに、「型」を知らないで「生花」を行うよりも、「型」を少しでも知っている方が より整った「生花」になるでしょう。 新しい事を勉強をする場合、ゼロから独自に行なうと かなり努力しても 『可』止まりですが、「型」を勉強すると 『良』を取ることは比較的容易に行えるでしょう。 「型」の習熟度が進めば『優』取得もそれほど難しくは無いと思います。 しかしながら『超優』となる為には、習熟した「型」を壊すことが必要となることがあります。(成功すれば、新しく成功した事例が次の「型」となる) 但し、「型」の否定は、一度「型」に習熟してから行うべきです。
ところで、CommonMPも 色々な要素モデルを接続し・連動させて動作させる為の 一つの「型」を提供します。 「型にはめる」とは フレームワーク内で動作する要素モデルの「親」クラスを提供することに他なりません。
先ず、スタブの制作から行なっていきます。
CommonMPでは スタブ制作は2種類の方法が用意されています。
最初の方法は、CommonMPプログラミング開発環境をインストールし インストールされた開発環境のウイザードを利用する方法です。(開発環境はCommonMP本体とは別に、CommonMPホームページからダウンロードして 自PCにインストールします。)
二番目の方法は、CommonMP本体と供にダウンロードされている要素モデルの型紙:「MyModel」
をコピーして、名称等を変更して作成する方法です。
ここでは、学習の為 敢えて二番目の方法で制作を行なってみます。
CommonMP上で動作する
要素モデルはDLLの形で提供されますが、DLL内に作成すべきクラスを下図に整理します。
第2章でも示しましたように、CommonMP要素モデルDLLには 1つのFactoryクラスが必要です。 一つの要素モデルに関連するクラスとしては、「要素モデル本体」、「演算データクラス」、「プロパティデータクラス」、「初期化データクラス」が必要です。
(第2章では「要素モデル本体」と「プロパティデータクラス」だけでしたが、CommonMPではそれに「演算データクラス」と「初期化データクラス」が追加されています。「初期化データクラス」は、モデル初期化時に与える情報を格納するクラスです。「演算データクラス」は、要素モデル内の情報を全て格納しておく為のクラスです。)
「要素モデル」クラスと「演算データ」クラスは必ず独自の派生クラスを作成する必要があります。 「プロパティデータ」クラスと「初期化データ」クラスは親クラスをそのまま使用することも可能です。 「MyModel」プロジェクトでは「プロパティデータ」クラスと「初期化データ」クラスは親クラスを使用します。
(補足)
独自要素モデル用DLLを作成する上で、CommonMP内でユニークにする必要がある事柄(1) DLL ファイル名
(2) ファクトリーID
(3) namespace 名
これから、要素モデル用のDLLを作成していきます。
(手順:1)プロジェクトの作成
1.1 ディレクトリ「\CommonMP\Source\HYMCO\OptionImpl\」下の「MyModel」フォルダーを複製し、名称を「MyExerciseModel」とします。
↓
1.2 今作成した「MyExerciseModel」内の「MyModel.csproj」の名称を「MyExerciseModel.csproj」に変更し、Microsoft
Visual C# から MyExerciseModel.csproj を開きます。(ソリューションからではなくて、単体プロジェクトを開きます。ディバッグソリューションには未だ追加しないで下さい。)
開いたプロジェクトを一度リビルドし、ビルドでエラーが無いことを確認しておきます。
この時、ソリューション保存を問われますので、そのまま保存します。
1.3 ここで、ソリューション内の namespace
名を全て変更します。
Microsoft Visual C#
「編集」−「検索と置換」−「クイック置換」 を選択します。
表示されたダイアローグを用いて、namespace 名 を置換します。
本例では namespace
名「CommonMP.HYMCO.OptionImpl.MyModelLIB」 を
「CommonMP.HYMCO.OptionImpl.MyExerciseModelLIB」 とします。
検索対象を必ず「ソリューション全体」とします。(プロジェクト内の一部だけが変更されると、ビルドした時にコンパイルエラーとなります) 変更後、リビルドしてエラーが発生しないことを確認しておきます。
1.4 プロジェクトのプロパティ設定画面を開きます。
この画面上で、アセンブリ名(DLL名)と、規定名前空間(namespace
名)を変更します。
・アセンブリ名は 「MyModel」→「MyExerciseModelDLL」に変更します。
・namespace
名は 先に変更した 「CommonMP.HYMCO.OptionImpl.MyExerciseModelLIB」
に変更します。(必ず同じ名称にしてください。)
変更し終わったらリビルドしてエラーが発生しないことを確認します。(何か変更を行ったら、致命的ミスをしていないことを毎回確認しています。)
今回は 下図のようなエラーが出ました。
これは、DLL名称が変更となったために起こったエラーです。
そこで、プロジェクトのプロパティ設定画面の「ビルドイベント」タグを開き「ビルド後に実行するコマンドライン」内に記述されている内容を全て削除します。(ビルドイベントについては
いずれ説明しますので、ここでは空白にしておいて下さい。)
ここで、再度リビルドすると エラーは消えました。
要素モデル用のDLLが作成した事を確認するため、「\CommonMP\Source\HYMCO\OptionImpl\MyExerciseModel\bin\Release」下を見てみます。 すると、ここに、今回作成する「MyExerciseModelDLL.dll」が生成されています。
以上で、要素モデル用DLLのプロジェクトが作成されました。
(手順2:ファクトリークラスの変更)
手順2では、ファクトリークラスを整備します。 namespace
名がユニークになったので コピー元のMyModelプロジェクト内に含まれているFactoryと、今回作成したMyExerciseModelDLL 内のFactory名称が同じであっても、CommonMP側では区別できますが、独自の名前のクラスにしたいので、Factoryクラス名を変更します。
CommonMPでは基本的に クラス名とそれを記述したファイル名は同一にする事になっているので、最初にFactoryクラスのファイル名称を変更します。
ソリューションエクスプローラーのFactoryクラスを選択し、マウスを右クリックして表示されたポップアップメニューから「名前の変更」を選択します。
ここで、ファイル名称を「MyModelFactory.cs」から「MyExerciseFactory.cs」に変更します。
この時、下図のように、自動的にクラス名称も変更するか否かを問い合わせるダイアローグが表示される事があります。この時には、「はい」を選択します。
すると、自動的にソース内に記述されているソース名が変更されます。
もしも、自動修正が行われない時には、下図のようにクラス定義場所で名称を選択し、マウス右クリックしてポップアップメニューを表示させ、「リファクタ」−「名前の変更」を選択します。
表示されたダイアローグ上で新しい名称を設定し「OK」ボタンを押下します。
これで、ファクトリー名称が変更されました。
第2章で DLLが読み込まれた時にFactoryインスタンスをメインプログラム側で取得するための特別な記述を追加しました。 CommonMPも同様の仕組みを組み込みます。
CommonMPでは、namespace CommonMP.HYMCO._SYSTEM_ に囲まれた部分がそれにあたります。 この部分は namespace
名、class 名、メソッド名を変更しないで下さい。
リファクタリーングした事で、Factoryクラスを new
する箇所は自動的に変更されていました。
2章では
Factoryを識別する為にID番号をつけました。 CommonMPでは識別子をユニークにします。
FactoryクラスのIDは CreateFactoryIDで生成します。(下図)
ここで、直接 識別子を生成しても良いのですが、Factoryの識別子は 色々な所で使用されます。 人手でコーディングすると 大文字小文字の間違いやスペルミス等が発生する可能性があるので、何回も使用する文字列等は MyExerciseModelDefineというDefineクラスを準備し、そのDefineクラス内で定義しておくことにします。 すると コーディング中に Defineクラス名.定義名称の一部を記述すると コーディングすべき候補が表示されるので、それを選ぶだけで 単純なキーボード打ち間違いを回避できます。(下図)
(
↑ 一部をタイプすると、候補が表示されるので、それを選べは全てを人手で打ち込む必要がない)
|
|
|
(↓比較
↓ ディファインクラスを使用しない場合には、全てを 完全に人手で打ち込む必要がある)
また、Defineクラス内で定義しておくと、定義値を変更する場合でも、Defineクラス内部のソースを一箇所変更するだけで、全定義を変更することができるので、メインテナンス性が上がります。 Defineクラスの制作は必須ではありませんが、先に述べたような理由から CommonMPではDefineクラスを使用しています。
Defineクラス名を型紙の名称から変更します。(Factoryクラスと同じようにしてクラス名を「MyModelDefine」から「MyExerciseModelDefine」に変更します。)
内部で、「MODEL_FACTORY_LIB_ID」で定義されたモデルファクトリ識別子を ユニークな名称にします。 モデルファクトリ識別子は CommonMP内でユニークな必要があるので、ここでは、「namespace
名+名称」としています。
HySIDクラスは、CommonMPでは、識別子が必要な時に使用するクラスで、内部に定義された文字列でユニーク性を判別します。 概念的にIDで識別できるものは全て HySIDクラスを用います。(HySIDクラスの親クラスはHySIdentifierです)
(雑談)
既に、CommonMPでは、全体を「HYSSOP」、計算部分を「HYMCO」とに分けている事を説明しました。 HYSSOP内で制作されたクラスには「HyS」の接頭語を、「HYMCO」内で制作されたクラスには「Mc」の接頭語をつけています。 クラス名に統一した接頭語を付けることで C#が提供するクラスか、CommonMPが提供するクラスかを区別しています。 提供者が簡単に区別できることで、クラスの使用方法等を調べる際、何処を調べればよいかが簡単に解ります。
ついでに、Defineクラス内で定義されている以下の定義も変更しておきます。
定義 MY_MODEL_KIND はクラスの種類を区別するための定義で、 先ずは 定義名を変更します。 本例では、DynamicWaveモデルを作成するため、 「MY_MODEL_KIND」 を 「MY_DYNAMIC_MODEL_KIND」に変更します。(下図の通り、「リファクタ」−「名称の変更」で
行います)
また、定義された文字列の中身を
”MyModel”から”MyDynamicWaveModel”に変更します。
次に モデル名称の定義を 「MY_MODEL_NAME」 から 「MY_DYNAMIC_WAVE_MODEL_NAME」 に変更します。(MY_MODEL_KINDの場合と同様にリファクタリングを行います)
ここで、
HySString の()内の”Properties.MyModelResources.MODEL_MY_MODEL_NAME
”は 2か国語対応用の定義です。 本例では日本語で制作するので直接日本語を代入するようにします。
HySObjectKind クラスは、クラスのカテゴリー区分を行う為に使用するクラスです。 HySIDクラスは 個々のインスタンスを区別するために利用しますが、HySObjectKind クラスは 個々を区別するためではなく、同じ種類をひと纏りにして区別するために使用します。
また、 HySString は文字列を扱うクラスです。
(雑談)
HySString クラスは、文字列を扱うクラスです。 C#では文字列を取り扱う string クラスがありますが、 CommonMPでは独自の HySString クラスを用いています。 CommonMP開発開始当時、 Linux版で動作させる為に C++へ移植する可能性を排除できなかったので、敢えて文字列を扱うクラスを独自に作成しました。 C#の提供する文字列クラス:string を使用しないで、独自クラス:HySString を使用すれば、C#→C++への移植時に HySString 内部のみを変更するだけで、CommonMP全体を修正する必要がなくなります。(オブジェクト指向による隠蔽の効果) 但し、使用する時に文字列を一々 new HySString() する必要が有り、利便性に劣るため、C++への移植の可能性が低くなった現在では C# が提供する string クラスもそのまま利用しています。
Factoryクラスの修正はひとまず此処までにしておいて、モデル本体名称を修正します。
(手順3:モデルクラス名称の変更)
Factoryクラスと同様に、クラス本体のクラス名とファイル名を変更します。(Factoryの場合と同様に
Microsoft Visual C#
のリファクタリング機能を活用します)
<変更対象>
・モデル本体クラス : MyModel → MyDynamicWaveModel
・演算データクラス : MyCalInfo → MyDynamicWaveCalInfo
↓ (修正)
ここで、再度リビルドして コンパイルエラーが無い事を確認します。
(手順4:CommonMP要素モデル用ソリューションへ追加)
namespace
名称の変更、 クラス名の変更が終わったので、CommonMP要素モデル開発用ソリューションに登録します。
MyExerciseModelプロジェクトを閉じて、要素モデル開発用ソリューションを開きます。
(Microsoft
Visual C# から
\CommonMP\Source\HYMCO\OptionImpl\ModelDeveloperExpressEdition\TestModelDeveloperMainExp.sln
を開きます。)
ソリューションを選択し、マウスを右クリックしてポップアップメニューの「追加」−「既存のプロジェクト」を選択します。
表示されたダイアローグで、製作中の「MyExerciseModel」
を選択します。
ソリューションに「MyExerciseModel」が追加されたので、ディバッグ用のメインプログラム「TestModelDeveloperMainExp」の参照設定に 「MyExerciseModel」を追加します。(
TestModelDeveloperMainExp の参照設定を選択し、ポップアップメニューの「参照追加」を選択します。)
表示されたダイアローグから、「MyExerciseModel」を選択して、参照を追加します。
参照設定が終了したとこで、要素モデル開発用のCommonMPをディバッグ起動します。 CommonMPが立ち上がったところで、\CommonMP\Source\HYMCO\OptionImpl\ModelDeveloperExpressEdition\bin\Debug\
下を調べます。 MyExerciseModelDLL.dll
が存在していれば、参照設定が終了し、開発する「MyExerciseModel」が Microsoft Visual C#
上から ディバッグできるようになった事を示します。
初版:2013/06/15 |