¿Está bien poner una llamada de inicialización de base de datos en un constructor de C #? [cerrado]

StackOverflow https://stackoverflow.com/questions/159886

  •  03-07-2019
  •  | 
  •  

Pregunta

He visto que se trata de varias bases de código, y quería saber si esto generalmente está mal visto o no.

Por ejemplo:

public class MyClass
{
   public int Id;

   public MyClass()
   {
      Id = new Database().GetIdFor(typeof(MyClass));
   }
}
¿Fue útil?

Solución

Hay varias razones por las que esto generalmente no se considera un buen diseño, algunas de las cuales ya han mencionado las pruebas difíciles de la unidad y la dificultad de manejar errores.

La razón principal por la que elegiría no hacerlo es que su objeto y la capa de acceso a datos ahora están muy estrechamente acoplados, lo que significa que cualquier uso de ese objeto fuera de su diseño original requiere una revisión considerable. Como ejemplo, ¿qué pasa si se encuentra con una instancia en la que necesita usar ese objeto sin ningún valor asignado, por ejemplo, para persistir en una nueva instancia de esa clase? ahora tiene que sobrecargar el constructor y luego asegurarse de que todas sus otras lógicas manejen este nuevo caso, o heredar y anular.

Si el objeto y el acceso a los datos se desacoplan, puede crear una instancia y no hidratarla. O si tiene un proyecto diferente que usa las mismas entidades pero usa una capa de persistencia diferente, entonces los objetos son reutilizables.

Habiendo dicho que he tomado el camino más fácil de acoplar proyectos en el pasado :)

Otros consejos

Bueno ... no lo haría. Pero, de nuevo, mi enfoque generalmente implica que la clase NO sea responsable de recuperar sus propios datos.

También hará que sea difícil escribir pruebas unitarias para la clase, ya que no podrá forzar a la clase a usar una versión Mock / Stub de la clase db. Mira aquí: http://en.wikipedia.org/wiki/Dependency_injection

Puede usar el patrón desechable si hace referencia a una conexión de base de datos:

public class MyClass : IDisposable
{
    private Database db;
    private int? _id;

    public MyClass()
    {
        db = new Database();
    }

    public int Id
    {
        get
        {
            if (_id == null) _id = db.GetIdFor(typeof(MyClass));
            return _id.Value;
        }
    }

    public void Dispose()
    {
        db.Close();
    }
}

Uso :

using (var x = new MyClass()) 
{
    /* ... */

} //closes DB by calling IDisposable.Dispose() when going out of "using" scope

Sí, PUEDES hacerlo, pero no es el mejor diseño, y el manejo de errores en los constructores no es tan ordenado como en otros lugares.

El único problema que puedo pensar con este enfoque es que cualquier error de la inicialización de la base de datos se propagará como excepciones del constructor.

¿Por qué alguien querría usar un objeto / trozo simulado en lugar de uno real? ¿Está de acuerdo en que los fabricantes de automóviles deberían usar modelos de cartón? para pruebas de choque?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top