0

組織と使いやすさ、および 100,000 程度のアイテムへのスケーラビリティに重点を置いて、Java で組み込み (ウェブではなく、エンタープライズではない) コンテンツ管理システムを作成しようとしています。ユーザーとシステムは、検索を可能にするために、一意のリソースに関連付けることができるメタデータ項目を作成および定義できる必要があります。

たとえば、文字列値を取るタグ「ProjectName」を作成できます。次に、一連のリソースを「Take Over the World」または「Fix My Car」プロジェクトに属するものとしてタグ付けできます。タグは厳密に型指定されているため、タグには単一または複数の文字列、整数、倍精度などを格納できます。各タグ タイプには、編集を許可するフォーマッタと入力バリデータが必要です。

スケーラビリティを考慮して、ストレージ モデルを GUI から抽象化することが重要であると判断しました。これを行う明白な方法は、リソースごとにデータ アクセス オブジェクト (DAO) を使用することです。ただし、可変数のタグをサポートし、適切にスケーリングする DAO を作成する方法がわかりません。

問題は、リソースがタプル (表形式の表示/並べ替え/フィルタリング用) と (TagName,TagValue) マップの両方として動作する必要があることです。GUI モデルは、GUI の更新ごとにこれらのメソッドを潜在的に何千回も呼び出す可能性があるため、インデックス作成のいくつかの概念により、すべてがより適切に機能します。残念ながら、タグの種類が複数あるということは、すべてをジェネリック オブジェクトとして返して、"TagValue instanceof Type" 条件をめちゃくちゃにしない限り、扱いにくいということです。

リフレクションと Apache の DynaBeans の使用を検討しましたが、これを GUI モデルで動作するようにコーディングするのは面倒で扱いにくいように見えます。これを行うより良い方法はありますか?いくつかのライブラリまたはデザインパターン?

だから、私の質問は、より良い方法はありますか? このすべてを単純にするライブラリまたはデザインパターンはありますか?

4

3 に答える 3

1

あなたの質問から、「リソース」は、それに関連付けられたいくつかの「タグ」エンティティを持つシステム内のエンティティであると思います。私の仮定が正しければ、これがバニラの DAO インターフェイスです。これがあなたの考えかどうか教えてください。

public interface ResourceDAO {
    void store(Resource resource);
    void remove(Resource resource);
    List<Resource> findResources(QueryCriteria criteria);
    void addTagsToResource(Resource resource, Set<Tag> tags);
}

ここでの考え方は、利用可能なデータ ストレージ メカニズムに合わせてこのインターフェイスを実装し、アプリケーションがこのインターフェイスを介してアクセスするというものです。実装クラスのインスタンスは、ファクトリから取得されます。

これはあなたの考えに合っていますか?

あなたが言及する問題のもう1つの側面は、タイプに応じて異なる動作を必要とする複数の異なるTagTypesと競合しなければならないことです(「TagValue instanceof Type」条件が必要です)。訪問者パターンは、これをエレガントな方法で処理できます。

于 2009-04-24T01:22:44.763 に答える
1

これらのプロパティを実際のメンバー変数と見なすべきではないと思います。プロパティを含む「プロパティ」オブジェクト (メンバー変数に類似) と、プロパティのコレクションを持つ「コレクション」オブジェクト (クラスのようなもの) が必要です。

これらの属性とコレクションには実際にはコードが関連付けられていないため、それらをオブジェクトとして実装しても意味がありません (そして、本当に面倒なことになります)。

属性とコレクションは、それらに固有のすべてのデータを保持する必要があります。たとえば、フィールドが最終的にデータベースに書き込まれる場合、そのテーブル名をどこかに保存する必要があります。画面に書き込む必要がある場合は、それもどこかに保存する必要があります。

範囲/値のチェックを属性に「追加」できるため、属性がどのタイプのデータであるかを定義するときに、値 12 で MaxLength というクラスをインスタンス化する「MaxLength(12)」というテキストが含まれる場合があります。そのクラスを属性に格納します。属性の値が変更されるたびに、このクラスに適用された各範囲チェッカーに新しい値が渡されます。クラスに関連付けられた多くのタイプのアクションが存在する可能性があります。

これは単なるベースです。私はこのようなものを設計しましたが、それはかなりの作業ですが、ストレートな言語でやろうとするよりもはるかに簡単です。

これは今は大変な作業のように思えますが (私が提案していることを実際に理解できればそうなるはずです)、心に留めておいてください。 .

編集 (コメントへの応答):

レジストリ/キーのことを考えてみましたが (まだ属性値のペアについて話しています)、うまくいきません。

DAO を Java オブジェクトに適合させようとしています。これは非常に自然なことですが、DAO/DTO の問題を解決するための単なる悪いアプローチであると考えるようになりました。Java オブジェクトには、属性と、それらの属性に作用する動作があります。あなたが行っていることには、動作はありません (たとえば、ユーザーが「誕生日」フィールドを作成した場合、誕生日が何であるかわからないため、オブジェクト コードを使用して年齢を計算することはありません)。

