2

我非常清楚这样一个问题可能已经发布了。然而,由于 IoC 在这种情况下的参与以及大量代码,我在一家我刚入职的公司中看到一位同事提出了这个问题。

设想:

在一个产品的代码库中,这位同事构建的每个接口都是明确实现的。整个应用程序是通过结构映射构建的,但在某些地方使用和转换的具体类型是这样的

((IInterface)concreteClass).SomeMethod()

背景:

那位同事在询问显式实现所有接口是什么后向我解释说,他们最近引入了 StructureMap,许多人仍然会使用具体类型。因此,从本质上讲,它是一种“教育”公司人员的手段。

我对此事的看法:

首先,切换到 StructureMap 已经在几年前完成了,虽然这在某种程度上迫使更多地使用接口,但在我看来这不是正确的方法。在我看来,了解具体类型的人可以看到实现,并且很容易看到我上面展示的内容......只需投射它。清晰的通信或编码约定会使这变得更好。如果使用 IoC 而没有具体的类,那么显式实现接口是完全没用的。

我也听说这真的会弄乱继承,但不知道一个例子。我还看到Jon Skeet有点不喜欢以上述方式使用它,而是使用它打算使用的方式,比如 IEnumerable<> 和其他名称冲突。

任何人都可以为我阐明这件事。优点和缺点(尽管我非常倾向于不这样做,因此我在这里发帖),尤其是其中一个或另一个的原因。

谢谢!

编辑:我很清楚这不是对与错的问题,也没有真正的答案。这更像是一个学习了解每种方法的缺陷的问题。为什么我会在一种情况下使用一种而不是另一种方法?

4

2 回答 2

0

显式接口实现有两个主要的潜在优势:

  1. 单个类可以实现两个具有冲突方法签名的接口,并且每个接口的实现略有不同。这种情况很少发生,而且按需而不是默认执行通常不是问题。
  2. 您可以“隐藏”某些您不希望人们使用的方法,除非在特定情况下。接口隔离原则鼓励我们不要向消费者公开他们不太可能需要的方法。

使用#2 的一个很好的例子是实体框架上下文避免ObjectContext直接暴露其底层的方式(因为大多数人不应该在他们的代码中使用它),但如果你将上下文转换为IObjectContextAdapter.

就您的公司而言,听起来他们正试图利用#2,但出于错误的原因。他们想隐藏方法实现,不是因为不希望使用该方法,而是因为他们确实希望它被使用——当他们希望它会鼓励开发人员将他们的代码与具体的代码分离时类型。您的代码示例表明它缺少标记——开发人员仍在实例化具体类型,然后对其进行强制转换以访问接口方法。

于 2014-09-08T17:10:22.987 回答
0

一个很好的起点可能是这篇文章:为什么我使用显式接口实现作为默认实现技术

最初我并不倾向于明确地实现接口,但我不得不承认作者提出了一些非常好的观点。

更新:在下面的评论中,OP 声明显式实现会破坏继承,因为您无法覆盖派生类型中的接口实现。我不确定我是否正确地理解了这个问题:

public interface IFooable
{
     void Foo();
     void FooAgain();
}

public class Blah: IFooable
{
     void IFooable.Foo()
     {
         Console.WriteLine("Hi from 'Blah'!");
     }

     void IFooable.FooAgain() {}
}

public class Bar: Blah, IFooable
{
     void IFooable.Foo()
     {
         Console.WriteLine("Hi from 'Bar'!");
     }
}

public static void Main()
{
   var fooList = new List<IFooable>();
   fooList.Add(new Blah());
   fooList.Add(new Bar());

   foreach (var fooable in fooList) //Outputs "Hi from 'Blah'!" / "Hi from 'Bar'!"
       fooable.Foo();

   Console.ReadLine();
}
于 2014-09-08T14:58:00.970 回答