まず、クラスについて知っておく必要のある最も重要なことである、サブクラスも常に存在するという基本から始めましょう。スーパークラスの完全なインスタンス。したがって、スーパークラスでフィールド変数を定義する場合、サブクラスのインスタンスを作成すると、このフィールドは常に作成されます。super.getVariable()を使用して、サブクラス内のその変数を取得し、フィールドを再利用できます(クラス変数、フィールド、フラグ、これはオブジェクト指向プログラミングでもすべて同じです)。ただし、外部からsubclassInstance.getVariable()を呼び出すだけでも、同じフィールドを取得できます(サブクラスで変更する必要はありません)。したがって、通常は外部からスーパークラス(抽象クラスを含む!)のフィールドを取得/設定するだけなので、サブクラスで「スーパー」を呼び出す必要はほとんどありません。フィールド変数は常にプライベートとして設定する必要があるため、フィールド変数にアクセスするために「スーパー」を呼び出さないことを常にお勧めします(スーパーでも可能であるため)protected
super.getField()のようなメソッドは、煩わしいですが必要です)。
それでは、データモデルから始めましょう。modelAとmodelBがあります。それらをスーパークラスから、または単にObjectから継承することができます。ただし、Objectからのみ継承する場合は、単純な(Java!)インターフェースを定義し、このインターフェースをmodelAおよびmodelBに実装できます。次に、これら2つのクラスをインターフェイスを介して処理します(これらは両方とも「インターフェイスオブジェクト」であり、一般的に処理できます)。modelAとmodelBで構成されるmodelCがある場合は、modelC内で両方のモデルのインスタンス(「逆参照」とも呼ばれる)を使用するだけで、これ以上のコードは必要ありません。したがって、このモデルはできるだけ小さくシンプルなもの(「Bean」)を選択できます。コンポーネントベースの実装。これは、データ構造の通常の方法です。
GUIまたはフォームがある場合は、見た目が異なります。おそらく多くの共通のコードがあり、このコードを数十の異なるクラスに分割してから、コントローラー/プレゼンタークラスにコンポーネントをまとめたくないでしょう。したがって、すべての共有フィールド/フラグと、それらにアクセスして変更するためのいくつかのメソッドを含む抽象クラスを定義できます。次に、formAとformBからこれらの一般的なメソッドを呼び出し、コードを再利用します。
集合論はあなたに何かを言いますか?AとBの2つの円と、AとBの共通部分があります。抽象クラスは交差であり、サブクラスformAとformBは集合の違いです。正しいプログラムをコーディングすることを学ぶことは...集合論を理解することです。;-)
あなたの言葉で言うと、Foo形式のコードのほとんどは抽象的なスーパークラスFoobarにあり、このクラスはAとBを処理できます。次に、フォームFooとフォームBarを継承し、CはおそらくほとんどFoobarのサブセットのままですが、Cを処理するためにBarにハビリティを追加します。これがセットの違いです。
結局、BarはいつでもFooになることはなく、どちらもFoobarだけになります。あなたはいくつかの新しい共有フィールド/フラグを手に入れましたか?問題ありません。コードをFoobarに移行すると、両方のサブクラスで使用できます。
しかし、ある日、 Fooとは少し異なる3番目のコンポーネントFooTooが必要になった場合はどうでしょうか。問題ありません。FooBarFooを抽象クラスにしてFooBarを拡張し、 FooとFooTooをサブクラスとして作成します。最終結果は、ルートが(通常)抽象クラスであり、リーフが実際のクラスであるクラスツリーになります。この構造により、コードの再利用が最大化されます(クラス名は変更されないため、変更する必要はありません)。クラスFooを使用している他のコード)。
あなたはあなたのフォーム(またはそのプレゼンター)にセッター/ゲッターを実装すると言いましたか?次に、モデルmodelAとmodelBも使用する必要があります(ただし、CはBarでのみ使用され、Fooでは使用されないためmodelCは使用しません)。これらのモデルは、 FooとBarの間でデータを転送するためのラッパーとして使用されます。また、このデータフローは、FooやBarではなく、プレゼンターが制御する必要があります。
だからあなたの質問はこれになります:プレゼンターとは何ですか?実際、プレゼンターはGUIコンポーネントとデータモデルを実行するコードです。一方ではGUIコンポーネントを使用し、もう一方ではデータモデルのゲッター/セッターを使用するのは「フレーム」です。これは、GUIレイヤーとデータレイヤーの2つのレイヤーの間、さらには異なるGUIコンポーネントと異なるデータモデルの間のミドルウェアです。
したがって、通常、それを行う方法は2つしかありません。プレゼンター/コントローラーを使用しない場合と使用する場合です。これがないと、多くのswingコンポーネントコードをプレゼンタークラスにコピーアンドペーストする必要があります。だから何?そうです、スイングコンポーネントを使用するときは、常に( M)VPパターンを使用しているので、別の方法で使用することはできません。
つまり、フレームワークを作成するには、フレームワークを操作するプログラマーに最大限の柔軟性を提供したいので、コンポーネント設計を使用する必要があります。しかし、生産的なシステムはフレームワークと同じではありません。それは多くのフレームワークプログラマーが考えるエラーです。したがって、フレームワークプログラマーが「コンポーネントベースの実装がすべてだ」と言った場合、彼は間違っている可能性があります。彼がフレームワークのコンポーネントをプログラミングしているからといって、これはプレゼンターに対して同じことをする必要があるという意味ではありません。
それで、GUIコンポーネントとGUIプレゼンテーションについて話し始めます。メソッド「include(...)」を使用して、単純なHTMLサイトを取得し、そこから数十のPHPサイトを作成できるため、「できるだけ多くのプレゼンターコンポーネント」を作成することができます。ただし、コンポーネントベースの設計では、コードの保守性が常に向上するとは限りません。1つのクラスだけで何かを行うことができ、それを明確で読みやすいものにすることができれば、10ではなく1つのクラスを使用します。1つのプレゼンター=1つのクラス、またはより具体的には、1つのGUIフレーム/タブ=1つのクラス。
繰り返しになりますが、2つの類似したフレーム/タブがありますが、それらが同じではない場合は、どうすればよいですか?共有コードを抽象クラスに移行し、2つのサブクラスを作成しますよね?いいえ、最初にそれらのGUIが何を共有するかを考える必要があります。彼らは旗を共有しましたか?したがって、フラグを抽象スーパークラスに移動します。しかし、それらは単に異なる動作をしますか?同じクラス内に2つの異なるメソッドを実装するだけで、必要なときにいつでも呼び出すことができます。それが最も重要です。
あなたの言葉でそれを言うと:GUI Pres1はFoo、Bar、A、B、Cをすべて使用します。また、GUI Pres2は、フラグが異なる場合にのみ別のクラスに属します。それ以外の場合は、フラグPres1とフラグPres2を設定し、メソッド内でこのフラグを確認します。によってif(flag="Pres1"){} else if(flag="Pres2"){}
。このように、最大限の柔軟性とコードの再利用性が得られます。
Javaクラスを、柔軟性がなく、再利用できず、変更できないものと見なさないでください。優れたプログラマーであれば、必要に応じて、プログラムの構造を直感的に変更できます。人工的な概念を考える必要はありません。オブジェクト指向プログラミングパターンを理解するだけです。
「コンポーネント」は常に「コンストラクターを持つもの」を意味します。ただし、コンポーネントの代わりにメソッドを使用して何かを行う場合もあります。したがって、誰かが「コンポーネントの設計がすべてだ」と言った場合、彼は「コンストラクターベースの設計がすべてだ」と言います。ただし、コンストラクターを作成するには、フィールド変数/フラグが必要です。フィールド変数がなければ、そのためだけに新しいクラスを作成することはまったく意味がありません。
重要:「コンポーネント」はメソッドではないことを意味します。GUIクラス内で非常に簡単に処理する多くのメソッドを使用することは明らかです。したがって、最終的には、いくつかのメソッドを呼び出すだけです。したがって、コンポーネントとメソッドを混在させないでください。使用するコード行を減らすことがすべてであるため、私は常に強力なメソッド指向の設計を提案します。したがって、できるだけ多くのメソッドを定義します...ただし、できるだけ少ないクラス/コンポーネントも定義します。