c# - 通过仅使用原始类型/委托(delegate)实现松散耦合

标签 c# interface dependencies primitive-types loose-coupling

我有一个关于松散耦合和接口(interface)的概念/理论问题。

因此使用接口(interface)的一种方法可能是封装某个构造函数所需的参数:

class Foo
{
    public Foo(IFooInterface foo)
    {
       // do stuff that depends on the members of IFooInterface
    }
}

所以只要传入的对象实现了契约,就万事大吉了。根据我的理解,这里的主要好处是它支持多态性,但我不确定这是否真的与松散耦合有关。

为了论证,假设 IFooInterface 如下所示:

interface IFooInterface
{
   string FooString { get; set; }
   int FooInt { get; set; }

   void DoFoo(string _str); 
}

从松耦合的角度来看,在上面的构造函数中不使用 IFooInterface 而是像这样设置 Foo 不是更好吗:

class Foo
{
    public Foo(string _fooString, int _fooInt, Action<string> _doFoo)
    {
       // do the same operations
    }
}

因为我想将 Foo 的功能放到另一个项目中。这意味着其他项目也必须引用 IFooInterface,添加另一个依赖项。但是这样我就可以将 Foo 放到另一个项目中,它准确地表达了它需要什么才能工作。显然我可以只使用重载的构造函数,但是为了争论我不想和/或不能修改 Foo 的构造函数。

最显着的缺点(至少对我来说)是,如果你有一个带有一堆原始参数的方法,它会变得丑陋且难以阅读。所以我有了创建一种包装函数的想法,它允许您仍然传入一个接口(interface)而不是所有原始类型:

    public static Func<T, R> Wrap<T, R>(Func<T, object[]> conversion)
    {
        return new Func<T, R>(t =>
        {
            object[] parameters = conversion(t);

            Type[] args = new Type[parameters.Length];

            for (int i = 0; i < parameters.Length; i++)
            {
                args[i] = parameters[i].GetType();
            }

            ConstructorInfo info = typeof(R).GetConstructor(args);

            return (R)info.Invoke(parameters);
        });
    }

这里的想法是,我可以取回一个函数,该函数采用符合 Foo 要求的某个接口(interface)的实例,但 Foo 实际上对该接口(interface)一无所知。它可以像这样使用:

public Foo MakeFoo(IFooInterface foo)
{
    return Wrap<IFooInterface, Foo>(f => 
       new object[] { f.FooString, f.FooInt, f.DoFoo })(foo);  
}

我听说过关于接口(interface)应该如何实现松散耦合的讨论,但我对此感到疑惑。

想知道一些有经验的程序员是怎么想的。

最佳答案

在您的初始示例中,您非常接近 Parameter Object模式,尽管这里更常见的是使用一个简单的类(通常带有自动属性)而无需额外的接口(interface)抽象。

通常,当您听说将接口(interface)传递给构造函数时,它并不是要替换原语,而是作为依赖注入(inject)的一种形式。不是直接依赖于 MyFooRepository,而是依赖于 IFooRepository,这将消除与特定实现的耦合。

关于c# - 通过仅使用原始类型/委托(delegate)实现松散耦合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6462225/

相关文章:

c# - ASP.NET Identity UserStore中GetNormalizedUserNameAsync和SetNormalizedUserNameAsync函数的解释

C# 将接口(interface)应用到窗体类

java - 在没有 openjdk 依赖的情况下安装 cassandra

c# - 桌面应用程序中的 MongoDB

c# - 我如何通过带有反射 C# 的属性获取类信息

java - 数组编程 - N 个玩家的 Tic Tac Toe nxn 板

java - 如何避免 'Interface Abstract class error' ?

java - 无法从外部库导入 MediaPlayer

java - 如何禁用 Maven 中依赖项的任何类型的日志记录? [ logback,ethereumJ]

c# - 使用ZOHO SMTP配置发送邮件时出现`The operation has timed out.`异常