- PR -

フォームの基本クラスについて

投稿者投稿内容
mover
常連さん
会議室デビュー日: 2004/06/20
投稿数: 47
投稿日時: 2004-06-30 18:37
SolutionAは以下のような構成になっています。

SolutionA
-BaseProject(基本クラス郡)
-ApplProject(アプリクラス郡)

アプリクラスは基本クラスを継承して、作成します。

基本クラスにはフォームの基本クラスもあります。
以下のようにMainMenuを搭載しています。

FormBase
MainMenu1
MenuItem1

で、MenuItem1_Clickイベントで、アプリクラスを生成したいのですが、
この状況だと循環する依存関係が発生してしまい、
BaseProjectからApplProjectを参照できません
(ApplProjectがBaseProjectを参照しているため)。

現状で、MainMenuを共通化しようと考えると上記の方法しか思いつきませんでした。
どなたか良い方法があればアドバイスして頂きたく思っています。

よろしくお願いいたします。

以上。

Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2004-07-01 08:41
 インターフェイスを定義して、各フォームはそのインターフェイスを実装する(ベースクラスが実装し、ベースクラスはMustInherit宣言をして、メソッドは実装しない)。メニューはインターフェイスを通してインスタンスを得る。


?ん?ベースクラスにアブストラクトメソッドを定義してもいいかな?
#そういえば、この辺の設計の明確な判断基準を持ってないなぁ
mover
常連さん
会議室デビュー日: 2004/06/20
投稿数: 47
投稿日時: 2004-07-01 11:47
Jittaさんアドバイスありがとうございます。

色々考察し、テストしてみたのですが、
どうも自分のクラス設計自体に問題があるのではないのか?
と思ってきました--;

現状のクラス構成が以下のようになってるのですが、
アドバイスしていただいた方法で実装可能でしょうか?

[クラス構成]
System.Windows.Forms.Form
↑(継承)
【BaseProject】
FormBase
-MenuItem1_Click:ApplFormのインスタンスを生成
↑(継承)
【ApplProject】
ApplForm

一郎
ぬし
会議室デビュー日: 2002/10/11
投稿数: 1081
投稿日時: 2004-07-01 11:58
MenuItem1はFormBaseのメンバ、つまりBaseProjectに含まれているわけですよね。
それなのにApplProject内のクラスをnewしようしていること自体おかしいですよね。
BaseProjectはApplProject以外では使えない事になるじゃないですか。

(1)本当はMainMenu1がFormBaseのメンバであるべきではない
(2)MenuItem1のClickはApplProjectのクラスをnewするわけではない(意味的に)のにnewしている
(3)BaseProjectとApplProjectの分け方が間違っている

これのどれかでしょうね。

(2)は補足すると、最終的にFormBaseを継承したフォームのMenuItem1のClickでは、ApplProjectのクラスをnewすることになるが、FormBaseのMenuItem1のClickはもっと抽象的な仕事を割り当てられている(例えば「次のページに進む機能」等)。
そうすると、最終的にFormBaseを継承したフォーム側でその機能のメソッドをオーバーライドして処理することになるかと。


(3)があやしいかな。
BaseProjectとはどのような意味を持ったプロジェクトでしょうか?

[ メッセージ編集済み 編集者: 一郎 編集日時 2004-07-01 12:02 ]
nodera
大ベテラン
会議室デビュー日: 2003/09/08
投稿数: 200
投稿日時: 2004-07-01 12:13
MainItem1ってのはFormBaseに含まれるものなんでしょうか。それとも独立したもの?

どちらにしろ、BaseProjectでApplProjectを参照設定しようとするから循環になってしまうので、参照はしないほうがいいです。それにアプリ側のプロジェクトが増えてく度に、BaseProject側に参照してたら面倒ですよね。

じゃあ、どうするかっていうと、リフレクション使ってメニュー側からアプリ側のアセンブリをロードし、インスタンス化してやればいいです。

AssemblyクラスのLoad()メソッドでアセンブリロードして、CreateInstance()でインスタンス化。インスタンスはFormBaseでキャストしてやれば、画面表示できると思いますよ。

ただしメニュー側にアセンブリの名前等を認識させる仕組みが必要ですが。
(メニュー定義ファイルみたいなのつくって、アセンブリ名を記述しておくとか)
mover
常連さん
会議室デビュー日: 2004/06/20
投稿数: 47
投稿日時: 2004-07-01 12:26
一郎さん

早速の返答ありがとうございます。

再度考察したいと思いますが、
やりたいこととしては、全ての画面に同じMainMenuがあるイメージです。
HTMLでいうところのフレームメニュー機能です。

メニューアイテムが10近くあり、全ての画面において同じ動作をさせるので、
Formのベースクラスに実装できれば、全体のコード量が減るなぁと安易に考えていた次第です。

上記のような機能を実装する場合は、どのような設計を心がけると良いですか?
やはりベースクラスにはインターフェースのみ実装し、
ベースクラスを継承した各フォーム側でメソッドを実装しないといけないのでしょうか?

一郎
ぬし
会議室デビュー日: 2002/10/11
投稿数: 1081
投稿日時: 2004-07-01 13:03
>メニューアイテムが10近くあり、全ての画面において同じ動作をさせるので

ということは、すべての画面で現在ApplProjectに含まれる「あるクラス」を使用しているということですよね。
どうしてその「あるクラス」はBaseProjectではなくApplProjectに含まれているんですか?

前回の書き込みにある
「BaseProjectとはどのような意味を持ったプロジェクトでしょうか?」
に通じますが、それぞれのクラスがなぜそのプロジェクトに属しているのかはっきりしていますか?
mover
常連さん
会議室デビュー日: 2004/06/20
投稿数: 47
投稿日時: 2004-07-01 13:37
>メニューアイテムが10近くあり、全ての画面において同じ動作をさせるので

すいません。
当初の投稿と現状がごちゃ混ぜになってました。
当初は、サンプルとして記述してました。

現状は、

Solution
BaseProject(基本クラス:FormBase含む)
AppAProject(アプリA:FormA)
AppBProject(アプリB:FormB)
 …
AppJProject(アプリJ:FormJ)

アプリA〜アプリJは機能ごとにプロジェクト分割しています。
で、アプリA〜アプリJは同じメインメニューがある状態で。
各アプリはそのメニューから、アプリA〜アプリJを起動できます。

その為、BaseProjectでメインメニューを実装したFormBaseを作成しました。
AppAProject〜AppJProjectまではFormBaseを継承し、作成します。

なので、noderaさんのアドバイスが的確なのかと思っています。
>それにアプリ側のプロジェクトが増えてく度に、BaseProject側に参照してたら面倒ですよね。

確かに面倒です^^;

遅ればせながら、noderaさんアドバイスありがとうございます。
現状調べ中です^^;

スキルアップ/キャリアアップ(JOB@IT)