我正在浏览 SO 并在答案中看到了这条评论:
当我们可以 DI 委托以使其可测试时,为什么还要经历提取接口的仪式?
这表达了我今年早些时候的一个想法。注入纯功能(我猜是函数指针)而不是接口实现有什么本质上的错误吗?
我正在浏览 SO 并在答案中看到了这条评论:
当我们可以 DI 委托以使其可测试时,为什么还要经历提取接口的仪式?
这表达了我今年早些时候的一个想法。注入纯功能(我猜是函数指针)而不是接口实现有什么本质上的错误吗?
描述接口的“仪式”这个词听起来很可疑,就像一个反对静态类型的 Ruby 主义者的评论。有了一个好的重构和模板工具,大部分仪式无论如何都会被忽视。
虽然传入委托有其作用,但带有接口的 IoC 通常更易于实现、使用、理解和维护。
考虑一个典型的构造函数:
public class MyClass
{
public MyClass(IAmEasyToUnderstand easy)
{
if (easy == null) throw new ArgumentNullException("easy");
}
public MyClass(Func<bool, int, int, Point> IAmNot, Func<bool> Clear, Action aboutAnything)
{
//multiple null checks.
}
}
public interface IAmEasyToUnderstand
{
bool DoPointStuff(int a, int b, Point point);
bool CanHazExecute();
Action RunRun();
}
现在考虑一个返回接口供另一个使用的类:
public MyClass
{
//IFace
public IAmEasyToUnderstand FindEasy();
//Not Iface
Func<bool, int, int, Point> ReturnPointStuffDoer();
Func<bool> ReturnCanHazExecuteCallback();
Action WowThisIsAnnoying();
}
var easy = myclassInstance.FindEasy();
var consumer = new EasyConsumer(easy);
....
var consumer = new EasyConsumer(
myClassInstance.ReturnPointStuffDoer(),
myClassInstance.ReturnCanHazExecuteCallback(),
myClassInstance.WowThisIsAnnoying());
在查看后一个消费示例时,明显的清理将是:
var consumer = new EasyConsumer(myclassInstance);
这意味着您需要用模拟接口替换类类型。