patron example c# design-patterns interface-builder builder

c# - example - Patrón de diseño: Constructor



patron builder c# (4)

Nunca lo he pensado de esta manera, pero LINQ (el patrón, no la sintaxis) es en realidad un constructor, ¿verdad?

Es una interfaz fluida que crea una consulta y puede crear consultas en diferentes representaciones (SQL, consultas de objetos en memoria, consultas de servicios web, incluso Bart de Smet escribió una implementación de Linq-to-Excel).

He buscado un buen ejemplo de un patrón de Builder (en C #), pero tampoco puedo encontrar uno porque no entiendo el patrón de Builder o estoy tratando de hacer algo que nunca se pretendió. Por ejemplo, si tengo un automóvil abstracto y métodos abstractos de construcción para crear partes de automóviles, debería poder enviar todas mis 30 elecciones al Director, hacer que construya las piezas que necesito y luego construya mi automóvil. Independientemente de qué automóvil, camión, semi, etc. se produzca, debería poder "conducirlo" exactamente de la misma manera.

El primer problema es la mayoría de los ejemplos de valores de propiedad de código duro en las partes concretas, que realmente creo que deberían provenir de una base de datos. Pensé que la idea era enviar mis elecciones al Director (desde una fuente de datos) y que el creador creara un producto personalizado basado en mis datos.

El segundo problema es que quiero que los métodos del constructor realmente creen las partes y luego las asignen al producto, no pasen cadenas, sino partes del producto muy tipadas.

Por ejemplo, quiero crear un formulario sobre la marcha haciendo que un Builder fabrique campos de formulario para mí, incluyendo una etiqueta, una sección de entrada, validación, etc. De esta manera puedo leer el objeto desde mi ORM, verifique los metadatos del objeto. , pase esto a mi Generador y agregue el resultado del control de usuario recién creado a mi formulario web.

Sin embargo, cada ejemplo de Builder que encuentro solo tiene datos codificados en duro en lugar de pasar las elecciones del código principal al Builder y expulsar un producto personalizado. Todo parece ser una gran declaración de caso estático. Por ejemplo, si tengo tres parámetros con 10 opciones cada uno, no quiero crear 30 métodos de Generador concretos, quiero crear solo lo suficiente para fabricar las propiedades que requiere mi producto, que pueden ser solo tres.

Estoy tentado de que el Director exista solo en el código principal. Debería haber una manera de determinar automáticamente qué método de construcción de concreto llamar similar al polimorfismo y las sobrecargas de método (aunque ese es un ejemplo muy malo) en lugar de usar una declaración de caso dentro del patrón. (Cada vez que necesito agregar un nuevo tipo de producto, tendré que modificar el Director existente, lo cual es malo).


Sobre todo la llamada de un BuilderPattern se ve así:

Car car = new CarBuilder().withDoors(4).withColor("red").withABS(true).build();


Voy a consultar el ejemplo de C # en el artículo de Wikipedia here .

El primer problema es la mayoría de los ejemplos de valores de propiedad de código duro en las partes concretas, que realmente creo que deberían provenir de una base de datos. Pensé que la idea era enviar mis elecciones al Director (desde una fuente de datos) y que el creador creara un producto personalizado basado en mis datos.

En este caso, tendría una clase que implementa PizzaBuilder que sabe cómo recuperar datos de una base de datos. Puedes hacerlo de varias maneras.

Uno sería hacer un HawaiianPizzaBuilder. Cuando la clase se inicializa, consulta la base de datos para una pizza hawaiana y recupera la fila. Luego, cuando se llaman los diversos métodos de Build (x), se establecen las propiedades en el campo correspondiente de la fila de la base de datos recuperada.

Otro sería simplemente hacer un PizzaDatabaseBuilder y asegurarse de que cuando inicializa la clase, le pasa el ID de la fila que necesita para ese tipo de pizza. Por ejemplo, en lugar de

waiter.PizzaBuilder = new HawaiianPizzaBuilder();

Tu usas

waiter.PizzaBuilder = new PizzaDatabaseBuilder("Hawaiian");

El segundo problema es que quiero que los métodos del constructor realmente creen las partes y luego las asignen al producto, no pasen cadenas, sino partes del producto muy tipadas.

No debería ser un problema. Lo que necesita es otro patrón de tipo Fábrica / Constructor para inicializar los campos de la Pizza. Por ejemplo

en lugar de

public override void BuildDough() { pizza.Dough = "pan baked"; }

harías algo como

public override void BuildDough() { pizza.Dough = new DoughBuilder("pan baked"); }

o

public override void BuildDough() { pizza.Dough = new PanBakedDoughBuilder(); }

DoughBuilder puede ir a otra tabla en su base de datos para completar correctamente una clase de PizzaDough.


Yo diría que no puede evitar ninguno de estos: tener pocas sobrecargas para sus partes y tener un caso / declaración en algún lugar de la pila. También tener que modificar su código al agregar una nueva clase podría ser su única opción.

Dicho esto, puede obtener ayuda con algunos otros patrones, a saber, Factory que podría ayudarlo en el proceso de construcción. También el uso sensato del polimorfismo (por ejemplo, todas las partes heredadas de algún tipo, ya sea clase o interfaz) puede reducir la cantidad de ifs / casos y sobrecargas.

Espero que esto ayude.