返回void的方法是否会更改其参数的状态(即提供隐藏或隐式返回值)通常是一种不好的做法?
我发现它们很难嘲笑,这表明它们可能是一个糟糕设计的标志。
有哪些模式可以避免它们?
一个非常人为的例子:
public interface IMapper
{
void Map(SourceObject source, TargetObject target);
}
public class ClassUnderTest
{
private IMapper _mapper;
public ClassUnderTest(IMapper mapper)
{
_mapper = mapper;
}
public int SomeOperation()
{
var source = new SourceObject();
var target = new TargetObject();
_mapper.Map(source, target);
return target.SomeMappedValue;
}
}
答案 0 :(得分:1)
如果您执行此操作,您的代码将更容易测试:
public interface IMapper
{
TargetObject Map(SourceObject source);
}
public class ClassUnderTest
{
private IMapper _mapper;
public ClassUnderTest(IMapper mapper)
{
_mapper = mapper;
}
public int SomeOperation(SourceObject source )
{
var target = _mapper.Map(source, target);
return target.SomeMappedValue;
}
}
您现在可以分别测试Map opperation和SomeOperation。问题是你idd改变一个对象的状态,这使得很难提供一个存根进行测试。返回新对象时,您可以返回目标的测试存根并测试调用方法。
答案 1 :(得分:1)
在某种程度上是的。
您所描述的是典型的副作用。副作用使程序难以理解,因为您需要理解的信息不包含在调用堆栈中。您需要其他信息,即在订单之前(以及以什么方式)调用的方法。
解决方案是编程没有副作用。这意味着您不需要更改变量,字段或任何内容。相反,你会返回通常会改变的新版本。
这是函数式编程的基本原理。
当然,这种编程方式有其自身的挑战。只考虑I / O.