実践:MVCモデル(1)
By S.Nagao
本記事では、プログラミング開発において有用なフレームワークであるMVC(Model-View-Controller)モデルを、 VTK-wrap-Javaプログラミングを通じて、理解します。
これが正しいかどうかは判らないですが、取りあえず、こう考えたら分かりやすかった、という個人的見解に基づいた記事です。
第一回は、Modelを理解しましょう。
(VTK-wrap-Javaとは、C++で書かれた可視化用ライブラリVTKを Java言語で記述できるようラッピングしたものです。 詳しくは、VTK/Java Wrappingをご覧ください。)
Model - アプリケーションの実体
Modelクラスといった場合、動いているプログラムに必要なデータ群というのが、最もピッタリくるでしょうか?
例えば、メッシュファイルを画面に表示するプログラムがあったとします。これを、Prog-Aとします。
この時、Prog-AプログラムのModelクラスについて考えます。
まず、ファイル入力が必要ですね。ReadMeshClassです。このクラスは、ファイルが指定された時、
ファイルを入力してメモリに保存します。vtkDataReaderクラスを宣言します。
ReadMeshClass
private filename;
private vtkDataReader;
次に、メッシュの情報を画面に表示するために、データを表示しやすい形式に変換するFilterMeshClassが必要で、
このクラスは、vtkGeometryFilterクラスを宣言します。
また、ReadMeshClassから継承して作成します。
FilterMeshClass extends ReadMeshClass
private vtkGeometryFilter ;
次に、vtkWindowに表示するためには、
データをvtkActorと結合しなければなりません。
ここで、FilterMeshClassを継承して、MeshDataクラスを作成します。このクラスには、
vtkActorクラスを宣言します。
vtkActorクラスは、 vtkMapperクラスを必要とするので、同様に定義します。
MeshData extends FilterMeshClass
private vtkMapper ;
private vtkActor ;
ここまでで、3つのクラスのツリーができました。
ReadMeshClass、FilterMeshClass、MeshDataです。
これらのクラスを初期化するメソッドinitializeメソッドが必要ですね。
すべてに宣言します。
ここで、FilterMeshClass、MeshDataクラスでは、super.initialize()として、親のメソッドを参照します。
各々のクラスでは、クラスに宣言されたVTKクラスのみを初期化します。
それぞれのクラスに、virtualメソッドを定義して、親を参照するやり方は、
多くのメソッドに拡張できます。
例えば、クラスのパラメタを書き出す、読み込むメソッド、
readParam、writeParamメソッドとして同様に定義できます。
それぞれのクラスのreadParam、wariteParamメソッドでは、
そのクラスに宣言されたクラスに必要なパラメタのみを扱います。
これらを追加すると、各クラスは以下のようになります。
ReadMeshClass
private filename;
private vtkDataReader;
public initialize();
FilterMeshClass extends ReadMeshClass
private vtkGeometryFilter ;
override initialize() {super.initialize(); …}
override readparam() {super.readParam(); …}
override writeparam() {super.writeParam(); …}
MeshData extends FilterMeshClass
private vtkMapper ;
private vtkActor ;
override initialize() {super.initialize(); …}
override readparam() {super.readParam(); …}
override writeparam() {super.writeParam(); …}
VTKライブラリ特有のメソッドも必要です。
VTKのパイプラインを生成するメソッドを、pipelineCreateとでもしましょう。
これも、initializeメソッドと同様に、virtualメソッドとして定義できます。
ReadMeshClass
private filename;
private vtkDataReader;
public initialize();
public pipelineCreate();
public readParam() ;
public writeParam() ;
FilterMeshClass extends ReadMeshClass
private vtkGeometryFilter ;
override initialize() {super.initialize(); …}
override pipelineCreate() {super.pipelineCreate(); …}
override readparam() {super.readParam(); …}
override writeparam() {super.writeParam(); …}
MeshData extends FilterMeshClass
private vtkMapper ;
private vtkActor ;
public addActor();
override initialize() {super.initialize(); …}
override pipelineCreate() {super.pipelineCreate(); …}
override readparam() {super.readParam(); …}
override writeparam() {super.writeParam(); …}
クラスを設計するとき、同じ機能は、同じ名前のメソッドとして、
virtualメソッドとして定義します。
このようにすることで、クラス群の見通しがよくなります。
同じ名前のvirtualメソッドを、拡張ではなく書き直したいときは、
super.xxxx()と参照することをやめ、オーバーライドします。
メソッドを拡張するかしないかは、臨機応変に考えて、設計するほうがいいように思います。 こうしないといけないと言う法則は、有りません。
Javaは、何も宣言しなくともprivateメソッド以外は、virtualメソッドになります。
protectedメソッドをpublicメソッドとしてオーバーライドはできません。
あるクラスを見たとき、注目しているメソッドがオーバーライドされているかどうか分からない場合は、
@overrideタグをつけます。最近のC++には、もう少し考えられた文法があるようです。
今回は、ここまで。
次回は、
実践:MVCモデル(2)です。