フォームの継承を避ける必要があるのはなぜですか?


9

VB4を学び、ボタンをフォームにドラッグし、そのボタンをダブルクリックし、魔法のように恵まれたイベントハンドラーにコードを入力したことを覚えています。QBASICから来た私は、「VB」の「V」に興奮しました。ビジュアルデザイナーは、スライスされたパン以来、文字通り最高のものでした。

もちろん、これらすべてをプログラムで行うことはできますが、「V」の魔法は非常に魅力的で、ボタンをドラッグせざるを得ませんでした。私たちはその道を進むように勧められました。

しかし、それから数年前、私はC#と.netフレームワークについて学び始め、自分が知っていると思っていたすべてのものが窓から出て行ったばかりの方法に魅了されました。VB6には、.netで完全に明らかにされた多くの魔法がありInitializeComponentsます。たとえば、コンストラクターとメソッドを見てみましょう。後者では、ツールボックスからドラッグしたすべてのコントロールインスタンス、登録したすべてのイベント、およびデザイナーで設定したプロパティが見つかります。

そして、それは結構です...私は推測します。ただ、私は何が起こっているのかを "所有"していないように感じます。このコードは、デザイナーを介してのみ変更でき、煩わしいことに煩わされます。「OK」と書かれたボタンをあるフォームから別のフォームにコピーするたびに(その兄弟の「キャンセル」とともに)、実際にコードを複製しているのは間違いです。教皇は言っています。

宗教と思想学派はさておき、すべての客観性において、代わりに基本フォームからフォームを派生させて、[OK]ボタン(およびそのすべての友達)を基本フォーム上に置くべきではありませんか?FormBaseから派生するのようなものDialogFormBase。すべてのクラスはすぐに作成されます...コードを入力してください。ボタンは、クラスがどのようにインスタンス化されるかに応じて作成されます(つまり、コンストラクタ列挙引数がどのボタンを作成するかを決定します)、コントロールは、分割パネルとフローレイアウトパネルの配置内にレイアウトされ、次のようにフォームに注入されますContentメインコンテンツパネルに収まります。これは、ASP.netがマスターページとコンテンツプレースホルダーで行うことではありませんか?新しい「マスターページ」が必要になったときにフォームを派生させますが、この新しい「マスターページ」は依然としてベースフォームクラスから派生しているため、アプリケーション全体でビジュアルが一貫しています。

私にとっては、WinFormsのデザイナでこれまでに行った他のどのコードよりもはるかに多くのコードの再利用であり、難しくもありませんでした。また、自分で制御できない200行のメソッドがコードに散らばっていません。私が好きな場所にコメントを付けてください。デザイナーによって上書きされることはありません。:私はそれだけでこのリンクを私にもたらしたものですパターンとアーキテクチャの問題、だと思う共通の機能を共有するWindowsフォームのベストデザイン私は除いて、上のスポットに気づいた、そこに答えは、私は正確に何を示唆しています実行しますが、デザイナーの考慮事項のため、フォームの継承はお勧めません。それは私が得ない部分ですコード構造の考慮事項のため、特にフォームとコントロールの継承に関しては、デザイナーを壊す以外に避けるべき理由はないと思います。

私たちはすべて怠惰になることはできないので、どの部分が欠けていますか?


わかりません。ビジュアルデザイナを使用してすべてのGUIコードを手動で記述してはならないことを意味していますか?
陶酔する

以前の.NETフォームにドラッグされたすべてのオブジェクトを制御するコードはどこにありましたか?
JeffO 2013年

1
私が扱ったレガシーコードから判断すると、@ JeffOは、アドホックインラインSQLとビジネスロジックの間のどこかにあるフォームで正しいと言えます。ポイントは、WinForms .netです。したがって、デザイナーが「悪いコード」や「悪いコーディング習慣」のような臭いでうまく機能してて、構造化を開始すると実際に壊れてしまう場合は、デザイナーを落としてフォームをそれらをクラス(クラス!)として扱います。とにかく、C#でのUIレイヤーのコーディングは、ExtJSでのUIレイヤーのコーディングとどう違うのですか?WinFormsでこれを行うのは "退屈"です。ExtJS UIのコーディングは面倒ですか?
Mathieu Guindon 2013年

別のユーザー、CodeCasterを引用します。イベントハンドラーは、GUIをビジネスロジックに接続するためのものです。ユーザーの名前を入力するテキストボックスと[追加]ボタンがある場合、[追加]ボタンをクリックしても_userRepository.AddUser(UsernameTextbox.Text)を呼び出すだけです。イベントハンドラーにビジネスロジックは必要ありません。stackoverflow.com/questions/8048196/...
ピーターB

@Pieterでは、プレゼンテーションレイヤーにDALの依存関係が含まれていませんか?
Mathieu Guindon 2013年

回答:


9

私は別のパラダイムであなたに反対します。継承よりも構成を優先します。

