2014-09-08 3 views
2

Я очень осведомлен о том, что такой вопрос, вероятно, уже был опубликован. Тем не менее с участием IoC в этом случае и большого количества кода я видел коллегу в компании, в которой я новичок, поставил этот вопрос.Каждый интерфейс явно реализован? (Задействован IoC)

Сценарий:

В кодовых одного продукта этот коллега построить каждый интерфейс реализован в явном виде. Все приложение строится с помощью структурной карты, но в некоторых местах используются конкретные типы и отливать, как этот

((IInterface)concreteClass).SomeMethod() 

Справочная информация:

что коллега объяснил мне, после выяснения того, что речь идет о явном внедряя все интерфейсы, которые недавно представили StructureMap, и многие люди все равно будут использовать конкретные типы. Таким образом, по сути, это средство «воспитывать» людей в компании.

Мои центах по этому вопросу:

Прежде всего, переход на StructureMap было сделано несколько лет назад и в то время как это, своего рода, заставляет использовать интерфейсы более, на мой взгляд, это не правильно. То, как я это вижу, люди, которые знают о конкретном типе, могут увидеть реализацию и легко понять то, что я показал выше ... просто бросьте ее. Четкие соглашения об обмене или кодировании сделают это намного лучше. Если используется IoC и нет конкретного класса, то явно имплицирование интерфейса совершенно бесполезно.

Я также слышал, что это действительно может испортить наследование, но не знаю примера. Я также видел Jon Skeet отчасти не рекомендуется использовать его так, как это было упомянуто выше, а скорее способом, которым он предназначался использовать, например, с IEnumerable <> и другими столкновениями имен.

Может ли кто-нибудь пролить свет на этот вопрос для меня. Плюсы и минусы (хотя я очень предвзятый, чтобы не делать этого, следовательно, мой пост здесь) и особенно причины, почему тот или другой.

Спасибо!

Редактировать: Я очень хорошо знаю, что это не вопрос правильного или неправильного, и нет реального ответа. Это больше вопрос, чтобы научиться знать дефицит каждого подхода. Почему я должен использовать один сценарий по другому?

ответ

0

Хорошей отправной точкой может быть эта статья: Why I use explicit interface implementation as a default implementation technique

Изначально я не был склонен по реализации интерфейсов в явном виде, но я должен признать, что автор делает некоторые очень хорошие моменты.

UPDATE: В комментариях ниже 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(); 
} 
+1

Я уже читал это. Проблема заключается в том, что вы можете аргументировать то же самое против него. Лично я использовал бы только явную реализацию интерфейса, когда это действительно необходимо, так как это может испортить ситуацию, и вы действительно не имеете никакой пользы от ее использования при нормальной реализации. Но я бы очень хотел услышать больше двух сторон. Зачем препятствовать этому или почему его поощрять. Что, на ваш взгляд, заставляет его использовать и что вы получаете от этого? Спасибо! –

+1

@Qudeid Лично я использую явные реализации, когда интерфейс, как правило, используется не столь прозрачными механизмами структуры. Типичным примером будет «IConvertible». Я не видел столько кода, напрямую вызывающего метод этого интерфейса, он обычно используется через System.Convert. Тем не менее, я не уверен, что есть правильный или неправильный способ сделать это, это скорее стиль кодирования I Угадай. – InBetween

+0

Нет правильного пути. Мне будет больше обсуждать, какие проблемы вы можете столкнуться, когда идете так или иначе. Проблема, которую я вижу с вышеприведенным сообщением, заключается в том, что кто-то излагает причину использования HIS, но он тоже опускает много вещей. Он очень похож на проповедь, учитывая комментарии ниже. Возможно, мне следует отредактировать мой вопрос, что это должно быть скорее обсуждение, чем вопрос. –

0

Есть два основные потенциальные преимуществ для явных реализаций интерфейса:

  1. Один класса может реализовать два интерфейса, которые имеют противоположные сигнатуры методы , и тонко разные реализации для каждого. Это редко случается, и обычно это не проблема, а не по умолчанию.
  2. Вы можете «скрыть» определенные методы, которые вы не ожидаете от людей, кроме как в определенных контекстах. Принцип децентрализации интерфейса побуждает нас не раскрывать методы для потребителей, которых они вряд ли понадобятся.

Один хороший пример # 2 используется путь, который Entity Framework контексты не подвергать их основной ObjectContext непосредственно (потому что большинство людей не должны использовать его в своем коде), но до сих пор делают это свойство доступно, если вам переведите контекст на IObjectContextAdapter.

В случае вашей компании это звучит так, будто они пытаются использовать # 2, но по неправильным причинам. Они хотят скрыть реализации методов, а не потому, что метод не предполагается использовать, но потому, что они do ожидают, что он будет использоваться - и когда это так, они надеются, что это побудит разработчиков отделить их код от конкретные типы. Ваш пример кода указывает на отсутствие метки - разработчики все еще создают конкретные типы и затем бросают их, чтобы получить доступ к методам интерфейса.

+0

- 1. Да, именно по этой причине вы используете его для реализации, например IEnumerable и IEnumerable <>. 2. Интересно, правильно ли вы подходите к Интернет-провайдеру. ISP строго связан с интерфейсами. Это означает, что если вы можете разделить один интерфейс на два интерфейса, потому что потребитель не использует большую часть второго интерфейса, ему не нужно знать об этом. Явная реализация интерфейса не применяет ISP. Кроме того, нет, ISP не применяется там таким образом. То, что нужно разделить, разделяется, но не имеет явной реализации интерфейса. Это другой вопрос. –

+1

@Qudeid: Я думаю, что ISP относится к интерфейсам как к * концепции *, а не как к языковой конструкции. В этом смысле каждый конкретный тип предоставляет «интерфейсы» с различной видимостью на основе модификаторов конфиденциальности, и каждый реализованный им интерфейс также предоставляет другой «интерфейс» с видимостью на основе * его модификатора конфиденциальности. «Интерфейс» может определять только подмножество методов, реализуемых конкретным классом, и (используя явную реализацию интерфейса), класс может выставлять только подмножество своей общей доступной функциональности в качестве общедоступных методов. Вы видите, откуда я? – StriplingWarrior

+0

Естественно, что у класса есть интерфейс его публичных пользователей. Вопрос здесь всегда, чего я хочу достичь. Например, предложение кода из InBetween. Хотя это 100% действительный код и работает, это не значит, что это хороший код. Кодекс рассказывает историю, и поскольку больше людей, чем мне нужно читать (и мы читаем больше кода, чем мы пишем), очень важно рассказать свою историю приятный и блестящий и не путающий и двусмысленный. Btw. во время написания моего последнего комментария к этому ответу я не думал о том, что вы только что заявили о том, что интерфейсы являются языковыми конструкциями. Ты прав. –

Смежные вопросы