tutorial - using class c#
¿Debe la clase ac#generar instancias de sí mismo? (12)
Tengo una clase que define un tipo de CallRate. Necesito agregar la capacidad de crear varias instancias de mi clase leyendo los datos de un archivo.
Agregué un método estático a mi clase CallRate que devuelve una List<CallRate>
. ¿Está bien para una clase generar nuevas instancias de sí mismo llamando a uno de sus propios constructores? Funciona, solo me pregunto si es lo correcto.
List<CallRates> cr = CallRates.ProcessCallsFile(file);
A menudo uso este patrón cuando necesito verificar la validez de los parámetros. Se desaconseja encarecidamente lanzar una excepción desde un constructor. No es tan malo desde un método de fábrica, o puede elegir devolver nulo.
A veces uso métodos públicos estáticos como alternativa a la sobrecarga de constructores.
Especialmente en situaciones en las que no es bueno depender solamente de los tipos de parámetros para indicar qué tipo de construcción de objeto se pretende.
Claro que está bien, incluso animado en algunos casos. Hay varios patrones de diseño que se ocupan de la creación de objetos , y algunos de ellos hacen exactamente lo que usted está describiendo.
Claro, para escenarios simples de análisis (o similares), de hecho prefiero que el método de fábrica sea parte de la clase. Sí, rompe SRP , pero cumple con KISS , así que lo llamo una ganancia neta. Para aplicaciones más grandes o rutinas de análisis más complicadas, tiene más sentido que sea una clase de fábrica externa.
Para su caso particular, probablemente preferiría un método que incluyera una <cadena> de IEnumerable en lugar de un nombre de archivo, que aún le daría la lógica de análisis sintáctico, pero permitiría pruebas de unidades sencillas y "reutilización". La persona que llama puede envolver el archivo en un IEnumerable con bastante facilidad.
Está bien. Lo que acaba de crear es algo así como un simple método de fábrica. Tiene un método estático que crea una instancia válida de un tipo. En realidad, su método ni siquiera tiene que ser estático y aún tiene un código válido. Hay un patrón de diseño (prototipo) que crea un nuevo objeto válido a partir de un objeto existente. Consulte los detalles en http://www.dofactory.com/Patterns/PatternPrototype.aspx .
Está perfectamente bien obtener objetos propios del método estático.
p.ej
Una de las bibliotecas de punto red hace lo mismo que tú,
XmlReadrer reader = XmlReader.Create(filepathString);
Generalmente uso esto cuando necesito implementaciones instantáneas de una clase. Por ejemplo
public class Car
{
public static Car RedExpensiveCar = new Car("Red", 250000);
public Car()
{
}
public Car(string color, int price)
{
Color = color;
Price = price;
}
public string Color { get; set; }
public int Price { get; set; }
}
Y con esto, no necesito recordar o escribir parámetros de constructor en mi código.
Car car = Car.RedExpensiveCar;
Los métodos de fábrica a menudo son un buen diseño. Cuando los escribo en C #, los llamo ''Nuevos'', de modo que:
new MyClass()
se convierte
MyClass.New()
Trivialmente se implementa así:
class MyClass
{
public static MyClass New()
{
return new MyClass();
}
}
Principalmente hago esto cuando hay condiciones adicionales sobre si realmente crear la clase o simplemente devolver null
, o si devolver MyClass
o algo derivado de él.
Me parece bien. En otros idiomas probablemente escribirías una función, pero en un lenguaje como C #, los métodos estáticos toman ese rol.
Solo quiero señalar "generar nuevas instancias de sí mismo llamando a uno de sus propios constructores"
No es del constructor, es del método estático.
Soy fanático de que los métodos estáticos devuelvan instancias, como se sugirió muchas veces, más arriba.
@Paul: no olvides marcar el comentario anterior, que es la mejor respuesta.
Es perfectamente aceptable hacer esto. Cuando lo hago, normalmente hago que los constructores reales de la clase sean privados, por lo que está claro que la única forma de construir instancias es a través del método estático.
Esto es muy útil en casos donde "construcción" no siempre devuelve una nueva instancia. Por ejemplo, es posible que desee devolver un objeto previamente almacenado en caché.