C# 工厂模式

标签 c# design-patterns database-design factory-pattern

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

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

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

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

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

最佳答案

我认为这个提议的解决方案的可维护性不亚于将数据源与代码模板相关联,正如您目前所拥有的那样。事实上,我什至会说将模板架构和呈现信息推送到数据库会失去灵 active ,这将使您的应用程序更难维护。

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

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

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

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

进一步假设您决定文档结果需要一个下拉控件,图片需要几个按钮,而歌曲需要一个声音播放器控件。现在,每个数据源的每个模板都发生了翻天覆地的变化,所以您又回到了起点,只是现在您加入了一个数据库层。

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

我会研究如何在发出的 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>

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

关于C# 工厂模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1448949/

相关文章:

mysql - 需要一个想法来设计用于诊所预约安排的数据库 : "A doctor is working in multiple clinics in different timings"

MySQL,20 亿行数据,只读,性能优化?

c# - Mongodb .Net Driver 如何关闭连接

c# - 多个数据提供者/ORM 上的存储库模式?

oop - 从嵌套结构通知观察者

wpf - WPF 应用程序可以进行依赖注入(inject)吗?

java - 如何实现引用数据Java/DB

c# - 如何从 IEnumerable 创建多维数组

c# - Linq to NHibernate 存储库实现细节

c++ - 速度关键系统的设计跟踪/日志