Al diseñar una clase, ¿debería favorecerse la consistencia en el comportamiento sobre la práctica de programación común? Para dar un ejemplo específico:
Una convención común es esta: si una clase posee un objeto (por ejemplo, lo creó), es responsable de limpiarlo una vez que está hecho. Un ejemplo específico sería en .NET que si su clase posee un IDisposableobjeto, debería disponerlo al final de su vida útil. Y si no lo tienes, no lo toques.
Ahora, si miramos la StreamWriterclase en .NET, podemos encontrar en la documentación que cierra la secuencia subyacente cuando se cierra / elimina. Esto es necesario en los casos en que StreamWriterse instancia al pasar un nombre de archivo cuando el escritor crea la secuencia de archivos subyacente y, por lo tanto, debe cerrarla. Sin embargo, también se puede pasar una secuencia externa que el escritor también cierra.
Esto me ha molestado un montón de veces (sí, sé que puedes hacer un contenedor sin cierre, pero ese no es el punto), pero aparentemente Microsoft ha tomado la decisión de que es más consistente cerrar siempre la transmisión sin importar de dónde venga.
Cuando me encuentro con este patrón en una de mis clases, generalmente creo un ownsFooBarindicador que se establece en falso en los casos en que FooBarse inyecta a través del constructor y en verdadero de lo contrario. De esta forma, la responsabilidad de limpiarlo se transfiere a la persona que llama cuando pasa la instancia explícitamente.
Ahora me pregunto si tal vez la coherencia debería estar a favor de las mejores prácticas (o tal vez mi mejor práctica no es tan buena). ¿Algún argumento a favor o en contra?
Editar para aclaraciones
Con "consistencia" quiero decir: el comportamiento consistente de la clase siempre tomando posesión (y cerrando la transmisión) frente a "mejores prácticas" para tomar posesión de un objeto solo si lo creó o transfirió explícitamente la propiedad.
En cuanto a un ejemplo donde está enoying:
Suponga que tiene dos clases dadas (de una biblioteca de terceros) que aceptan una secuencia para hacer algo con ella, como crear y procesar algunos datos:
public class DataProcessor
{
public Result ProcessData(Stream input)
{
using (var reader = new StreamReader(input))
{
...
}
}
}
public class DataSource
{
public void GetData(Stream output)
{
using (var writer = new StreamWriter(output))
{
....
}
}
}
Ahora quiero usarlo así:
Result ProcessSomething(DataSource source)
{
var processor = new DataProcessor();
...
var ms = new MemoryStream();
source.GetData(ms);
return processor.ProcessData(ms);
}
Esto fallará con una excepción Cannot access a closed streamen el procesador de datos. Está un poco construido pero debería ilustrar el punto. Hay varias formas de solucionarlo, pero sin embargo siento que trabajo alrededor de algo que no debería tener que hacerlo.