2

私は確かにデザインパターンを使用するのが初めてで、ここでどのように進めればよいかわからないようです。JavaFX でカスタム グラフィカル シンボルを作成しています。Parent を拡張し、シンボル クラスに四角形と円を追加して、そのシンボル オブジェクトをシーンに表示するだけです。

このシンボル クラスは、マウス イベントに応答してシンボルを変更するために、setOnMouseEntered などのイベント ハンドラも登録します。私が聞きたいのは、これらすべてのイベント ハンドラーをどこに格納するのが最も合理的かということです。代わりにコントローラークラスに移動する必要があるのか​​ 、それともそのシンボルのビューにのみ影響するため、おそらくシンボルのクラスに保持し、ビューから通信する必要があるもののためにコントローラーを予約する必要があるのか​​ わかりませんモデルへ、またはその逆。これに光を当てることができる人(または良いリソースを教えてくれる人)に感謝します!

4

3 に答える 3

1

あなたの意図はオブジェクトを変更することなので..

私はそれを次のように理解します:

モデル: 表示されたデータを表すすべてのもの。あなたの場合、すべての円を含むシンボルクラス

コントローラー: モデル (シンボル オブジェクト) を何らかの方法で変更する場合、これはコントローラー クラス内のメソッドを使用することによってのみ許可されます。コントローラーはレイヤーです。このレイヤーを介してのみ、変更のためにモデルにアクセスできます

ビュー: モデルを表示するために必要なものはすべて、このパーツに配置できます/配置する必要があります。

したがって、プログラムが現在の選択を「記憶」するかどうか、またはモデルにもそのための変数があるかどうかは、あなた次第です。両方のアプローチが機能するはずだと思います。

1.(モデル内):モデル内の変数の場合、シンボルの選択はコントローラークラスを介して呼び出されるアクションになり(モデルが変更されるため)、モデルが変更されるため、トリガーされますモデルのビューを更新するためのビュー クラス。(ビューはオブザーバー パターンを使用して新しいモデル データを取得し、モデルが変更されるたびに再描画します)

2.(View と Controller を使用する表示プログラムで): ここで選択が「記憶」されている場合、(選択によって) ビューが異なるため、混乱が生じる可能性があると思います。したがって、私は方法1に行くことをお勧めします。

OSR (1 つの単一の責任) についてお読みください。OSR を MVC と組み合わせる方法がわかりません。選択を追加するために「実際のモデル」を拡張する方がよい場合は、モデルが編集オブジェクトから解放されるためです。同じモデルを使用する可能性のある他のクラスでは必要ない場合があります。常にシンボル クラスの編集を許可する場合は、選択変数をモデルに追加する必要はありません。

したがって、マウスの入力とクリックのイベントについては、厳密になるようにしてください。ユーザー入力は常にプログラム自体で処理しますが、モデルの操作として理解できるアクションの場合は、コントローラーでメソッドを呼び出します. これらの MVC ルールに従う必要はありませんが、プロジェクトをより読みやすく保つのに役立ち、すべてが自動的に更新される複数のビューを追加でき、拡張がより簡単になるはずです。

構造について確信が持てない場合、典型的なアプローチは、考えられるすべての解を定義してからそれらを比較することです。シンプルな (理解しやすく、拡張しやすい) 方法を見つけるようにしてください。疎結合、OSR および DRY はそのための良いヒントです。できるだけ頻繁にそれらを適用しようとするのに十分一般的です。ただし、ソリューションが設計パターンに従っているだけで、複雑すぎると「感じる」場合は、単純なクラスまたは別のアプローチを構築することも検討してください。必要以上に複雑なものを構築することがあります。たとえば、Factory および Builder パターンは優れた設計パターンですが、クラスが非常に複雑な構成を必要とするが、複数の異なる構造を必要とせず、他のオブジェクトに関連付けられていない場合は、.. コンストラクター内のコードを含むクラスがより良いアプローチになる可能性があります。

