C# 是一种多范式语言。通过嵌套接口和类,可以获得对象的组合。通过这种方式,可以将某个问题分解为多个简单的问题,从而为每个组件提供自己的难题来解决。同样的技巧可以以稍微不同的方式完成,可以将功能组合在一起,每个功能负责解决自己的小任务,而所有功能结合起来并相互关联,可以解决主要问题。
遵循 SOLID 原则,我发现自己处于这样一种情况,即 95% 的接口只带有一个名为 do-something 的方法,并且接口的名称是 something-doer。实现此类接口的类是 DI'ed 与完成该方法应该做的任何事情所需的一些组件。这种方法基本上是手动关闭一个函数。如果是这样,我为什么不与自然且免费(无需打字)的代表一起去?如果我一直将单个方法接口转换为委托,我将从我的代码中消除 95% 的委托,使其看起来像是用函数式语言编写的。但这似乎是一件正确的事情,除非有一些大胆的理由坚持使用接口。有没有?
更新:
@Fendy,让我争论一下。你说过
“您无法从 BLL 控制委托逻辑”。好吧,委托可以在任何地方定义,而不必在调用者中定义。可以完美地做到这一点:
public namespace Bbl
{
public static class TestableUtils {
public static Func<A, B> CreateA2B() {
Func<A, B> a2b = a => new B(a);
return a2b;
}
public static Func<B, C> CreateB2C() {
Func<B, C> b2c = b => new C(b);
return b2c;
}
public static Func<A, C> CreateA2C(Func<A, B> a2b, Func<B, C> b2c)
{
Func<A, C> a2c = a => b2c(a2b(a));
return a2c;
}
}
}
public namespace Caller
{
using Bbl;
public class Demo()
{
public void RunMe()
{
var a = new A();
var a2b = TestableUtils.CreateA2B();
var b2c = TestableUtils.CreateB2C();
var a2c = TestableUtils.CreateA2C(a2b, b2c);
var c = a2c(a);
}
}
}
“一不小心,到处重复代码”,确实如此,偷懒小心,不要重复做同样的工作。类很容易发生同样的问题。所以代表也不例外。
“如果构造函数注入并使用可变实体,它可能导致有状态接口”我很抱歉我没有看到你的例子有问题。我的意思是它完全按照它的程序设计。如果你改变实体,这就是你所期望的,不是吗?只需防止在构造函数之外设置 Name 即可确保安全。如果你这样做,那么你的例子中的情况将是不可能的。
基本上,在您列出的 4 点中,与使用委托相比使用接口/类时遇到更多问题没有任何关系。或者我只是没有得到它。