c# casting factory factory-pattern

Fábrica de C#- es un upcast una necesidad?



casting factory (6)

¿El patrón de fábrica de C # requiere una actualización?

Quiero que Dios en la biblioteca de clases G cree un Adán en la biblioteca de clases A sin hacer que G dependa de A. Dios produce Adams para el consumo de Eva en la biblioteca de clases E, y está bien que Eva conozca y dependa de Adán. (Editar - esta muestra sigue mejorando y mejorando :)

La solución que podría pensar es tener un AdamFactory en A. De esta manera, AdamFactory conoce a Adam y puede crearlo fácilmente (posiblemente simplemente llamando al constructor de Adam). Dios recibe un AdamFactory y puede ordenarlo a CreateAdam.

Ahora, debido a que a Dios no se le permite conocer a Adán, CreateAdam de AdamFacotry debe devolver un objeto, y esto requiere que Eva envíe el objeto devuelto por AdamFactory a un Adán.

Esto funcionará, creo. Sin embargo, me siento incómodo con el lanzamiento ya que es un no-no. ¿Es esto realmente una necesidad?

PD: no pretendía la blasfemia, y me disculpo si los sentimientos de alguien fueron heridos. Parecía mejor usar a Dios y Adán en lugar de Creador y Creado porque las dos últimas palabras son demasiado similares entre sí.

Edición: Re sugerencia de interfaces. Asumamos que Adam tiene dos métodos: Proveer Amor, Proveer Comida y Proveer Protección (estamos guardando esta muestra kis-safe :). Eva usa a Adán para estos dos propósitos, pero, por supuesto, Dios no lo hace. Entonces, ¿por qué proporcionarle a Dios el conocimiento de que AdamFactor devuelve algo que implementa un IAdam y no solo un objeto? No lo entiendo

Edición: El código de trabajo (con todos en la misma biblioteca, cuyo objetivo es separar las bibliotecas diferentes) es algo así:

Adam God.LoadAdam(AdamID theAdamID) var adam = new Adam(theAdamId, this) Adam.Adam(AdamID theAdamID, God theGod) _god = theGod _mind = theGod.LoadMind(theAdamId, this) Mind God.LoadMind (AdamID theAdamID, Adam theAdam) var mind = new Mind (theAdam) var mindId = new minId(theAdamId) mind.DeserializeFromFile(minId) Mind.Mind (Adam theAdam) _adam = theAdam


¿Qué pasa con el uso de interfaces para que Dios sepa IAdam, o algo así como IHuman?


Bueno, si Dios es una biblioteca de clases de persistencia como mencionaste en el comentario, entonces no debería influir en el diseño de clase del resto del sistema.

Por lo tanto, no añadiría interfaces innecesarias. Está bien devolver un objeto desde el deserializador y luego hacia abajo (por ejemplo, BinaryFormatter, XmlSerializer).

La mejor manera sería hacer su deserializador genérico.



Está describiendo un patrón de fábrica abstracto , aunque las fábricas "secundarias" (por ejemplo, AdamFactory) normalmente tienen algo en común, por lo que espera que produzcan algo más como una interfaz común en lugar de solo un objeto (consulte la respuesta de Davide)

Tienes razón en preocuparte por el lanzamiento ya que esto vinculará a Eva con la implementación de Adán, que derrota el propósito de una fábrica (a menos que realmente lo estés utilizando como constructor).

La pregunta es, ¿por qué necesitas la clase de Dios?


No estoy seguro de entender completamente los requisitos, pero aquí hay una sugerencia:

//in assembly G public abstract class HumanFactory<T> { public abstract T CreateHuman(); } //in assembly A public class Adam { } //in assembly A public class AdamFactory : HumanFactory<Adam> { public override Adam CreateHuman() { return new Adam(); } } //in assembly G public class God { public T Create<T>(HumanFactory<T> factory) { return factory.CreateHuman(); } }

y el uso:

//Somewhere in assembly E Adam adam = new God().Create(new AdamFactory());


OK, ¿qué hay de rociar en algunos genéricos aquí?

Digamos que Dios puede aceptar fábricas de cualquier tipo T que se adhieran a la siguiente interfaz:

interface IFactory { Type CreatedType { get; } object Create(); }

Una clase abstracta para implementar esto puede verse así:

abstract class AbstractFactory<T> : IFactory { public Type CreatedType { get { return typeof(T); } public virtual object Create() { return innerCreate(); } protected abstract override T innerCreate(); }

Ahora, puedes registrar las fábricas con Dios:

God.RegisterFactory(new AdamFactory());

AdamFactory hereda de AbstractFactory<Adam>

Dios almacena sus fábricas en un diccionario donde la clave es el tipo devuelto por la interfaz IFactory

El método de creación ahora se ve así:

God.Create<Adam>();

Dios mira en sus fábricas, ve que hay una para typeof (T) del método genérico, recupera la fábrica, llama a la creación y reduce a T.

¿Qué piensas?