良いリソースとして、OReally の書籍「Head First Design Patterns」と「Head First Object-Oriented Analysis and Design」をお勧めします。出版社のウェズリーの本も良いです。通常、大学の図書館で無料で借りることができます。設計パターンの実際の用途を見つけてみてください。これは、それらを理解するのに大いに役立ち (なぜ役立つのか)、その使用法についてある程度の経験を積むことができます。

于 2013-04-08T13:12:34.807 に答える
1

一般的なアドバイス

抽象的な概念から直接取り組もうとするのではなく、既存のコードで JavaFX に実装されたこれらのパターンの例を見て、そこでどのようにコーディングされているかを確認することをお勧めします。気に入ったパターンが見つかったら、コードでそれらをエミュレートできます。

アプリケーションまたはシーン全体に MVC パターンを適用する大規模なプログラミングと、特定のコントロール タイプにパターンを適用する小規模なプログラミングには違いがあります。あなたの質問は後者のケースにより関連しているように思われるので、この回答では主にそれを考慮します。


JavaFX コントロール - スキン、動作、およびパブリック API

JavaFXの既存のコントロール コードを見てください。の場合Button、次のようになります。

  1. javafx.scene.control.Button - コントロールを操作するためのパブリック API。
  2. javafx.scene.control.skin.ButtonSkin - コントロールのビジュアル ビュー。
  3. javafx.scene.control.behavior.ButtonBehavior - イベント バインディング (キー/マウス イベントなど)。

ButtonBehavior抽象化 API を提供するため、キー、マウス、およびタッチの組み合わせについて、ボタンをさまざまなプラットフォームおよびユーザー固有のイベント マップにバインドできます。

を使用ButtonSkinすると、パブリック API や動作を変更することなく、コントロールの視覚的な実装を完全に入れ替えることができます。

Buttonパブリック API は、ボタンのユーザーがコントロールの実装に対する視覚的または動作上の変更とは無関係にプログラムできる安定した API を提供します。


抽象化を取り除く

スキン API とビヘイビアー API は、ビヘイビアーとルック アンド フィールの実装の詳細を抽象化するのに最適ですが、コントロールの実装者にとって複雑さとオーバーヘッドが追加されます。作成しているコントロールが本当にこの複雑さを必要とするかどうかを検討し、別のより単純なアプローチを評価する必要があります。

最も簡単な方法は、既存のペインを拡張し、すべてのロジックを 1 つの拡張クラスに配置することです (または、コントロール ノードを構築するファクトリ メソッドを提供することさえできます)。抽象化が失われ、単純な実装の互換性と関心の分離の利点が失われますが、実装は非常に単純です。この単純な拡張メカニズムの例は、Oracle Mastering FXML チュートリアルのカスタム コントロールの例です。

私が使用したもう少し洗練されたアプローチは、パブリック API とコントロールの状態情報をカプセル化するクラスと、イベントまたは UI レンダリングを処理する別のスキン クラスを用意することです。標準 JavaFX コントロールの動作/スキン/パブリック API アプローチと同じくらい概念的なオーバーヘッドを追加することなく、JavaFX 固有のロジックとコードを基になるコントロール状態とパブリック API から明確に分離するため、このアプローチが気に入っています。このアプローチを使用したサンプル コードは、このTic-Tac-Toe game にあります。


スキン/ビヘイビアとパブリック API 間の通信

コントロールのパブリック API を含むクラス内でJavaFX プロパティ メカニズムを利用します。プロパティは、コントロールのパブリック API を定義するだけでなく、ReadOnlyWrappersなどの型を介して内部コントロールの状態をカプセル化できます。

スキンはバインディングとリスナーをプロパティに適用できるため、リスナーが起動されると、スキンはそれ自体の自動更新をトリガーして、新しいコントロールの状態を反映できます。コントロールのユーザーは、コントロールの内部状態をリッスンまたはバインドして、状態の変化に応じてアクションを実行できます。このアプローチの例は、ボタンが選択されているかどうかに応じてスキンがトグル ボタンの外観を変更するToggleButton の selected プロパティです。

