5

我正在构建一个已索引多个不同数据源的搜索应用程序。当针对搜索引擎索引执行查询时,每个搜索结果都会指定它来自哪个数据源。我已经建立了一个工厂模式,用于为每种类型的搜索结果显示不同的模板,但我意识到随着越来越多的数据源被搜索引擎索引(即新的必须为每个新数据源创建代码模板)。

我根据 Granville Barnett 在DotNetSlackers.com上的一篇文章为我的工厂创建了以下结构

工厂模式 http://img11.imageshack.us/img11/8382/factoryi.jpg

为了使这个搜索应用程序更易于维护,我的想法是创建一组数据库表,这些表可用于定义我的工厂模式可以引用的各个模板类型,以确定构建哪个模板。我想我需要一个查找表,用于指定要根据搜索结果数据源构建的模板类型。然后我需要有一个表来指定要为该模板类型显示哪些字段。我还需要一个表(或模板表中的其他列),用于定义如何呈现该字段(即超链接、标签、CssClass 等)。

有没有人有这样的模式的例子?请告诉我。谢谢,-罗伯特

4

1 回答 1

4

我会提出,这个提议的解决方案的可维护性不亚于简单地将数据源关联到代码模板,就像您现在拥有的那样。事实上,我什至会说,通过将模板模式和呈现信息推送到数据库,您将失去灵活性,这将使您的应用程序更难维护。

例如,假设您有这些带有属性的数据源(如果我理解正确的话):

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

然后,您的搜索结果中可能会包含这些数据源中的一个。每个元素都以不同的方式呈现(图片可以使用锚定在左侧的预览图像来呈现,或者歌曲可以显示专辑封面等)

让我们看看您提出的设计下的渲染。您将查询数据库以获取渲染,然后调整您发出的一些 HTML,例如因为您想要文档的绿色背景和图片的蓝色背景。为了争论,假设您意识到您确实需要三种背景颜色用于歌曲,两种用于图片,一种用于文档。现在,除了更改要应用呈现值的参数化模板之外,您正在查看数据库模式更改,该更改被提升和推出。

假设您决定 Document 结果需要一个下拉控件,Picture 需要几个按钮,Songs 需要一个声音播放器控件。现在,每个数据源的每个模板都发生了巨大的变化,所以你回到了你开始的地方,除了现在你有一个数据库层。

这就是设计中断的原因,因为您现在失去了为每个数据源定义不同模板的灵活性。您丢失的另一件事是在源代码管理中对模板进行版本控制。

我会看看如何在发出的视图中重用通用元素/控件,但将模板和数据源之间的映射保留在工厂中,并将模板作为每个数据源的单独文件保存。看看通过 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>

并使用反射等。人。填充 IDictionary。您仍在维护映射,但现在在一个 XML 文件中,这可能更容易部署。

于 2009-09-19T19:20:42.973 回答