¿Cuánto trabajo se debe hacer en un constructor?

En caso de que las operaciones que podrían llevar algún tiempo se realicen en un constructor o se construya el objeto, se inicializarán más tarde.

Por ejemplo, cuando se construye un objeto que representa una estructura de directorio, la población del objeto y sus elementos secundarios deben hacerse en el constructor. Claramente, un directorio puede contener directorios y que a su vez puede contener directorios, etc.

¿Cuál es la solución elegante para esto?

Históricamente, he codificado mis constructores para que el objeto esté listo para usar una vez que el método constructor esté completo. La cantidad o la cantidad de código involucrado depende de los requisitos para el objeto.

Por ejemplo, supongamos que necesito mostrar la siguiente clase de empresa en una vista de detalles:

public class Company { public int Company_ID { get; set; } public string CompanyName { get; set; } public Address MailingAddress { get; set; } public Phones CompanyPhones { get; set; } public Contact ContactPerson { get; set; } } 

Como quiero mostrar toda la información que tengo sobre la empresa en la vista de detalles, mi constructor contendrá todo el código necesario para completar cada propiedad. Dado que es un tipo complejo, el constructor de la Compañía también activará la ejecución del constructor Dirección, Teléfonos y Contacto.

Ahora, si estoy rellenando una vista de listado de directorios, donde es posible que solo necesite CompanyName y el número de teléfono principal, puedo tener un segundo constructor en la clase que solo recupere esa información y deja la información restante vacía, o simplemente puedo crear un objeto separado que solo contiene esa información. Realmente solo depende de cómo se recupera la información y de dónde.

Independientemente del número de constructores en una clase, mi objective personal es hacer cualquier procesamiento que sea necesario para preparar el objeto para cualquier tarea que se le pueda imponer.

Para resumir:

  • Como mínimo, su constructor necesita configurar el objeto hasta el punto en que sus invariantes sean verdaderas.

  • Su elección de invariantes puede afectar a sus clientes. (¿El objeto promete estar listo para el acceso en todo momento? ¿O solo en ciertos estados?) Un constructor que se encarga de todos los preparativos puede simplificar la vida para los clientes de la clase.

  • Los constructores de larga ejecución no son inherentemente malos, pero pueden ser malos en algunos contextos.

  • Para los sistemas que involucran una interacción del usuario, los métodos de larga duración de cualquier tipo pueden llevar a una capacidad de respuesta deficiente y deben evitarse.

  • Retrasando el cálculo hasta después de que el constructor pueda ser una optimización efectiva; puede resultar innecesario realizar todo el trabajo. Esto depende de la aplicación, y no debe determinarse prematuramente.

  • En general, depende.

Por lo general, no desea que el constructor realice ningún cálculo. Alguien más que use el código no esperará que haga más que una configuración básica.

Para un árbol de directorios como el que está hablando, la solución “elegante” probablemente no sea construir un árbol completo cuando se construye el objeto. En cambio, comstackrlo según demanda. Puede que a alguien que use su objeto no le importe realmente lo que hay en los subdirectorios, así que empiece simplemente haciendo que su lista de constructores sea el primer nivel, y luego, si alguien desea descender a un directorio específico, compile esa parte del árbol cuando lo soliciten. eso.

El tiempo requerido no debe ser una razón para no poner algo en un constructor. Puede poner el código en una función privada y llamarlo desde su constructor, solo para mantener el código en el constructor despejado.

Sin embargo, si lo que desea hacer no es necesario para darle al objeto una condición definida, y podría hacer eso más adelante en el primer uso, este sería un argumento razonable para apagarlo y hacerlo más tarde. Pero no lo haga dependiente de los usuarios de su clase: estas cosas (inicialización bajo demanda) deben ser completamente transparentes para los usuarios de su clase. De lo contrario, invariantes importantes de su objeto podrían romperse fácilmente.

Depende (respuesta típica de CS). Si está construyendo objetos al inicio para un progtwig de larga ejecución, entonces no hay problema con hacer mucho trabajo en constructores. Si esto es parte de una GUI donde se espera una respuesta rápida, podría no ser apropiado. Como siempre, la mejor respuesta es intentarlo de la manera más simple primero, perfilar y optimizar desde allí.

Para este caso específico, puede hacer una construcción diferida de los objetos del subdirectorio. Solo crea entradas para los nombres de los directorios de nivel superior. Si se accede, luego cargue el contenido de ese directorio. Repita esto cuando el usuario expulse la estructura del directorio.