スキンを作成するときは、コントロールを含むパブリック API への後方参照を使用してスキンと動作を初期化します (たとえばSymbolSkinSymbolBehaviourへの参照を持ちますSymbol)。マウス クリックは、SymbolSkin または SymbolBehavior の mouseclickhandlerによってインターセプトされ、パブリック API で選択されたプロパティをシンボルに切り替えることができます。その後、シンボルで選択されたプロパティへの変更をリッスンするユーザー コードは、そのユーザー コードが厳密でなくても有効になります。シンボルのスキンまたは動作に結合されています。

パブリック APIは、シーン グラフで利用できる単純なノードとしてスキンを返すSymbol単一のメソッドを公開するだけで済みます。getSkin()これにより、スキンと動作の実装は、Symbolパブリック API を使用するクラスの呼び出しから隠されます。


Region を拡張して CSS を利用する

コントロール スキンを拡張することによりRegion、コントロールは CSS を介してスタイル設定可能になります。このアプローチは、コントロールの多くの視覚的側面 (塗りつぶし、背景、境界線、形状など) をJavaFX の豊富な CSS スタイル言語で操作できることを意味するため、強くお勧めします。

これを行うときは、コントロール スキン内のすべてのノードに個別の css スタイル クラスを装備するようにしてください。これにより、コントロールのビジュアル コンポーネントへのフックが提供され、これらのコンポーネントのスタイルを設定するために使用できます。複雑なコンポーネントをスタイリングするこのアプローチのサンプルは、CSS を使用したチャートのスタイリングに関する Oracle チュートリアルです。

Symbol質問のようにさまざまなシンボルを定義するには、単一のコントロールを作成できます。SymbolBehaviourユーザー イベントを処理するための と、SymbolSkin拡張するだけの を定義しますRegion。各シンボル インスタンスには独自のスタイル クラスを割り当てることができ、パブリック シンボル API は、このスタイル クラスをシンボル スキンの領域に設定するコンストラクターまたはファクトリ メソッドを提供できます。css 指定子を使用し-fx-shapeて、svg パス文字列に基づいてシンボルの形状をスタイルします。

css スタイルクラス名自体は、SymbolSkin実装にハードコーディングし、パブリック API の一部として文書化できます (標準コントロールの CSS リファレンス ガイドで行われているように)。

コントロールの既定のスタイルを定義する既定の css テンプレートを使用して、コントロールを出荷します。


FXML に関する考慮事項

調整が必要な多くのサブコントロールで構成される大規模なアプリケーションまたはシーンがある場合、FXMLのようなものを使用してシーンを宣言的な方法で定義できます。これにより、UI デザインを命令型プログラミング コード ベースから切り離すことができ、ビューで命令型コードを書き始める必要がなくなります。

FXML を使用した真の MVC アーキテクチャの場合、FXML ファイルとシーン実装用のバッキング コントローラーだけでなく、シーンのスワップ インとアウトのためのより高度な制御メカニズム、およびおそらく次のようなより高度なイベント処理メソッドも必要になるでしょう。イベントバスとしてですが、それはこの質問の範囲外です。


関連している

問題のドメインをよりよく理解するのに役立つ、わずかに異なるが関連する質問があります ( JavaFX 2.0 - スタイル/テンプレートの既存のコントロール)。

于 2013-04-08T20:21:23.820 に答える
0

意見 :

  • 可能であれば、FXML でバインドを適用しようとしています (双方向のものはまだ実行できません)。
  • 可能であれば、コントローラーを省略しようとします (読み取り専用ステージが適切な候補です)。

コントローラー:

  • モデルをコンストラクターの依存関係として渡します
  • FXMLLoader のコントローラー ファクトリを使用してコントローラーを作成します。
  • 初期化メソッドでバインディングを設定しました

モデル :

  • プロパティと、必要に応じて各プロパティのゲッター/セッターを定義します
  • コードのこの部分でできる限りアプリの動作を定義します

私はまだ JavaFX について学んでおり、その技術全体はまだ成熟していないようです。

http://twittersearch.codeplex.comで JavaFX 2.2 (IDE : IntelliJ IDEA) で書かれた私の小さな PoC を参照してください。

于 2013-11-21T15:53:25.247 に答える