При розробці класу слід підтримувати послідовність у поведінці щодо звичайної практики програмування? Навести конкретний приклад:
Поширена умова така: Якщо класу належить об'єкт (наприклад, він створив його), він відповідає за його очищення, як тільки це буде зроблено. Конкретним прикладом може бути .NET, що якщо ваш клас володіє IDisposableоб'єктом, він повинен розпоряджатися ним наприкінці свого життя. А якщо ви не володієте нею, тоді не торкайтеся.
Тепер, якщо ми подивимось на StreamWriterклас у .NET, то в документації ми можемо виявити, що він закриває основний потік, коли він закривається / розміщується. Це необхідно в тих випадках, коли StreamWriterекземпляр передається в ім'я файлу, коли автори створюють базовий потік файлів, і тому його потрібно закрити. Однак можна також пройти у зовнішній потік, який письменник також закриває.
Це дратувало мене безліч разів (так, я знаю, що ви можете зробити обгортку, що не закривається, але це не сенс), але, очевидно, Microsoft прийняла рішення, що більш послідовно завжди закривати потік незалежно від того, звідки він прийшов.
Коли я стикаюся з таким шаблоном в одному з моїх класів, я зазвичай створюю ownsFooBarпрапор, який встановлюється значення false у випадках, коли FooBarвводиться через конструктор, а в іншому - true. Таким чином відповідальність за його очищення передається абоненту, коли він передає екземпляр явно.
Тепер мені цікаво, чи, можливо, послідовність має бути на користь кращої практики (а може, моя найкраща практика не є такою доброю)? Будь-які аргументи за / проти цього?
Редагувати для уточнення
Під "послідовністю" я маю на увазі: Послідовна поведінка класу, який завжди приймає право власності (і закриває потік) проти "найкращої практики", приймає право власності на об'єкт лише тоді, коли ви створили його або явно передали право власності.
Що стосується прикладу, коли воно enoying:
Припустимо, у вас є два задані класи (з якоїсь сторонньої бібліотеки), які приймають потік, щоб зробити щось із ним, наприклад, створити та обробити деякі дані:
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))
{
....
}
}
}
Тепер я хочу використовувати його так:
Result ProcessSomething(DataSource source)
{
var processor = new DataProcessor();
...
var ms = new MemoryStream();
source.GetData(ms);
return processor.ProcessData(ms);
}
Це не вдасться за винятком Cannot access a closed streamу процесорі обробки даних. Це трохи побудовано, але має ілюструвати суть. Існують різні способи виправити це, але все-таки я відчуваю, що працюю над чимось, чого мені не слід.