クラスを設計するとき、動作の一貫性は一般的なプログラミングの実践よりも優先されるべきですか?特定の例を挙げます:
一般的な規則は次のとおりです。クラスがオブジェクトを所有している場合(たとえば、オブジェクトを作成した場合)、それが完了したら、それをクリーンアップする責任があります。具体的な例は、.NETで、クラスがIDisposableオブジェクトを所有している場合、そのオブジェクトが寿命の終わりに破棄されるようにすることです。そして、もしあなたがそれを所有していないなら、触らないでください。
StreamWriter.NET のクラスを見ると、ドキュメンテーションで、基になるストリームが閉じられている/破棄されているときに閉じていることがわかります。これはStreamWriter、ライターが基礎となるファイルストリームを作成し、それを閉じる必要があるときにファイル名を渡すことによってインスタンス化される場合に必要です。ただし、ライターが閉じる外部ストリームを渡すこともできます。
これにより私は何度も悩まされました(閉じないラッパーを作成できることはわかっていますが、それはポイントではありません)が、Microsoftは、ストリームがどこから来たとしても常にストリームを閉じる方が一貫しているという決定を下したようです。
クラスの1つでこのようなパターンに出くわすと、通常、コンストラクターを介して注入さownsFooBarれた場合はfalseに設定され、FooBarそれ以外の場合はtrueに設定されるフラグを作成します。このようにして、呼び出し元がインスタンスを明示的に渡すときに、それをクリーンアップする責任が呼び出し元に渡されます。
今、私はおそらくベストプラクティスよりも一貫性を優先すべきかどうか疑問に思っています(または私のベストプラクティスはそれほど良くないかもしれません)?それに対する/反対の議論はありますか?
明確化のために編集
「一貫性」とは、つまり、オブジェクトを作成または明示的に所有権を譲渡した場合にのみオブジェクトの所有権を取得する「ベストプラクティス」に対して、常に所有権を取得する(およびストリームを閉じる)クラスの一貫した動作です。
厄介な例:
いくつかのデータを作成および処理するなど、ストリームを受け入れて何らかの処理を行う2つのクラス(サードパーティライブラリから)があるとします。
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、データプロセッサの例外で失敗します。それは少し構築されていますが、ポイントを説明する必要があります。それを修正するにはさまざまな方法がありますが、それでも私はするべきではない何かを回避すると感じています。