I. *_*edy 18 .net c# oop abstract-class stream
我花了很多时间熟悉.NET Stream类.通常我通过研究专业的,商业级的框架的类设计来学到很多东西,但我不得不说这里的东西不太好闻.
System.IO.Stream是一个表示字节序列的抽象类.它有10个抽象方法/属性:Read, Write, Flush, Length, SetLength, Seek, Position, CanRead, CanWrite, CanSeek
.如此多的抽象成员使得派生起来很麻烦,因为你必须覆盖所有这些方法,即使大多数最终只是抛出NotImplemented
.
Stream类的用户希望能够打电话CanRead
,CanWrite
或CanSeek
找出了数据流的能力,或者我想先走一步,打电话Read
,Write
或者Seek
看它是否抛出NotImplemented
.它只是我,还是这个糟糕的设计?
虽然现在有很多尼特我想用挑Stream
一流的设计,主要的一个,我想请教一下的是:他们为什么不使用界面,比如IReadable
,IWriteable
,ISeekable
,而不是?然后,新的Stream类可以从它支持的接口中优雅地派生.这不是面向对象的做事方式吗?或者我错过了什么?
更新:有人指出,值CanRead
等可以在运行时更改 - 例如,如果a FileStream
关闭 - 并且采取了这一点.但是,我仍然不相信这是一个很好的设计.从我来自哪里,尝试从已经关闭的文件中读取是一个错误,或者至少是一个特殊情况.(因此抛出异常是处理这种情况的一种自然方式.)
这是否意味着每次我要Read
离开时Stream
,我应该检查一下CanRead
?并且这是否意味着我应该设置一个锁以避免竞争条件,如果值可能在CanRead
呼叫和Read
呼叫之间的某个时间发生变化?
2010年8月7日更新:这里的共识似乎是Stream设计非常好.但是让我再一次要求100%肯定:人们每次从流中读取内容时都会写这样的东西?
// s is a Stream
lock(s)
{
if (s.CanRead)
{
s.Read(buf, 0, buf.Length);
}
}
Run Code Online (Sandbox Code Playgroud)
Bob*_*Bob 10
我认为课程设计得很好.我宁愿检查一个属性然后尝试做某事并且必须捕获异常.在具有多个"类型"的流类型的情况下,接口不足.从一个获取可读写流的方法返回什么类型?我同意设计不是真正的面向对象设计,但你真的想以这种方式处理流吗?如果流关闭或其他更改,某些属性可能会更改,在这种情况下会发生什么?
我认为这个问题提出了一个非常有趣的实验,为什么不尝试设计自己的流相关类.在CodePlex或Google Code上发布您的重新设计,这将是一个很好的学习经验,并将导致一个潜在有用的库供其他人使用.
使用接口意味着无法在运行时更改"CanRead"的值."FileStream"类根据文件的当前状态更改"CanRead"属性.
接口可能被过度使用,这将是其中一种情况.我认为目前的设计很棒.流可以在运行时更改功能这一事实意味着IReadable/IWritable/ISeekable不会消除对CanRead,CanWrite和CanSeek的需求,因此除了消除少数存根方法和属性之外,您只会增加复杂性而无法获得实际收益.在派生类中.
就个人而言,我更喜欢流类更易于使用而不是更容易编写,因为您将编写一次并使用它多次.