¿Cómo puedo forzar un C # constructor para ser una fábrica?
-
13-09-2019 - |
Pregunta
El código siguiente consiste en dos clases :
- SmartForm (simple clase de modelo)
- SmartForms (clase plural que contiene una colección de SmartForm objetos)
Quiero ser capaz de crear instancias de ambas clases singular y plural como esto (es decir, no quiero un método de fábrica GetSmartForm ()):
SmartForms smartForms = new SmartForms("all");
SmartForm smartForm = new SmartForm("id = 34");
Para consolidar la lógica, sólo la clase plural debe tener acceso a la base de datos . La clase singular, cuando se le preguntó a una instancia de sí mismo, simplemente será una instancia de una clase plural, a continuación, escoger el objeto fuera de la recogida del objeto plural y se convierten en ese objeto .
¿Cómo puedo hacer eso? He intentado asignar el objeto a this
que no funciona.
using System.Collections.Generic;
namespace TestFactory234
{
public class Program
{
static void Main(string[] args)
{
SmartForms smartForms = new SmartForms("all");
SmartForm smartForm = new SmartForm("id = 34");
}
}
public class SmartForm
{
private string _loadCode;
public string IdCode { get; set; }
public string Title { get; set; }
public SmartForm() {}
public SmartForm(string loadCode)
{
_loadCode = loadCode;
SmartForms smartForms = new SmartForms(_loadCode);
//this = smartForms.Collection[0]; //PSEUDO-CODE
}
}
public class SmartForms
{
private string _loadCode;
public List<SmartForm> _collection = new List<SmartForm>();
public List<SmartForm> Collection
{
get
{
return _collection;
}
}
public SmartForms(string loadCode)
{
_loadCode = loadCode;
Load();
}
//fills internal collection from data source, based on "load code"
private void Load()
{
switch (_loadCode)
{
case "all":
SmartForm smartFormA = new SmartForm { IdCode = "customerMain", Title = "Customer Main" };
SmartForm smartFormB = new SmartForm { IdCode = "customerMain2", Title = "Customer Main2" };
SmartForm smartFormC = new SmartForm { IdCode = "customerMain3", Title = "Customer Main3" };
_collection.Add(smartFormA);
_collection.Add(smartFormB);
_collection.Add(smartFormC);
break;
case "id = 34":
SmartForm smartForm2 = new SmartForm { IdCode = "customerMain2", Title = "Customer Main2" };
_collection.Add(smartForm2);
break;
default:
break;
}
}
}
}
Solución
No tiene que ser exactamente el mismo objeto, sólo tiene que parecen ser la misma para los observadores externos. Si copia todos los datos de un objeto a otro, va a lograr lo mismo.
public SmartForm(string loadCode)
{
_loadCode = loadCode;
SmartForms smartForms = new SmartForms(_loadCode);
this.IdCode = smartForms[0].IdCode;
this.Title = smartForms[0].Title;
}
Otros consejos
No se puede conseguir un objeto a "convertirse" en la otra.
Utilice métodos estáticos en lugar de constructores (y hacen que los constructores privados / interno / lo que sea para que sólo los métodos estáticos pueden acceder a ellos). Existen numerosos beneficios a la utilización de métodos estáticos sobre constructores:
- Usted puede devolver null si procede
- Usted puede devolver un objeto existente en su caso
- Usted puede hacer un montón de trabajo y después llamar a un constructor simple que simplemente establece campos
La desventaja es que no funcionan con C # colección / inicializadores de objeto: (
Una alternativa a métodos estáticos (que no funciona bien con dependencia de la inyección, es cierto) es tener una fábrica separada y llamar a los métodos de instancia en eso.
No se puede. Microsoft hace esto mediante la definición de un método public static Crear () en su lugar. Véase, por ejemplo WebRequest y HttpWebRequest en el espacio de nombres System.Net. Le sugiero que haga lo mismo.
Hacer que el constructor de la clase base interna o privada, por lo que no se pueden crear instancias directamente. O mejor aún, que sea una clase abstracta. Hacer uso de los constructores ocultos en su Create () aplicación.
Se podría utilizar un internal
o modificador protected
para el constructor, en lugar de public
. Tal que:
public SmartForm() {}
public SmartForm(string loadCode)
{
_loadCode = loadCode;
SmartForms smartForms = new SmartForms(_loadCode);
//this = smartForms.Collection[0]; //PSEUDO-CODE
}
se convierte en:
internal SmartForm() {}
internal SmartForm(string loadCode)
{
_loadCode = loadCode;
SmartForms smartForms = new SmartForms(_loadCode);
//this = smartForms.Collection[0]; //PSEUDO-CODE
}
Se podría hacer una clase privada llamada SmartFormData
, y poner todos los valores en ella.
Hacer la clase plural SmartForms
mantener una colección de esos objetos, y crea el constructor singular SmartForm
encontrar la instancia SmartFormData justo en plural SmartForms
.
A continuación, hacer que todas las propiedades en SmartForm
singular ha podido recuperar sus valores de SmartFormData
Sin embargo, la mejor manera de hacerlo es tener un constructor privado y el uso de un método de fábrica.
¿Hay una razón por la que usted tiene que utilizar un constructor?