对象与静态方法设计 [英] Object vs static method design
问题描述
如下图所示,我可以通过两种简单的方式制作流式复印机(介绍Apache Commons或类似的)。我应该选择哪一个,以及为什么?
As shown below, there are two straightforward ways I could make a stream copier (bar introducing Apache Commons or similar). Which one should I go for, and why ?
public class StreamCopier {
private int bufferSize;
public StreamCopier() {
this(4096);
}
public StreamCopier(int bufferSize) {
this.bufferSize = bufferSize;
}
public long copy(InputStream in , OutputStream out ) throws IOException{
byte[] buffer = new byte[bufferSize];
int bytesRead;
long totalBytes = 0;
while((bytesRead= in.read(buffer)) != -1) {
out.write(buffer,0,bytesRead);
totalBytes += bytesRead;
}
return totalBytes;
}
}
vs
public class StreamCopier {
public static long copy(InputStream in , OutputStream out)
throws IOException {
return this.copy(in,out,4096);
}
public static long copy(InputStream in , OutputStream out,int bufferSize)
throws IOException {
byte[] buffer = new byte[bufferSize];
int bytesRead;
long totalBytes = 0;
while ((bytesRead= in.read(buffer)) != -1) {
out.write(buffer,0,bytesRead);
totalBytes += bytesRead;
}
return totalBytes;
}
}
推荐答案
我使用非静态(实例)版本,并将其作为与setter的显式依赖关系提供给消费者:
I'd go with the non-static (instance) version, and supply it to consumers as an explicit dependency with a setter:
- 嘲笑它因此,单元测试的结果是微不足道的,因此消费者的测试不会与实现相结合;
- 交换功能非常简单,例如:使用子类;
- 与依赖注入系统很好地配合。
编辑
回应一个(有用的!)评论这有助于嘲笑?,这是它的工作方式:
In response to a (useful!) comment of "how does this help mocking?", here's how it might work:
class ThingThatUsesStreamCopier {
// our copier instance. set in constructor, but might equally use
// a setter for this:
private StreamCopier copier;
public ThingThatUsesStreamCopier(StreamCopier copier) {
this.copier = copier;
}
public void makeCopy(Stream in, Stream out) {
// probably something a little less trivial...
copier.copy(in, out);
}
}
当我来测试 ThingThatUsesStreamCopier
,我可以创建一个<$ c的模拟对象版本$ c> StreamCopier 并使用此模拟实例化 ThingThatUsesStreamCopier
。
When I come to test ThingThatUsesStreamCopier
, I can create a mock object version of a StreamCopier
and instantiate the ThingThatUsesStreamCopier
using this mock.
这样做,我可以完全控制我的模拟行为,所以我的测试与 StreamCopier
的任何实际实现分离。我只测试消费者,而不是消费者和消费者。
By doing so, I have full control over the behaviour of my mock, so my test is decoupled from any real implementations of StreamCopier
. I am only testing the consumer, not the consumer plus the consumed.
这篇关于对象与静态方法设计的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!