Java Beans に関する何かが欠けているのではないかと思っています。オブジェクトがコンストラクターでできるだけ多くの初期化を行い、ミューテーターの数を最小限に抑えるのが好きです。Beans はこれに真っ向から反対するようで、一般的に不格好に感じます。オブジェクトを Bean としてビルドしないことで、どの機能を利用できませんか?
5 に答える
あなたは正しい軌道に乗っているように聞こえます。Java Beans の要点を見逃しているのはあなたではなく、Java Beans を悪用しているのは他のプログラマーです。
Java Beans 仕様は、ビジュアル ツールで使用するために設計されました。アプリケーション設計者は、オブジェクトのインスタンスをインタラクティブに構成し、構成された Bean をシリアル化 (またはコードを生成) して、実行時に再構築できるようにするという考えでした。その意図は、実行時に変更されないことでした。
残念ながら、多くの開発者は、アクセサーがカプセル化に違反していることを理解していません。オブジェクトの代わりに構造体を使用します。彼らは、クラスのデータ メンバーに依存する他のクラス (他のパッケージであっても) に問題があるとは考えていません。
もちろん、通常はオブジェクトのインスタンスを構成する必要があります。これは、ある種の構成機能を介して行う必要があるというだけです。これは、依存性注入コンテナー、「BeanBox」スタイルのビジュアル ツール、または手動で作成した JSON、XML、またはプロパティ ファイルの単なる読み取りである可能性があります。重要なのは、実行時にこれらのオブジェクトが事実上不変であるということです。クライアントは操作を呼び出すだけで、プロパティにはアクセスしません。
オブジェクトがコンストラクターでできるだけ多くの初期化を行い、ミューテーターの数を最小限に抑えるのが好きです。
不変オブジェクトを優先することは賢明な選択です。ただし、Bean の利点は、特定のインターフェイスを実装する必要なく、フレームワーク/ツール/ライブラリが実行時にクラスのプロパティを決定できることです。
たとえば、 Person Bean のコレクションがあり、各 Bean に名前、年齢、身長などのプロパティがあるとします。
次のコードを使用して、この Bean のコレクションを (たとえば) 名前で並べ替えることができます。
Collection<Person> myCollection = // initialise and populate the collection
Comparator nameCompare = new BeanComparator("name");
Collections.sort(myCollection, nameCompare);
BeanComparatorクラスは、各オブジェクトから「name」プロパティを抽出する方法を知っています。これは、Java Beans の規則に従っているためです。つまり、次のようなインターフェースを実装する「オーバーヘッド」を回避できます。
interface Nameable {
public String getName();
public void setName(String name);
}
Spring MVC の別の例は、リクエスト URL パラメーターを格納する Bean です。これは、Web コントローラー (Struts では「アクション」と呼ばれます) で次のように定義できます。
public ModelAndView searchUsers(UserSearchCriteria criteria) {
// implementation omitted
}
UserSearchCriteria は JavaBean であると想定されるため、リクエスト URL に などのパラメーターが含まれている場合maxItems=6
、Spring フレームワークは、署名付きのメソッドを呼び出す必要があることを「認識」します。
void setMaxItems(int maxItems);
本質的に、JavaBeans は、クラスのプロパティを実行時に (通常はツールまたはフレームワークによって) 動的に検出できるようにする単純な規則にすぎません。
可変性を最小限に抑えることは良いことだという考えを共有します。すでに指摘したように、JavaBeansの利点は、フレームワークで簡単に処理できることです。
「両方の世界」を最大限に活用するには、 Builderパターンを使用し、JavaBeans標準に準拠するようにBuilderを少し変更するのが良いオプションだと思います。したがって、クラスがJavaBeans標準に準拠する必要があるフレームワーク機能が必要な場合は、実際のクラスの代わりにBuilderを使用できます。
「豆」という言葉を聞くと、ある種の「容器」を見ていると思います。あらゆる種類の JavaBean の考え方は、実行時に追加および操作できるコンポーネントに統一されたインターフェイス規則を提供することです。プレーンな JavaBeans は、この最も単純な例にすぎません。これは、すべてのインターフェースの可能性を提示し、シリアライズ可能です。つまり、Bean のインスタンスを作成し、変更し、保存し、再ロードできます。
ずっと前に、テキスト文字列を表す単純な「データベース」を含み、Bean を使用する「プラグイン アーキテクチャ」を備えた Java エディタを作成しました。Bean ストレージ ビンから Bean をドラッグしてエディターにドロップすることで、エディターに動作を追加できます。一度実行すると、動作 (たとえば、Cntl-T でカーソル位置の文字を転置する) がエディターで自動的に使用できるようになりました。Bean には既知のインターフェースがありました --- コンテナーにそのデータ構造と doSomething() メソッドを要求する方法を知っていました --- そしてコンテナーはクラス ファイルを動的にロードし、オブジェクトをインスタンス化し、そのアクセスをデータベース。
ところで、アクセサーがカプセル化に違反しているとは限りません。ただし、メンバーがあるからといって、そのメンバーにget および set メソッドを提供する必要がないことは事実です。JavaBean 仕様は、これについて少し不明確です。ポイントは、オブジェクトの「コントラクト」に必要なものにゲッターとセッターを提供することです。
内省と熟考が言語に追加され、実際に理解された後、それらの慣習の必要性は幾分減少しました。初期の Java では、メソッドを見つけるための規則が必要でした。