オブジェクトと属性を捨てるとしたら、このデータをどのように保存しますか?

非常に単純な最初のステップ(これは、あなたが言及したレジストリ/タグシステムに非常に近いものです)から始めましょう。オブジェクトを使用する場所では、ハッシュテーブルを使用します。属性名にはキーを使用し、属性値にはハッシュテーブルの値を使用します。

ここで、この単純なモデルを拡張するために私が行った問題と解決策について説明します。

問題: ストロング タイピングが失われ、データが非常に自由な形式になっています (これはおそらく悪いことです)。

解決策: ハッシュテーブルの値の代わりに使用される「属性」の基本クラスを作成します。IntegerAttribute、StringAttribute、DateAttribute などの基本クラスを拡張します。その型に適合しない値を許可しないでください。これで強力な型付けができましたが、コンパイル時ではなく実行時です。データは実行時に実際に定義されているため、おそらく問題ありません。

問題: フォーマッターとバリデーター

解決策: 属性の基本クラスのプラグインを作成できるようにします。任意の属性に対して「setValidator」または「setFormatter」を実行できるはずです。バリデーター/フォーマッターは属性と一緒に存在する必要があります。そのため、属性を保存するときに、それらを DB にシリアル化できる必要があります。

ここでの良い点は、属性に対して「attribute.getFormattedValue()」を実行すると、表示用に事前にフォーマットされていることです。attribute.setValue() は自動的にバリデーターを呼び出し、例外をスローするか、いずれかの検証が失敗した場合はエラー コードを返します。

問題: これらを画面に表示するにはどうすればよいですか? すでに getFormatted() がありますが、画面のどこに表示されるのでしょうか? ラベルには何を使用しますか? このフィールドを編集する必要があるのは、どのようなコントロールですか?

解決策: これらすべてを EACH 属性内に格納します。(注文はクラスに保存する必要がありますが、それはハッシュテーブルであるため機能しません--まあ、次で説明します)。表示名、これをレンダリングするために使用されるコントロールのタイプ (テキスト フィールド、テーブル、日付など)、およびデータベース フィールド名を保存する場合、この属性には、表示およびデータベース I/ O 属性を扱うために書かれたルーチン。

問題: Hashtable は、DAO のインターフェイスとしては不十分です。

解決策: これは絶対に正しいです。ハッシュテーブルは、それが保持する属性のコレクションを認識しているクラスでラップする必要があります。おそらくヘルパー クラスの助けを借りて、それ自体 (すべての属性を含む) をデータベースに格納できるはずです。おそらく、単一のメソッド呼び出しですべての属性を検証できるはずです。

問題: これらのものを実際に扱うにはどうすればよいですか?

解決策: それらには独自のデータが含まれているため、システム内の相互作用する (画面や DB など) あらゆる場所で、「アダプター」が必要です。

データを編集する画面を提示しているとしましょう。アダプタには、フレームとハッシュテーブル ベースの DTO の 1 つが渡されます。

最初に、属性のリストを順番に調べます。最初の属性 (文字列など) に、編集に使用するコントロールの種類 (テキスト フィールドとしましょう) を尋ねます。

テキストフィールドを作成し、データを更新するリスナーをテキストフィールドに追加します。これにより、データが画面上のコントロールにバインドされます。

これで、ユーザーがコントロールを更新するたびに、更新が属性に送信されます。属性に新しい値が保存されます。これで完了です。

(これは、すべての値を一度に転送する「OK」ボタンの概念によって複雑になりますが、それでも事前に各バインディングを設定し、「OK」をトリガーとして使用します。)

このバインディングは難しい場合があります。「JGoodies」と呼ばれるツールキットを使用したことがありますが、これにはバインディング機能が組み込まれているため、可能なバインディングの組み合わせを自分で作成する必要はありませんでしたが、長期的にはわかりませんそれは多くの時間を節約しました。

これは長すぎます。いつか DAO/DTO ツールキットを作成する必要があります。Java オブジェクトは、DAO/DTO オブジェクトとしてはまったく適していないと思います。

それでも困惑している場合は、お気軽に gmail の bill.kress にメールまたは IM でお問い合わせください。

于 2009-04-24T01:51:51.137 に答える
0

リレーショナル データベースの使用に縛られていますか? カウチDBなどのドキュメント指向のデータベースを調べる価値があるかもしれません。これにより、必要な任意の厳密に型指定されたオブジェクトを格納するために必要な柔軟性が得られ、それらのオブジェクトをクエリすることもできます。また、couchDB にアクセスするための Java ライブラリもいくつかあると思います。

于 2009-04-23T19:53:19.563 に答える