代码之家  ›  专栏  ›  技术社区  ›  Robert Williams

C#工厂模式

  •  5
  • Robert Williams  · 技术社区  · 16 年前

    我根据Granville Barnett在 DotNetSlackers.com

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

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

    有人有这样的模式的例子吗?请让我知道。 谢谢 -罗伯特

    1 回复  |  直到 16 年前
        1
  •  4
  •   emptyset    16 年前

    我想说的是,这个建议的解决方案的可维护性不亚于将数据源与代码模板相关联,正如您现在所做的那样。事实上,我甚至会说,如果将模板模式推送到数据库并将信息呈现到数据库中,您将失去灵活性,这将使您的应用程序更难维护。

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

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

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

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

    让我们进一步假设,您决定文档结果需要一个下拉控件,图片需要几个按钮,歌曲需要一个声音播放器控件。现在,每个数据源的每个模板都发生了巨大的变化,所以您回到了开始的位置,只是现在您有了一个数据库层。

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

    template = TemplateMap[resultType].CreateTemplate();
    

    我的主要论点是,在某个时候,您仍然需要维护映射——要么在数据库中,要么在一个大的switch语句中,要么在这个需要初始化的IDictionary实例中。

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

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

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