C#工厂模式

扫码查看

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

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

factory pattern http://img11.imageshack.us/img11/8382/factoryi.jpg

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

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

最佳答案

我要提供的是,与您现在所拥有的一样,该提议的解决方案与将数据源与代码模板简单地关联起来一样,具有可维护性。实际上,我什至可以说,通过推送模板架构并将信息呈现到数据库中,您将失去灵活性,这将使您的应用程序难以维护。

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

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

然后,您可能在搜索结果中具有这些数据源之一。每个元素的渲染方式都不同(图片可以在左侧 anchor 定预览图像的情况下渲染,或者Song可以显示专辑封面等)

让我们看一下您建议的设计下的渲染。您将在数据库中查询渲染,然后调整正在发射的HTML,例如,因为您希望文档的背景为绿色,图片的背景为蓝色。为了便于讨论,假设您意识到,您确实需要为Songs提供三种背景颜色,为Picture提供两种背景颜色,为Documents提供一种背景颜色。现在,您正在查看数据库模式更改,该模式已被促进和推出,除了更改向其应用呈现值的参数化模板之外。

进一步说,您决定“文档”结果需要一个下拉控件,“图片”需要一些按钮,“乐曲”需要声音播放器控件。现在,每个数据源的每个模板都将发生巨大变化,因此您可以回到开始的位置,除非现在有了一个数据库层。

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

我将研究如何在发射的 View 中重用常见的元素/控件,但将映射保留在模板和数据源之间的工厂中,并将模板作为每个数据源的单独文件保留。看一下如何通过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文件中,这可能更易于部署。

10-07 15:58
查看更多