C # Заводская модель - PullRequest
       10

C # Заводская модель

5 голосов
/ 19 сентября 2009

Я создаю поисковое приложение, которое проиндексировало несколько различных источников данных. Когда запрос выполняется по индексу поисковой системы, каждый результат поиска указывает, из какого источника данных он поступил. Я создал фабричный шаблон, который использовал для отображения разных шаблонов для каждого типа результатов поиска, но я понял, что этим шаблоном будет все труднее управлять, поскольку все больше и больше источников данных индексируются поисковой системой (т. Е. Новые шаблон кода должен быть создан для каждого нового источника данных).

Я создал следующую структуру для своей фабрики на основе статьи Гранвилла Барнетта в DotNetSlackers.com

заводская модель http://img11.imageshack.us/img11/8382/factoryi.jpg

Чтобы упростить поддержку этого поискового приложения, я подумал о создании набора таблиц базы данных, которые можно использовать для определения отдельных типов шаблонов, на которые мог бы ссылаться мой шаблон фабрики, чтобы определить, какой шаблон создать. Я подумал, что мне нужно иметь справочную таблицу, которая будет использоваться для указания типа шаблона для построения на основе источника данных результатов поиска. Затем мне нужно иметь таблицу (таблицы), чтобы указать, какие поля отображать для этого типа шаблона. Мне также понадобится таблица (или дополнительные столбцы в таблице шаблонов), которая будет использоваться для определения способа визуализации этого поля (например, гиперссылка, метка, CssClass и т. Д.).

У кого-нибудь есть примеры подобной схемы? Пожалуйста, дайте мне знать. Спасибо, -Роберт

1 Ответ

4 голосов
/ 19 сентября 2009

Я хотел бы предложить, что это предлагаемое решение не менее легко обслуживаемо, чем просто связывание источника данных с шаблоном кода, как у вас сейчас. На самом деле, я бы даже сказал, что вы потеряете гибкость, передавая схему шаблона и передавая информацию в базу данных, что усложнит обслуживание вашего приложения.

Например, предположим, у вас есть эти источники данных с атрибутами (если я правильно понимаю):

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.

Затем, вместо оператора switch, вы можете сделать одну строку:

template = TemplateMap[resultType].CreateTemplate();

Моим главным аргументом было то, что в какой-то момент вам все еще нужно поддерживать отображения - либо в базе данных, либо в большом операторе switch, либо в этом экземпляре IDictionary, который необходимо инициализировать.

Вы можете пойти дальше и сохранить сопоставления в простом XML-файле, который читается в:

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

И используйте отражение и др. и др. заполнить IDictionary. Вы по-прежнему поддерживаете сопоставления, но теперь в XML-файле, который может быть легче развернуть.

...