C#工厂模式

Rob*_*ams 5 c# database-design design-patterns factory-pattern

我正在构建一个索引几个不同数据源的搜索应用程序.当针对搜索引擎索引执行查询时,每个搜索结果指定它来自哪个数据源.我已经构建了一个工厂模式,我用它为每种类型的搜索结果显示不同的模板,但我意识到这种模式将变得更难以管理,因为越来越多的数据源被搜索引擎索引(即新的必须为每个新数据源创建代码模板.

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

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

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

有没有人有这样的模式的例子?请告诉我.谢谢,-Robert

emp*_*set 4

我认为这个建议的解决方案的可维护性并不比简单地将数据源与代码模板相关联(就像您现在所拥有的那样)一样。事实上,我什至会说,通过推送模板架构并将信息呈现到数据库,您将失去灵活性,这将使您的应用程序更难以维护。

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

Document { Author, DateModified }
Picture { Size, Caption, Image }
Song { Artist, Length, AlbumCover }
Run Code Online (Sandbox Code Playgroud)

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

让我们看看您提议的设计下的渲染效果。您将在数据库中查询渲染结果,然后调整您发出的一些 HTML,例如您希望文档使用绿色背景,图片使用蓝色背景。为了方便讨论,假设您意识到您确实需要三种背景颜色用于歌曲,两种用于图片,一种用于文档。现在,您正在查看数据库架构更改,除了更改要应用渲染值的参数化模板之外,还会升级和推出数据库架构更改。

进一步说,您决定文档结果需要下拉控件,图片需要一些按钮,歌曲需要声音播放器控件。现在,每个数据源的每个模板都发生了巨大的变化,因此您又回到了开始的地方,只不过现在您添加了一个数据库层。

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

我将研究如何在发出的视图中重用通用元素/控件,但将模板和数据源之间的映射保留在工厂中,并将模板保留为每个数据源的单独文件。考虑通过 CSS 或类似的配置设置来维护渲染。为了使其更易于维护,请考虑将映射导出为简单的 XML 文件。要部署新的数据源,您只需添加映射、创建适当的模板和 CSS 文件,并将它们放入预期位置。

对以下评论的回应:

我的意思是一个简单的 switch 语句就足够了:

switch (resultType)
{
    case (ResultType.Song):
      factory = new SongResultFactory();
      template = factory.BuildResult();
      break;
    // ...
Run Code Online (Sandbox Code Playgroud)

您有输出给定模板的逻辑。如果您想要比长 switch 语句更紧凑的东西,您可以在字典中创建映射,如下所示:

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

然后,您可以执行以下一行操作,而不是使用 switch 语句:

template = TemplateMap[resultType].CreateTemplate();
Run Code Online (Sandbox Code Playgroud)

我的主要论点是,在某些时候您仍然必须维护映射 - 无论是在数据库中、大型 switch 语句中还是在需要初始化的 IDictionary 实例中。

您可以更进一步,将映射存储在读入的简单 XML 文件中:

<TemplateMap>
    <Mapping ResultType="Song" ResultFactoryType="SongResultFactory" />
    <!-- ... -->
</TemplateMap>
Run Code Online (Sandbox Code Playgroud)

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