2009-09-19 15 views
5

Buduję aplikację wyszukującą, która zindeksowała kilka różnych źródeł danych. Gdy zapytanie jest wykonywane względem indeksu wyszukiwarki, każdy wynik wyszukiwania określa, z którego źródła pochodzi. Zbudowałem wzór fabryczny, którego użyłem do wyświetlenia innego szablonu dla każdego rodzaju wyniku wyszukiwania, ale zdałem sobie sprawę, że ten wzór będzie trudniejszy do zarządzania, ponieważ coraz więcej źródeł danych jest indeksowanych przez wyszukiwarkę (np. należy utworzyć szablon kodu dla każdego nowego źródła danych).C# Factory Pattern

I stworzył następującą strukturę dla mojej fabryce umiejscowionej off artykule Granville Barnett na co DotNetSlackers.com

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

Aby ta aplikacja wyszukiwania łatwiejsze do utrzymania, moja myśl była do stworzenia zestawu tabel bazy danych, które mogą być używane do definiowania poszczególnych typów szablonów, które mój wzorzec fabryki mógłby odwoływać się w celu ustalenia, który szablon należy utworzyć. Pomyślałem, że muszę mieć tabelę wyszukiwania, która będzie używana do określenia typu szablonu do zbudowania na podstawie źródła danych wyników wyszukiwania. Musiałbym wtedy mieć tabele, aby określić, które pola mają być wyświetlane dla tego typu szablonu. Potrzebowałabym również tabeli (lub dodatkowych kolumn w tabeli szablonów), która byłaby użyta do zdefiniowania sposobu renderowania tego pola (np. Hiperłącze, Etykieta, CssClass, itp.).

Czy ktoś ma przykłady takiego wzoru? Proszę daj mi znać. Dzięki, -Robert

Odpowiedz

4

Proponuję, aby proponowane rozwiązanie było nie mniej przydatne niż zwykłe powiązanie źródła danych z szablonem kodu, tak jak obecnie. W rzeczywistości nawet posunąłbym się do stwierdzenia, że ​​utracisz elastyczność, przesuwając schemat szablonu i wyświetlając informacje w bazie danych, co utrudni utrzymanie aplikacji.

Na przykład, załóżmy, masz te źródła danych z atrybutami (jeśli mam zrozumienia tego poprawnie):

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

Następnie może mieć jeden z każdego z tych źródeł danych w wynikach wyszukiwania. Każdy element jest renderowany inaczej (obrazek może być renderowany z obrazem podglądu zakotwiczonym po lewej stronie, lub utwór może wyświetlać okładkę albumu itp.).

Spójrzmy tylko na renderowanie w ramach proponowanego projektu. Zamierzasz zapytać bazę danych o renderowanie, a następnie dostosować kod HTML, który chcesz emitować, powiedzmy, że chcesz uzyskać zielone tło dla dokumentów, a niebieskie dla obrazów. Dla dobra argumentu powiedzmy, że zdajesz sobie sprawę, że naprawdę potrzebujesz trzech kolorów tła dla utworów, dwóch dla obrazów i jednego dla dokumentów. Teraz patrzysz na zmianę schematu bazy danych, która jest promowana i wypychana, oprócz zmiany sparametryzowanego szablonu, do którego stosujesz wartości renderowania.

Powiedzmy, że po tym zdecydujesz, że wynik dokumentu wymaga rozwijanej kontroli, obrazek potrzebuje kilku przycisków, a utwory wymagają sterowania dźwiękiem. Teraz każdy szablon na źródło danych zmienia się drastycznie, więc jesteś z powrotem w miejscu, w którym zacząłeś, z tą różnicą, że teraz masz wrzuconą warstwę bazy danych.

W ten sposób projekt przestaje działać, ponieważ utraciłeś elastyczność definiować różne szablony dla każdego źródła danych. Inną rzeczą, którą tracisz, jest posiadanie wersji szablonów w kontroli kodu źródłowego.

Chciałbym sprawdzić, jak można ponownie użyć wspólnych elementów/kontrolek w emitowanych widokach, ale zachowaj odwzorowanie w fabryce między szablonem a źródłem danych i zachowaj szablony jako oddzielne pliki dla każdego źródła danych.Popatrz na utrzymanie renderowania za pomocą CSS lub podobnych ustawień konfiguracyjnych. Dla ułatwienia utrzymania, rozważając eksportowanie mapowań jako prosty plik XML. Aby wdrożyć nowe źródło danych, wystarczy dodać mapowanie, utworzyć odpowiedni szablon i plik CSS i umieścić je w oczekiwanych lokalizacjach.

odpowiedzi na komentarze poniżej:

mi chodziło proste stwierdzenie przełącznik powinien wystarczyć:

switch (resultType) 
{ 
    case (ResultType.Song): 
     factory = new SongResultFactory(); 
     template = factory.BuildResult(); 
     break; 
    // ... 

Gdzie masz logiki do wyjścia dany szablon. Jeśli chcesz coś bardziej zwarty niż długi switch, można utworzyć mapowania w słowniku, jak to:

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

Następnie, zamiast instrukcji switch, można to zrobić jedną wkładkę:

template = TemplateMap[resultType].CreateTemplate(); 

Moim głównym argumentem było to, że w pewnym momencie nadal musisz zachować mapowania - albo w bazie danych, dużą instrukcję przełącznika, albo tę instancję IDictionary, która musi zostać zainicjalizowana.

można podjąć dalsze kroki i przechowywania mapowania w prosty plik XML, który jest w językach:

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

I użyć refleksji et. glin. zapełnić IDictionary. Nadal zachowujesz mapowania, ale teraz w pliku XML, który może być łatwiejszy do wdrożenia.

+0

Jeszcze raz dziękuję za wyjaśnienie. Zawsze dobrze jest zdobyć kolejny zestaw oczu i opinii! Twoje myśli dały mi jeszcze kilka pomysłów do rozważenia. Dzięki jeszcze raz. - Robert –