GUIコードを手動で作成し始め、継承を使用してフォーム間で動作とビジュアルを共有する場合でも、通常のOOP設計と同じ問題が発生します。OK / Cancelボタンを持つDialogFormとグリッドを持つGridFormがあるとします。すべてのダイアログはDialogFormから派生し、すべてのフォームはGridFormのグリッドで派生します。そして、あなたはあなたが両方で形を望むことを発見します。どのように解決しますか?フォームの継承を使用している場合、それを解決する方法はありません。一方、UserControlsを使用している場合は、GridControlをフォームに配置するだけで完了です。また、UserControlでデザイナーを使用できるため、面倒なGUIコードを作成する時間を無駄にする必要がありません。


ベースフォームにはPanel2が修正されたSplitContainerがあり、呼び出されたFlowLayoutPanelを含みBottomPanel、一般的なOk / Cancel / Apply / Close動作をホストしています。Panel1には、SplitContainerが含まれており、Panel1が固定され(共通の「指示」ラベル、またはメニュー、ツールバーなど、上位にあるものをホストするため)、Panel2が保護されたPanelを保持しMainContentます。実際の各実装は、それを埋める方法を決定します。すべてのコンテンツを実装に挿入できます。これは、時間を節約するためにデザイナーが作成したユーザーコントロールにすることができます。ただし、フォーム自体はどうですか?
Mathieu Guindon 2013年

ここでの問題はスケールです。アプリケーションを10個のフォームで使用する場合、単一の共通フォームがあることは大したことではありません。数十または数百のフォームを持つアプリケーションがあると、問題が始まります。次に、共通の部分を持つフォームがありますが、基本フォームを作成するには不十分です。あなたの場合、別のレイアウトや別のボタンを使用したいが、それ以外はすべて同じにしたい場合があります。そして、それが問題の始まりです。
陶酔

2
中途半端なデザインの場合、「スケールの問題」は存在しません。私たちは数百のフォームで作業するプロジェクトを持っています。一貫性と共通の機能を提供するためにフォームの継承を多用していますが、問題は一度もありませんそれに。
メイソンウィーラー

2
@MasonWheeler私は正反対の経験をしました。アプリケーションの1つでフォームの継承を使用しようとしましたが、ベースフォームに少しでも変更を加えるたびに、全体が壊れ、他のすべてのフォームを手動で修正する必要がありました。また、継承されたフォームを使用すると、デザイナーの動作がおかしくなります。
陶酔

1
@ユーフォリック:どのデザイナー?私たちはDelphiを使用しており、そのデザイナーは継承されたフォームでうまく機能します。繰り返しになりますが、優れたデザインがあれば、これらの問題は発生しません。何も計画を立てていない場合は、もちろんすべてが壊れやすく、触れるといつでも壊れますが、それは他のコードと何の違いもありません。
メイソンウィーラー

2

これの多くは、選択したテクノロジースタックに関連しています。

WinFormsとWPFはどちらも.NET UIフレームワークですが、最終目標の達成方法は大きく異なります。特定のパラダイムはテクノロジー間をうまく移動しますが、他のパラダイムはそうではなく、単にすべてのフレームワークに存在することを意図していると感じているからといって、パラダイムを強制しようとするべきではありません。MVVMがWPF / SLに対応しており、MVCがASP.NETでWebFormsなどとは別の概念であるという理由があります。特定のテクノロジは、特定のパラダイムでより適切に機能します。

生成されたコードは通常、DRYの問題から削除する必要があること注意してください。場合によっては適用できますが、多くの場合無視する必要があります。DRYの概念は確かにプレゼンテーションレイヤーの外側に集中する必要がありますが、プレゼンテーションレイヤーで生成されたコードは、作業しているフレームワークの副産物ではありません。慎重。基本フォームを作成して、それから無期限に継承できますか?はい。必要に応じて、毎回新しいフォームにコンポーネントをドラッグアンドドロップできますか?はい。最終的な目標に焦点を当て、潜在的な欠陥を回避し、ダウンストリームのリファクタリングを容易にし、選択したテクノロジースタックの範囲内で作業しながらスケーラビリティを維持します。


0

あなたはできますが、正しくフィールドをカプセル化し、それに応じて移入提供継承を使用します。継承を使用したい場合、私の提案は、ベースフォームとそのフォームに対応するモデルを用意し、派生ごとにフォームとモデルの両方を派生させることです。

はるかに優れた代替策は、関連するコントロールを1つ以上のUserControlコントロールにグループ化することです。必要なのは、関連するデータをその中に入れるための少しのロジックだけです。


0

私はメイソンウィーラーに完全に同意しますが、おそらく3年間で彼自身も彼の考えを変えました。

Delphi実行可能ファイルからWEBに移行するための代替手段を探しています。

今までは、フォームの継承をまだ使用できるため、UNIGUIを選択しました。Delphiには、DartのようなMixinが必要です。これにより、祖先のフォームが少なくなります。しかし、ほとんどのナビゲーション、データモジュールの検証ルールの呼び出し(applyupdates)、SQLフィルタリング基準、クライアントデータセットの検索、すべてが5多分6祖先を形成します。

「MVCを使用すると、Delphiを機能に残しておく方が簡単になる」としても、私は議論として機能しません。人々がOOPを招待したため、すべてがクラス、プロパティ、メソッドです。だから私が必要なのは翻訳者だけです。本当に何の利点も見つけることができませんでした。おそらくそれほど複雑ではないが、毎日のベースで変化するWebサイトにとっては。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.