2009-09-19 18 views
5

Estoy construyendo una aplicación de búsqueda que ha indexado varias fuentes de datos diferentes. Cuando se realiza una consulta con respecto al índice del motor de búsqueda, cada resultado de búsqueda especifica de qué origen de datos proviene. Construí un patrón de fábrica que utilicé para mostrar una plantilla diferente para cada tipo de resultado de búsqueda, pero me di cuenta de que este patrón será más difícil de administrar a medida que el motor de búsqueda indexe cada vez más fuentes de datos (es decir, nuevas plantilla de código debe ser creado para cada nueva fuente de datos).C# Factory Pattern

creé la siguiente estructura para mi fábrica con sede fuera de un artículo de Granville Barnett encima en DotNetSlackers.com

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

Con el fin de hacer esta aplicación de búsqueda más fácil de mantener, mi pensamiento era crear un conjunto de tablas de bases de datos que se pueden usar para definir tipos de plantillas individuales a las que mi patrón de fábrica podría hacer referencia para determinar qué plantilla construir. Pensé que necesitaría tener una tabla de búsqueda que se usaría para especificar el tipo de plantilla para construir en función de la fuente de datos de resultados de búsqueda. Entonces necesitaría tener una tabla (s) para especificar qué campos mostrar para ese tipo de plantilla. También necesitaría una tabla (o columnas adicionales dentro de la tabla de plantillas) que se usaría para definir cómo representar ese campo (es decir, hipervínculo, etiqueta, CssClass, etc.).

¿Alguien tiene algún ejemplo de un patrón como este? Por favor hagamelo saber. Gracias, -Robert

Respuesta

4

Ofrecería que esta solución propuesta no sea menos fácil de mantener que simplemente asociar una fuente de datos a la plantilla de código, como lo hace ahora. De hecho, incluso llegaría a decir que perderá flexibilidad al empujar el esquema de la plantilla y la información de representación a una base de datos, lo que hará que su aplicación sea más difícil de mantener.

Por ejemplo, supongamos que usted tiene estas fuentes de datos con atributos (si estoy entendiendo esto correctamente):

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

A continuación, puede tener uno de cada una de estas fuentes de datos en los resultados de la búsqueda. Cada elemento se procesa de forma diferente (la imagen se puede representar con una imagen de vista previa anclada a la izquierda, o la canción puede mostrar la portada del álbum, etc.)

Veamos la representación según su diseño propuesto. Va a consultar la base de datos para las representaciones y luego ajustar algo de HTML que está emitiendo, digamos porque quiere un fondo verde para Documentos y uno azul para Imágenes. En aras de la argumentación, supongamos que te das cuenta de que realmente necesitas tres colores de fondo para Canciones, dos para Imágenes y uno para Documentos. Ahora, está viendo un cambio en el esquema de la base de datos, que se promueve y extrae, además de cambiar la plantilla parametrizada a la que está aplicando los valores de representación.

Digamos que decide que el resultado del documento necesita un control desplegable, la imagen necesita unos pocos botones y las canciones necesitan un control del reproductor de sonido. Ahora, cada plantilla por fuente de datos cambia drásticamente, por lo que está justo donde comenzó, excepto que ahora tiene una capa de base de datos lanzada.

Así se rompe el diseño, porque ahora ha perdido la flexibilidad de definir diferentes plantillas por fuente de datos La otra cosa que pierde es tener sus plantillas versionadas en control de fuente.

Me gustaría ver cómo puede volver a utilizar elementos/controles comunes en las vistas emitidas, pero mantener la asignación en fábrica entre la plantilla y la fuente de datos, y mantener las plantillas como archivos separados por fuente de datos.Observe cómo mantener el renderizado a través de CSS o configuraciones de configuración similares. Para facilitar el mantenimiento, considerando exportar las asignaciones como un simple archivo XML. Para implementar una nueva fuente de datos, simplemente agrega una asignación, crea la plantilla y el archivo CSS apropiados y colócalos en las ubicaciones esperadas.

Respuesta a los comentarios siguientes:

que significaba una declaración simple interruptor debería ser suficiente:

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

Cuando usted tiene la lógica para emitir una plantilla dada. Si quieres algo más compacto que una sentencia switch larga, puede crear las asignaciones en un diccionario, como esto:

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

Entonces, en lugar de una sentencia switch, puede hacerlo de una sola línea:

template = TemplateMap[resultType].CreateTemplate(); 

Mi argumento principal fue que en algún punto aún tiene que mantener las asignaciones, ya sea en la base de datos, una gran declaración de cambio o esta instancia de IDictionary que debe inicializarse.

Puede llevarlo más lejos y almacenar las asignaciones en un archivo XML simple que ha leído en:

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

Y el uso reflexión et. Alabama. para poblar el IDictionary. Todavía está manteniendo las asignaciones, pero ahora en un archivo XML, que podría ser más fácil de implementar.

+0

Gracias de nuevo por la explicación. ¡Siempre es bueno tener otro conjunto de ojos y opiniones! Tus pensamientos me han dado algunas ideas más para considerar. Gracias de nuevo. - Robert –