5

いくつかの異なるデータソースにインデックスを付けた検索アプリケーションを構築しています。検索エンジンインデックスに対してクエリが実行されると、各検索結果は、それがどのデータソースからのものであるかを指定します。検索結果の種類ごとに異なるテンプレートを表示するために使用するファクトリパターンを作成しましたが、検索エンジンによってインデックスが作成されるデータソースが増えるにつれて、このパターンの管理が難しくなることに気付きました(つまり、新しい新しいデータソースごとにコードテンプレートを作成する必要があります)。

DotNetSlackers.comにあるGranvilleBarnettの記事に基づいて、工場用に次の構造を作成しました。

ファクトリパターンhttp://img11.imageshack.us/img11/8382/factoryi.jpg

この検索アプリケーションの保守を容易にするために、作成するテンプレートを決定するためにファクトリパターンが参照できる個々のテンプレートタイプを定義するために使用できるデータベーステーブルのセットを作成することを考えました。検索結果のデータソースに基づいて作成するテンプレートのタイプを指定するために使用されるルックアップテーブルが必要だと思いました。次に、そのテンプレートタイプに対して表示するフィールドを指定するためのテーブルが必要になります。また、そのフィールド(ハイパーリンク、ラベル、CssClassなど)のレンダリング方法を定義するために使用されるテーブル(またはテンプレートテーブル内の追加の列)も必要です。

このようなパターンの例はありますか?私にお知らせください。ありがとう、-ロバート

4

1 に答える 1

4

この提案されたソリューションは、現在のように、データソースをコードテンプレートに関連付けるだけでなく、保守も容易です。実際、テンプレートスキーマをプッシュして情報をデータベースにレンダリングすると、柔軟性が失われ、アプリケーションの保守が難しくなると言っても過言ではありません。

たとえば、属性を持つこれらのデータソースがあるとします(これを正しく理解している場合)。

Document { Author, DateModified }
Picture { Size, Caption, Image }
Song { Artist, Length, AlbumCover }

次に、検索結果にこれらの各データソースの1つが含まれる場合があります。各要素は異なる方法でレンダリングされます(画像は左側に固定されたプレビュー画像でレンダリングされる場合があります。または、Songはアルバムカバーなどを表示する場合があります)。

提案されたデザインの下でのレンダリングを見てみましょう。データベースにレンダリングを照会してから、出力するHTMLを調整します。たとえば、ドキュメントには緑色の背景、画像には青色の背景が必要なためです。議論のために、歌には3つの背景色、写真には2つ、ドキュメントには1つの背景色が本当に必要であることに気付いたとしましょう。ここで、レンダリング値を適用するパラメーター化されたテンプレートを変更することに加えて、プロモートされてプッシュされるデータベーススキーマの変更を確認しています。

さらに、ドキュメントの結果にはドロップダウンコントロールが必要であり、画像にはいくつかのボタンが必要であり、曲にはサウンドプレーヤーのコントロールが必要であると判断したとします。これで、データソースごとの各テンプレートが大幅に変更されるため、データベースレイヤーがスローされていることを除いて、最初の場所に戻ります。

データソースごとに異なるテンプレートを定義する柔軟性が失われたため、これが設計の失敗の原因です。もう1つ失うのは、テンプレートをソース管理でバージョン管理することです。

エミッションされたビューで共通の要素/コントロールを再利用する方法を検討しますが、テンプレートとデータソースの間のマッピングを工場で維持し、テンプレートをデータソースごとに個別のファイルとして保持します。CSSまたは同様の構成設定を介してレンダリングを維持することを検討してください。保守を容易にするために、マッピングを単純なXMLファイルとしてエクスポートすることを検討してください。新しいデータソースをデプロイするには、マッピングを追加し、適切なテンプレートとCSSファイルを作成して、それらを予想される場所にドロップするだけです。

以下のコメントへの回答:

私は単純なswitchステートメントで十分であることを意味しました:

switch (resultType)
{
    case (ResultType.Song):
      factory = new SongResultFactory();
      template = factory.BuildResult();
      break;
    // ...

特定のテンプレートを出力するロジックがある場合。長いswitchステートメントよりもコンパクトなものが必要な場合は、次のようにディクショナリにマッピングを作成できます。

IDictionary<ResultType, ResultFactory> TemplateMap;
mapping = new Dictionary<ResultType, ResultFactory>();
mapping.Add(ResultType.Song, new SongResultFactory());
// ... for all mappings.

次に、switchステートメントの代わりに、次のワンライナーを実行できます。

template = TemplateMap[resultType].CreateTemplate();

私の主な議論は、ある時点で、データベース、大きなswitchステートメント、または初期化する必要のあるこのIDictionaryインスタンスのいずれかでマッピングを維持する必要があるということでした。

さらに進んで、次のように読み込まれる単純なXMLファイルにマッピングを保存できます。

<TemplateMap>
    <Mapping ResultType="Song" ResultFactoryType="SongResultFactory" />
    <!-- ... -->
</TemplateMap>

そして、反射などを使用します。al。IDictionaryにデータを入力します。マッピングは引き続き維持されていますが、XMLファイルになっているため、展開が簡単な場合があります。

于 2009-09-19T19:20:42.973 に答える