Re: Необходимость интерфейсов
От: Sinix  
Дата: 15.12.13 12:24
Оценка: 59 (5) +3
Здравствуйте, Аноним, Вы писали:

А>А вот когда проект внутренний. Когда есть в них необходимость?

А>Можно простой пример, который будет понятен?

Недавно было хорошее обсуждение
Автор:
Дата: 04.12.13
на эту же тему — посмотрите

Если говорить конкретно про дотнет, то интерфейсы — это способ явно описать контракт кода и отделить его (контракт) от реализации. Всё остальное — возможность смены реализации, возможность передавать интерфейсы в код на других языках, использование интерфейсов для описания сетевых сервисов — это уже следствия.


Плюсы интерфейсов: у вас появляется переиспользуемый жёстко задокументированный контракт и возможность заменить одну реализацию другой, не заботясь о том, что что-либо поломается.

Минусы: у вас появляется жёстко задокументированный контракт Во-первых, это дополнительный слой кода, который нужно сопровождать и поддерживать, причём стоимость его изменения выше стоимости исправления "обычных" классов. Во-вторых, нередко этот слой оказывается лишним. По крайней мере, до тех пор, пока в проекте нет реальной необходимости иметь полностью взаимозаменяемые реализации одного и того же поведения. Когда такая необходимость есть — к использованию интерфейсов (или наследования) приходят сами собой и ничего обосновывать не надо


Если посмотреть на BCL, то в ней интерфейсы практически не используются, за редкими удачными исключениями — IEnumerable/IComparer/IFormatable etc. Все они описывают минимально необходимый API для конкретного сценария использования. Чуть более "универсальные" интерфейсы, например IList/IDictionary etc заметно сложнее, в них торчат хвосты от предыдущих версий фреймворка. Не, серьёзно — кто использует dictionary.SyncRoot или list.IsReadOnly?

Всё что сложнее — это уже не интерфейсы, а базовые классы. Вот тут
Автор: Sinclair
Дата: 12.12.13
ув. Sinclair привёл очень хороший пример с наследованием от TextReader. Попробуйте придумать интерфейсы для Stream, TraceListener, xml-документа — неизбежно получится или интерфейс, дублирующий нюансы конкретной реализации, или сборник мелких интерфейсов, которые, опять-таки, проще реализовать в базовом классе, чем реализовывать их раз за разом в отдельных наследниках.

Отдельная тема — тестирование. Лично я к "интерфейсы нужны для беспроблемного тестирования" отношусь очень скептически.

Во-первых, ради решения одной задачи (причём не имеющей никакого отношения к предметной области софта) создаются проблемы для всего остального кода.
Во-вторых, для тестирования вовсе необязателен перевод всего на интерфейсы. Эту же задачу решают наследование от всё тех же базовых классов, или мок-фреймворки аля moles/MS fakes.
В-третьих, такое тестирование слоёв находит очень узкий круг проблем — снизу подпирают простые юнит-тесты и ассерты, сверху — интеграционное тестирование и всё те же ассерты.
Конечно, стоит ли связываться с интерфейсами чисто ради тестируемости кода или нет — зависит от конкретного проекта, но в общем случае — я резко против
Re[2]: Необходимость интерфейсов
От: IT Россия linq2db.com
Дата: 16.12.13 17:59
Оценка: +8
Здравствуйте, Tom, Вы писали:

Tom>Если в тестах надо эмулировать их поведение то единственный кошерный способ это использование IoC & DI принципов


Уважаемый, не говорите ерунды. Единственный кошерный способ (и тебе об этом уже не раз говорили) это чистая функция — принимаем всё как параметры, возвращаем всё как возвращаемое значение, работаем без артефактов и побочных эффектов, не используем глобальный контекст.
Если нам не помогут, то мы тоже никого не пощадим.
Re[3]: Необходимость интерфейсов
От: IT Россия linq2db.com
Дата: 17.12.13 02:09
Оценка: 12 (2) +3
Здравствуйте, MozgC, Вы писали:

Никого не слушай. У DI весьма специфическое реальное применение — в плагинных архитектурах и приложения, которые к моменту своего выполнения понятия не имеют чего они там будут выполнять. Остальное — overdesign. DI для тестов это очень чёткий и вполне одназначный признак такой архитектуры.

А судя по нашим оппонентам на этом форуме, у меня складывается впечатление, что DI — это ещё и ловушка для ума, эдакая петля захвата. Если в неё попадает неокрепший ум, то выбраться из неё крайне сложно, потому что у таких умов возникает чувство собственной просветлённости, хотя по сути речь идёт о косвенном вызове метода. В результате получаются люди с искалеченной DI'ем судьбой
Если нам не помогут, то мы тоже никого не пощадим.
Re[3]: Необходимость интерфейсов
От: IncremenTop  
Дата: 16.12.13 18:01
Оценка: -3 :)
Здравствуйте, IT, Вы писали:

IT>Единственный кошерный способ (и тебе об этом уже не раз говорили) это чистая функция


Это первый признак говнокода, если речь об ОО-языке.
Re[4]: Необходимость интерфейсов
От: IT Россия linq2db.com
Дата: 16.12.13 18:12
Оценка: +3 -1
Здравствуйте, IncremenTop, Вы писали:

IT>>Единственный кошерный способ (и тебе об этом уже не раз говорили) это чистая функция

IT>Это первый признак говнокода, если речь об ОО-языке.

А это первый признак зашоренности мышления, идолопоклонничества и восприятия мира через замочную скважину. Открой двери, станет лучше видно. ОО здесь вообще по боку.
Если нам не помогут, то мы тоже никого не пощадим.
Re[3]: Необходимость интерфейсов
От: Tom Россия http://www.RSDN.ru
Дата: 16.12.13 22:47
Оценка: :)))
Здравствуйте, MozgC, Вы писали:

MC>Здравствуйте, Tom, Вы писали:


Tom>>единственный кошерный способ это использование IoC & DI принципов


MC>Только у меня неприятие IoC-контейнеров? Мне кажется это какая-то мода, которая создаёт свои проблемы и без чего можно прекрасно обойтись. Особо меня пугает, что в некоторых книгах (например Pro ASP.NET MVC 4 by Adam Freeman (в целом книга неплохая)) применение IoC-контейнеров идет по умолчанию и преподносится как что-то само собой разумеещееся. Со мной что-то не так и мне надо лучше вникать в IoC-контейнеры или всё нормально? Хотелось бы мнения уважаемых опытных разработчиков.


С тобой всё абсолютно так. Это нормальная ПЕРВАЯ реакция.
Понимание этих принципов идёт через понимание проблем которые они призваны решать.
Вообще я не видел ещё ни одного девелопера который бы сразу проникса этой идеей.
Просветление наступает по поим наблюдениям от полу года до пары лет.
Причём чем младше девелопер тем проще ему перестраиваться.
Некоторые никогда не перестраиваются.
Народная мудрось
всем все никому ничего(с).
Re[4]: Необходимость интерфейсов
От: Visor2004  
Дата: 17.12.13 13:06
Оценка: +1 -1 :)
Здравствуйте, IT, Вы писали:

IT>А судя по нашим оппонентам на этом форуме, у меня складывается впечатление, что DI — это ещё и ловушка для ума, эдакая петля захвата. Если в неё попадает неокрепший ум, то выбраться из неё крайне сложно, потому что у таких умов возникает чувство собственной просветлённости, хотя по сути речь идёт о косвенном вызове метода. В результате получаются люди с искалеченной DI'ем судьбой


не надо путать DI и IoC, не смотря на то, что они парами ходят — это вообще две разные вещи. Inversion of control — это проекция SOA принципов построения программных систем на современные фреймворки, что само по себе достаточно фундаментально и существует не первый десяток лет. А dependency injection — это особенность реализации большинства современных контейнеров, она получила широкое распространение всего пару лет назад и действительно является злом, т.к. control flow становится очень сильно не очевидным и соответственно слабоподдерживаемым.
Помните!!! ваш говнокод кому-то предстоит разгребать.
Re[8]: Необходимость интерфейсов
От: Flem1234  
Дата: 18.12.13 11:50
Оценка: +3
Здравствуйте, Tom, Вы писали:

Tom>Поскипано.

Tom>Игорь давай ты воспроизведи полностью пример а потом поговорим о плюсах каждого подхода.
Tom>Иначе это опять ковыряние вносу на киселе...

А какие требования к решению?
Требованию воспроизведи полностью пример удовлетворяет только копия твоего кода.
Re[6]: Необходимость интерфейсов
От: SergeyT. США http://sergeyteplyakov.blogspot.com/
Дата: 29.12.13 20:21
Оценка: 30 (1) +1
Здравствуйте, IncremenTop, Вы писали:

ST>> здравый смысл говорит, что чистая функция будет проще с точки зрения всех сложностей, поскольку все, что идет на вход и является результатом является очевидным!


IT>С точки зрения сложности, то функция в которой или для которой создается объект и работающая с ним без интерфейса — это ад и израиль. Это не гибко, не читаемо, трудно поддерживается.


Хм... Я понимаю, что мы здесь теряем контекст рассуждения, но все небезызвестные ОО товарищи (Мейер, Фаулер, Эванс, Сииман) считают, что вводить интерфейсы и полиморфное поведение нужно лишь тогда, когда это требуется. К тому же, "гибко" и "трудно поддерживается" всегда идут рука об руку; за гибкость всегда нужно платить сложностью, без этого ни как (см. Who Needs an Architect Файлера в качестве примера рассуждения на эту тему).

Очень интересно, что отсутствие побочных эффектов рьяно популяризируется сторонниками ФП мира, но как-то многие забывают, что ключевые гуру ОО мира придерживаются этой же стратегии. Во-первых, существует небезызвестный в мире DDD принцип разделения команд и запросов (a.k.a. command query separation principle), предложенный все тем же Мейером, суть которого состоит в том, что мы должны четко разделять команды и запросы, при этом последние не должны менять состояние не в коем случае.

Еще, не менее интересным моментом является то, что Эрик Эванс, ключевой популяризатор DDD считает Side-Effect Free Function основой борьбы со сложностью и основой Model-Driven Design. Вот что он пишет по этому поводу:

Obviously, you can't avoid commands in most software systems, but the problem can be mitigated in two ways. First, you can keep the commands and queries strictly segregated in different operations.... Second, there are often alternative models and designs that do not call for an existing object to be modified at all. Instead a new VALUE OBJECT, representing the result of the computation, is created and returned. This is a common technique ... A VALUE OBJECT can be created in answer to a query, handed off, and forgotten — unlike an ENTITY, whose life cycle is carefully regulated.
... Therefore:
[b]Place as much of the logic of the program as possible into functions, operations that return results with no observable side effects. ... Further control side effects by moving complex logic into VALUE OBJECTS when a concept fitting the responsibility presents itself.


При этом Эванс прав, практически всегда этот "другой дизайн" найти можно и заменить код с горой интерфейсов, а значит и необъятным состоянием в набор VALUE OBJECT-ов и статических функций без побочных эффектов.

Как раз такой пример я разбирал в статье: Тестируемый дизайн vs. Хороший дизайн и именно такому подходу я следую в реальных проектах.


ST>>(да, другой вопрос, что чистые функции не всегда возможны, но где возможны, это лучший инструмент).

IT>Вы про промышленный код или про гномиков?
В каком-то обсуждении я уже упоминал о том, что отсутствие побочных эффектов является одним из фундаментальных основ довольно известной нынче парадигмы программирования, с помощью которой уже построены сотни и тысячи систем и которая оставила неизгладимый след на дизайн довольно известных .NET библиотек, таких как LINQ или Rx, а также является ключевой характеристикой дизайна Розлина. Так что я точно про промышленный код
Re: Необходимость интерфейсов
От: Tom Россия http://www.RSDN.ru
Дата: 16.12.13 12:16
Оценка: +2
А>Когда есть в них необходимость?
А>Можно простой пример, который будет понятен?
Когда начинаешь писать тесты на свой код и в тестах надо подменить одну реализацию другой.
Например когда у тебя класс работает с базой а в тесте по какой то причине надо его подменить что блы например вернуть результат не из базы а тот что тебе нужен в тесте.
Веб сервисы, различные дефайсы, файлы всё в ту же оперу. Если в тестах надо эмулировать их поведение то единственный кошерный способ это использование IoC & DI принципов

Вообще применение DI даёт намного больше.

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

2.
Применяя IoC & DI и желательно контейнер твой код становится бесплатно расширяем. Ибо любую реализацию можно поменять извне.

3.
Написание тестов становится на порядки проще, ибо опять же любую реализацию любого класса можно заменить

Итд итп
Народная мудрось
всем все никому ничего(с).
Re[3]: Необходимость интерфейсов
От: IT Россия linq2db.com
Дата: 16.12.13 19:11
Оценка: +2
Здравствуйте, MozgC, Вы писали:

MC>Особо меня пугает, что в некоторых книгах (например Pro ASP.NET MVC 4 by Adam Freeman (в целом книга неплохая)) применение IoC-контейнеров идет по умолчанию и преподносится как что-то само собой разумеещееся.


Коммерсанты Ему нужно продавать свои книжки. А кому нужен простой и понятный код без наворотов? А вот если туда пару паттернов вкрутить да по модней, до по раскрученней, то будет в самый раз.

Мне вся эта суета вокруг DI напоминает мою молодость, когда мы нереально пёрлись от косвенной адресации в целом и косвенных вызовов в частности, пока не поумнели и не стали их применять только по делу. Теперь молодёжь (местами запоздалая) нереально прётся от косвенности вызовов, но только уже через интерфейсы. Раз смог понять такой концепт, то жизнь вроде как удалась и можно считать себя крутым профиперцем.
Если нам не помогут, то мы тоже никого не пощадим.
Re[4]: Необходимость интерфейсов
От: IT Россия linq2db.com
Дата: 17.12.13 01:42
Оценка: +2
Здравствуйте, Tom, Вы писали:

Tom>Давай на конкретных примерах.


Ага, и сразу сериальный порт. А где же DateTime.Now?

Tom>Накидал простейший пример, думаю коментарии не нужны.

Tom>Перереши его так как считаешь нужным:

Блин, ну вы как дети малые

IEnumerable<Message> Process(MessageParser parser, IEnumerable<byte> sequence)
{
    var message = new List<byte>();

    foreach (var b in sequence)
    {
        message.Add(b);

        if (parser.IsEom(b))
            yield return parser.Parse(message);
    }
}

И прошу заметить, не понадобилось ни одного кастомного интерфейса.
Если нам не помогут, то мы тоже никого не пощадим.
Re[9]: Необходимость интерфейсов
От: IT Россия linq2db.com
Дата: 18.12.13 01:23
Оценка: +2
Здравствуйте, Tom, Вы писали:

Tom>В чём проблема полностью повторить мой код но с использованием твоего подхода?


Привести не проблема. Проблема в том, что пример твой не полный. Хочешь класс порт? Пожалуйста:

public class SerialPort : ISerialPort
{
    public IEnumerable<byte> ReadBytes()
    {
        yield return 1;
    }
}

Только это ничего не даёт. Ни твой ни мой код не компилируется и главное в них отсутствует самая важная часть — тест, о котором мы больше всего здесь спорим. Если хочешь нормального обсуждения, то напиши работающий пример в виде консольного приложения с тестом, с моками и остальными свистелками. Я его переделаю на свой манер.
Если нам не помогут, то мы тоже никого не пощадим.
Re[9]: Необходимость интерфейсов
От: IT Россия linq2db.com
Дата: 18.12.13 20:29
Оценка: +1 :)
Здравствуйте, Flem1234, Вы писали:

F>А какие требования к решению?

F>Требованию воспроизведи полностью пример удовлетворяет только копия твоего кода.

Ему уже не решение нужно, а повод отказаться от дискуссии желательно под предлогом неадекватности оппонента. Из моего примера и так всем понятно, что без DI можно легко и просто обойтись, получив при этом даже некоторые преимущества в виде корректно работающего кода.
Если нам не помогут, то мы тоже никого не пощадим.
Re[5]: Необходимость интерфейсов
От: IT Россия linq2db.com
Дата: 30.12.13 15:01
Оценка: +2
Здравствуйте, Аноним, Вы писали:

А>а можно пример как должен выглядеть код класса Репозиторий, чтобы он был тестируем независимо от контекста и при этом не привязан к DI?


А можно объяснить зачем мне репозиторий и почему именно в таком неприглядном виде?
Если нам не помогут, то мы тоже никого не пощадим.
Re[3]: Необходимость интерфейсов
От: QrystaL Украина  
Дата: 16.12.13 18:55
Оценка: 6 (1)
Здравствуйте, MozgC, Вы писали:
MC>мне надо лучше вникать в IoC-контейнеры?

Да, для начала прочитать части 1-3 этой книги: DI in .NET

MC>Хотелось бы мнения уважаемых опытных разработчиков.


Jimmy Bogard достаточно уважаем?

DI is about creating highly flexible components, both in lifecycle and component selection. DI removes component resolution responsibilities from classes, therefore removing code. And less code is ALWAYS a good thing.


http://lostechies.com/jimmybogard/2010/05/20/the-religion-of-dependency-injection/
Re[4]: Необходимость интерфейсов
От: SergeyT. США http://sergeyteplyakov.blogspot.com/
Дата: 16.12.13 18:14
Оценка: +1
Здравствуйте, IncremenTop, Вы писали:


IT>>Единственный кошерный способ (и тебе об этом уже не раз говорили) это чистая функция


IT>Это первый признак говнокода, если речь об ОО-языке.


Есть Command-Query Separation Principle, но даже в нем Query является чистым, т.е. без побочных эффектов. Стало очень любопытно, с точки зрения чего или кого чистые функции стали говногодом в ОО-языке? ОО гуру вроде Мейера, вроде бы, так не считают; здравый смысл говорит, что чистая функция будет проще с точки зрения всех сложностей, поскольку все, что идет на вход и является результатом является очевидным!

Поддержу Игоря, чистые функции — это идеальный инструмент композиции, проверенные раз, чистые функции будут работать в любом контексте (да, другой вопрос, что чистые функции не всегда возможны, но где возможны, это лучший инструмент).
Re[5]: Необходимость интерфейсов
От: IT Россия linq2db.com
Дата: 16.12.13 18:23
Оценка: +1
Здравствуйте, SergeyT., Вы писали:

ST>(да, другой вопрос, что чистые функции не всегда возможны, но где возможны, это лучший инструмент).


На самом деле чистую функцию вполне возможно воспринимать как паттерн. Также как в ОО-языках можно писать immutable код без специальной языковой поддержки, точно так же можно писать и чистый код без артефактов и использования глобального контекста. А внутренняя реализация такой "функции" вполне может использовать и даже базироваться на классах. Тут вопрос больше в мышлении, а не в ключевом слове "class". Но видимо у некоторых в голове это ключевое слово гвоздями прибито к облачкам Буча.
Если нам не помогут, то мы тоже никого не пощадим.
Re[4]: Необходимость интерфейсов
От: IT Россия linq2db.com
Дата: 16.12.13 19:13
Оценка: +1
Здравствуйте, QrystaL, Вы писали:

QL>Да, для начала прочитать части 1-3 этой книги: DI in .NET


В этой книжке есть хотя бы пол обзаца о недостатках DI? Нет? Тогда ей место на гвоздике в туалете.
Если нам не помогут, то мы тоже никого не пощадим.
Re[5]: Необходимость интерфейсов
От: IncremenTop  
Дата: 17.12.13 04:16
Оценка: :)
Здравствуйте, IT, Вы писали:

IT>А это первый признак зашоренности мышления, идолопоклонничества и восприятия мира через замочную скважину. Открой двери, станет лучше видно. ОО здесь вообще по боку.


Конечно, когда надо поддерживать проект с говнокодом, то мигом незашоренные люди смываются с проекта, ибо даже они не собираются разбираться в том, что накодили. Конечно ОО по боку, если плевать на чем писать, то явно получится говнокод очередного незашоренного человека.
Re[6]: Необходимость интерфейсов
От: IT Россия linq2db.com
Дата: 17.12.13 15:13
Оценка: +1
Здравствуйте, Tom, Вы писали:

IT>>И прошу заметить, не понадобилось ни одного кастомного интерфейса.

Tom>Эээ так у тебя пример не полный.
Tom>Где сам девайс в твоём примере то?

Возьми свой и прикрути к нему энумератор. Научить как это делается?

Кстати, я не знаю как ты собираешься тестировать свой код с бесконечным циклом. Как будешь прерывать его выполнение, с помощью AbortException? Мой код тестировать элементарно, не нужно даже фейковые объекты создавать, просто передать в качестве входной последовательности тестовый массив байт. Результат тоже проверить элементарно и тоже без фековых объектов.
Если нам не помогут, то мы тоже никого не пощадим.
Re[5]: Необходимость интерфейсов
От: IT Россия linq2db.com
Дата: 17.12.13 15:18
Оценка: +1
Здравствуйте, Visor2004, Вы писали:

V>не надо путать DI и IoC,


В каком конкретном месте я напутал?

V>А dependency injection — это особенность реализации большинства современных контейнеров, она получила широкое распространение всего пару лет назад и действительно является злом, т.к. control flow становится очень сильно не очевидным и соответственно слабоподдерживаемым.


Это ты расскажи апологетам DI. Для них DI это всё, что передаётся объекту в параметрах конструктора или через свойства. Потому что они не передают параметры, а инжектять зависимости.
Если нам не помогут, то мы тоже никого не пощадим.
Re[7]: Необходимость интерфейсов
От: IT Россия linq2db.com
Дата: 30.12.13 16:03
Оценка: :)
Здравствуйте, Аноним, Вы писали:

IT>>А можно объяснить зачем мне репозиторий и почему именно в таком неприглядном виде?

А>к одной базе могут подключаться: сайт, экзе и мобильное приложение.

И...?

А>а чем он непригляден?


Тем что он гвоздями прибит к Linq, а Linq устраняет необходимость в этом паттерне, так же как и в DAL.
Если нам не помогут, то мы тоже никого не пощадим.
Re[4]: Необходимость интерфейсов
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 03.01.14 00:30
Оценка: +1
Здравствуйте, Visor2004, Вы писали:

V>бОльшая часть продуктов MS написаны с использованием IoC контейнеров.


Крайне спорно. Мне вот так навскидку вспоминается только MEF, который не пинает только ленивый за черезмерные навороты на ровном месте.

V>Самый лучший и простой IoC контейнер, который невозможно не понять называется IServiceProvider и лежит в простарнстве имен System


IServiceProvider это не контейнер, это старый добрый service locator. Да и его применять в тех ситуациях, когда можно статически все зависимости разресолвить не стоит. Применяется он в основном к компонентной модели, где, понятное дело, ни о каких статических зависимостях речи не идет.
... << RSDN@Home 1.2.0 alpha 5 rev. 100 on Windows 8 6.2.9200.0>>
AVK Blog
Необходимость интерфейсов
От: Аноним  
Дата: 14.12.13 13:45
Оценка:
Единственно понимаю, что они нужны когда ты пишешь какой то класс, с которым могут работать внешние клиенты. тогда да. Надо чтобы они могли только вызывать задокументированные методы. Чтобы не могли что-то изменить по своему усмотрению.

А вот когда проект внутренний. Когда есть в них необходимость?
Можно простой пример, который будет понятен?
Re: Необходимость интерфейсов
От: ZloeBablo Германия  
Дата: 14.12.13 15:15
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Единственно понимаю, что они нужны когда ты пишешь какой то класс, с которым могут работать внешние клиенты. тогда да. Надо чтобы они могли только вызывать задокументированные методы. Чтобы не могли что-то изменить по своему усмотрению.


А>А вот когда проект внутренний. Когда есть в них необходимость?

А>Можно простой пример, который будет понятен?

А какая разница? Если проект внутренний то клиентом является ты сам. И то как ты спроектируешь все будет напрямую отражаться на поддержке и удобстве использования...
Re[2]: Необходимость интерфейсов
От: Аноним  
Дата: 16.12.13 17:42
Оценка:
Здравствуйте, Tom, Вы писали:



Tom>2.

Tom>Применяя IoC & DI и желательно контейнер твой код становится бесплатно расширяем. Ибо любую реализацию можно поменять извне.

нифига вот непросто подсунуть HttpContext в тестах.
asp.net mvc
Re[2]: Необходимость интерфейсов
От: MozgC США http://nightcoder.livejournal.com
Дата: 16.12.13 18:44
Оценка:
Здравствуйте, Tom, Вы писали:

Tom>единственный кошерный способ это использование IoC & DI принципов


Только у меня неприятие IoC-контейнеров? Мне кажется это какая-то мода, которая создаёт свои проблемы и без чего можно прекрасно обойтись. Особо меня пугает, что в некоторых книгах (например Pro ASP.NET MVC 4 by Adam Freeman (в целом книга неплохая)) применение IoC-контейнеров идет по умолчанию и преподносится как что-то само собой разумеещееся. Со мной что-то не так и мне надо лучше вникать в IoC-контейнеры или всё нормально? Хотелось бы мнения уважаемых опытных разработчиков.
Re[6]: Необходимость интерфейсов
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 16.12.13 18:47
Оценка:
Здравствуйте, IT, Вы писали:

IT>Но видимо у некоторых в голове это ключевое слово гвоздями прибито к облачкам Буча.


У Буча, кстати, не все так однозначно и прямолинейно.
... << RSDN@Home 1.2.0 alpha 5 rev. 100 on Windows 8 6.2.9200.0>>
AVK Blog
Re[5]: Необходимость интерфейсов
От: IncremenTop  
Дата: 16.12.13 18:58
Оценка:
Здравствуйте, SergeyT., Вы писали:

ST> здравый смысл говорит, что чистая функция будет проще с точки зрения всех сложностей, поскольку все, что идет на вход и является результатом является очевидным!


С точки зрения сложности, то функция в которой или для которой создается объект и работающая с ним без интерфейса — это ад и израиль. Это не гибко, не читаемо, трудно поддерживается.


ST>(да, другой вопрос, что чистые функции не всегда возможны, но где возможны, это лучший инструмент).

Вы про промышленный код или про гномиков?
Re[4]: Необходимость интерфейсов
От: QrystaL Украина  
Дата: 16.12.13 20:04
Оценка:
Здравствуйте, IT, Вы писали:
IT>пока не поумнели и не стали их применять только по делу.

Ну то же самое и с DI. В вышеозначенной книге есть глава по этому поводу — 1.3
Re[3]: Необходимость интерфейсов
От: Visor2004  
Дата: 16.12.13 20:19
Оценка:
Здравствуйте, MozgC, Вы писали:

MC>Только у меня неприятие IoC-контейнеров? Мне кажется это какая-то мода, которая создаёт свои проблемы и без чего можно прекрасно обойтись. Особо меня пугает, что в некоторых книгах (например Pro ASP.NET MVC 4 by Adam Freeman (в целом книга неплохая)) применение IoC-контейнеров идет по умолчанию и преподносится как что-то само собой разумеещееся. Со мной что-то не так и мне надо лучше вникать в IoC-контейнеры или всё нормально? Хотелось бы мнения уважаемых опытных разработчиков.


бОльшая часть продуктов MS написаны с использованием IoC контейнеров. Это очень мощная штука, но как и любая мощная штука она имеет свой порог вхождения и он достаточно высок. Отдельно надо понимать, что DI — это совсем другая штука, которая появилась не так давно и вот от нее уже на мой взгляд больше вреда, чем пользы. Самый лучший и простой IoC контейнер, который невозможно не понять называется IServiceProvider и лежит в простарнстве имен System
Помните!!! ваш говнокод кому-то предстоит разгребать.
Re[5]: Необходимость интерфейсов
От: IT Россия linq2db.com
Дата: 16.12.13 20:28
Оценка:
Здравствуйте, QrystaL, Вы писали:

IT>>пока не поумнели и не стали их применять только по делу.

QL>Ну то же самое и с DI. В вышеозначенной книге есть глава по этому поводу — 1.3

Применение DI для тестирования — это уже не то же самое.
Если нам не помогут, то мы тоже никого не пощадим.
Re[3]: Необходимость интерфейсов
От: Tom Россия http://www.RSDN.ru
Дата: 16.12.13 22:33
Оценка:
Здравствуйте, IT, Вы писали:

IT>Здравствуйте, Tom, Вы писали:


Tom>>Если в тестах надо эмулировать их поведение то единственный кошерный способ это использование IoC & DI принципов


IT>Уважаемый, не говорите ерунды. Единственный кошерный способ (и тебе об этом уже не раз говорили) это чистая функция — принимаем всё как параметры, возвращаем всё как возвращаемое значение, работаем без артефактов и побочных эффектов, не используем глобальный контекст.


Давай на конкретных примерах.
Я пример как бы сделал я — ты пример как бы сделал ты.
Потом обсудим оба. так будет лучше чем чесание языка.
Накидал простейший пример, думаю коментарии не нужны.
Перереши его так как считаешь нужным:


    public interface ISerialPort
    {
        byte ReadByte();
    }

    public class SerialPort : ISerialPort
    {
        public byte ReadByte()
        {
            return 1;
        }
    };

    public interface IMessage
    {
        // ...
    }

    public interface IMessageParser
    {
        bool IsEom(byte b);
        IMessage Parse(IEnumerable<byte> rawMessage);
    }

    public interface IMessageProcessor
    {
        void ProcessMessage(IMessage message);
    }

    public class MessageProcessor
    {
        public void ProcessMessage(IMessage message)
        {
            // E.g. save 2 database or trace to the file or anything
        }
    }

    public interface ISerialPortProcessor
    {
        void ReadAndProcessLoop();
    }

    public class SerialPortProcessor : ISerialPortProcessor
    {
        private readonly ISerialPort _port;
        private readonly IMessageParser _parser;
        private readonly IMessageProcessor _processor;

        public SerialPortProcessor(
            ISerialPort port,
            IMessageParser parser,
            IMessageProcessor processor)
        {
            _port = port;
            _parser = parser;
            _processor = processor;
        }

        public void ReadAndProcessLoop()
        {
            var message = new List<byte>();

            while (true)
            {
                var b = _port.ReadByte();
                message.Add(b);

                if (_parser.IsEom(b))
                {
                    var parsedMessage = _parser.Parse(message);

                    _processor.ProcessMessage(parsedMessage);
                }
            }
        }
    }
Народная мудрось
всем все никому ничего(с).
Re[3]: Необходимость интерфейсов
От: Аноним  
Дата: 17.12.13 04:35
Оценка:
Здравствуйте, IT, Вы писали:

IT>Здравствуйте, Tom, Вы писали:


Tom>>Если в тестах надо эмулировать их поведение то единственный кошерный способ это использование IoC & DI принципов


IT>Уважаемый, не говорите ерунды. Единственный кошерный способ (и тебе об этом уже не раз говорили) это чистая функция — принимаем всё как параметры, возвращаем всё как возвращаемое значение, работаем без артефактов и побочных эффектов, не используем глобальный контекст.


повторюсь.
как без глобального контекста (httpcontext) обойтись в asp.net mvc?
Re[6]: Необходимость интерфейсов
От: IT Россия linq2db.com
Дата: 17.12.13 04:56
Оценка:
Здравствуйте, IncremenTop, Вы писали:

IT>Конечно, когда надо поддерживать проект с говнокодом, то мигом незашоренные люди смываются с проекта, ибо даже они не собираются разбираться в том, что накодили. Конечно ОО по боку, если плевать на чем писать, то явно получится говнокод очередного незашоренного человека.


Ты это о ком?
Если нам не помогут, то мы тоже никого не пощадим.
Re[4]: Необходимость интерфейсов
От: IT Россия linq2db.com
Дата: 17.12.13 04:57
Оценка:
Здравствуйте, Аноним, Вы писали:

IT>>Уважаемый, не говорите ерунды. Единственный кошерный способ (и тебе об этом уже не раз говорили) это чистая функция — принимаем всё как параметры, возвращаем всё как возвращаемое значение, работаем без артефактов и побочных эффектов, не используем глобальный контекст.


А>повторюсь.

А>как без глобального контекста (httpcontext) обойтись в asp.net mvc?

Для чего он конкретно нужен в конкретном asp.net mvc проекте?
Если нам не помогут, то мы тоже никого не пощадим.
Re[3]: Необходимость интерфейсов
От: Аноним  
Дата: 17.12.13 05:25
Оценка:
Здравствуйте, IT, Вы писали:

IT>Здравствуйте, Tom, Вы писали:


Tom>>Если в тестах надо эмулировать их поведение то единственный кошерный способ это использование IoC & DI принципов


IT>Уважаемый, не говорите ерунды. Единственный кошерный способ (и тебе об этом уже не раз говорили) это чистая функция — принимаем всё как параметры, возвращаем всё как возвращаемое значение, работаем без артефактов и побочных эффектов, не используем глобальный контекст.


а можно статью или книгу где есть примеры как сделано с чистыми функциями и как тоже самое сделано с di?
Re[5]: Необходимость интерфейсов
От: Аноним  
Дата: 17.12.13 05:32
Оценка:
Здравствуйте, IT, Вы писали:

IT>Здравствуйте, Аноним, Вы писали:


IT>>>Уважаемый, не говорите ерунды. Единственный кошерный способ (и тебе об этом уже не раз говорили) это чистая функция — принимаем всё как параметры, возвращаем всё как возвращаемое значение, работаем без артефактов и побочных эффектов, не используем глобальный контекст.


А>>повторюсь.

А>>как без глобального контекста (httpcontext) обойтись в asp.net mvc?

IT>Для чего он конкретно нужен в конкретном asp.net mvc проекте?


из него берется данные о юзере. Своя реализация от IIdentity
Re[3]: Необходимость интерфейсов
От: Sinix  
Дата: 17.12.13 06:12
Оценка:
Здравствуйте, MozgC, Вы писали:

MC>Только у меня неприятие IoC-контейнеров?

Не только. IOC/DI — вполне хорошая штука, если использовать их по делу. Проблема в том, что у любой технологии есть свой порог сложности — затраты на изучение, внедрение в код, наработка лучших практик для конкретного проекта и т.д и т.п.. Если сложность решаемой задачи ниже порога сложности какой-либо технологии, то применять эту технологию очевидно бессмысленно. Ну, как привлекать боинг для развозки газет — для рекламы может и можно, но соседи будут точно недовольны

Поэтому набор удачных сценариев использования для IoC очень ограничен. Классический пример — расширяемость студии до перехода на MEF (до 2010й студии) и после.

MC>Мне кажется это какая-то мода, которая создаёт свои проблемы и без чего можно прекрасно обойтись.

Угу. Надо же на что-то переключаться после smart client/паттернов/экстремального программирования/веб-сервисов/noSQL/MVC/...
Re[5]: Необходимость интерфейсов
От: Tom Россия http://www.RSDN.ru
Дата: 17.12.13 11:10
Оценка:
IT>И прошу заметить, не понадобилось ни одного кастомного интерфейса.
Эээ так у тебя пример не полный.
Где сам девайс в твоём примере то?
Народная мудрось
всем все никому ничего(с).
Re[6]: Необходимость интерфейсов
От: Tom Россия http://www.RSDN.ru
Дата: 17.12.13 11:15
Оценка:
Здравствуйте, Tom, Вы писали:

IT>>И прошу заметить, не понадобилось ни одного кастомного интерфейса.

Tom>Эээ так у тебя пример не полный.
Tom>Где сам девайс в твоём примере то?
Да и обработчика сообщений я у тебя не вижу.
Перепиши пример полностью плиз.

PS:
У нас вроде была возможность редактировать сообщения когда то?
Народная мудрось
всем все никому ничего(с).
Re[5]: Необходимость интерфейсов
От: QrystaL Украина  
Дата: 17.12.13 13:18
Оценка:
Здравствуйте, Visor2004, Вы писали:
V>control flow становится очень сильно не очевидным и соответственно слабоподдерживаемым.

Это вы про Service Locator?
Re[5]: Необходимость интерфейсов
От: Sinix  
Дата: 17.12.13 13:44
Оценка:
Здравствуйте, Visor2004, Вы писали:

V>не надо путать DI и IoC, не смотря на то, что они парами ходят — это вообще две разные вещи.


Угу. Так уж сложилось, что DI/IoC используют как синоним для фреймворка, реализующего этот паттерн. По крайней мере, упоминание IoC в контексте "просто передаём нужный интерфейс (класс) через параметры" мне практически не попадалось.
Re[4]: Необходимость интерфейсов
От: IT Россия linq2db.com
Дата: 17.12.13 14:45
Оценка:
Здравствуйте, Аноним, Вы писали:

А>а можно статью или книгу где есть примеры как сделано с чистыми функциями и как тоже самое сделано с di?


Поищите где-нибудь в интернете.
Если нам не помогут, то мы тоже никого не пощадим.
Re[6]: Необходимость интерфейсов
От: IT Россия linq2db.com
Дата: 17.12.13 15:03
Оценка:
Здравствуйте, Аноним, Вы писали:

А>>>как без глобального контекста (httpcontext) обойтись в asp.net mvc?

IT>>Для чего он конкретно нужен в конкретном asp.net mvc проекте?
А>из него берется данные о юзере. Своя реализация от IIdentity

Большинство вещей связанных с авторизацией делаются атрибутами, поэтому прямой доступ к контексту не нужен. Если же непосредственный доступ к Identity необходим, то у контроллера есть вполне доступное нестатическое свойство User.

Но дело даже не в этом. Наличие статического контекста как такового не означает, что раз он есть и ниспослан нам свыше Майкрософтом, то это есть благо и его надо пихать куда только можно. Всегда можно локализовать подобную заразу и ограничить её распространение. Всего лишь не надо использовать такой контекст глубоко в классах бизнес логики. Можно передать необходимые данные в качестве параметров.

В .NET есть очень простой способ убедиться в том, что разрабатываемый компонент самодостаточен, независим и слабосвязан с другими частями системы. Такой компонент можно оформить в виде отдельной сборки и тщательно следить за недопущением в её референсы как всяких System.Web, так и собственных не относящихся к делу сборок. Попробуйте. Поначалу будет сложно обходиться без статики, но со временем к статическому контексту выработается устойчивое отвращение.
Если нам не помогут, то мы тоже никого не пощадим.
Re[7]: Необходимость интерфейсов
От: IT Россия linq2db.com
Дата: 17.12.13 15:15
Оценка:
Здравствуйте, Tom, Вы писали:

Tom>Да и обработчика сообщений я у тебя не вижу.

Tom>Перепиши пример полностью плиз.

Ну тогда давай и ты напиши свой пример полностью. Как минимум в нём нехватает то, а чём идёт спор — тестового метода.
Если нам не помогут, то мы тоже никого не пощадим.
Re[6]: Необходимость интерфейсов
От: Visor2004  
Дата: 17.12.13 21:07
Оценка:
Здравствуйте, IT, Вы писали:

IT>В каком конкретном месте я напутал?


ну... ты иногда пишешь IoC/DI, а иногда просто DI. Это не только из этой ветки, я видел несколько тем, где ты не лестно отзывался о них. И всегда текстовка была такая, что это мол все плохо и неудобно, как в случае написания IoC/DI так и просто DI, поэтому у меня сложилось впечатление, что ты эти вещи не разделяешь.

IT>Это ты расскажи апологетам DI. Для них DI это всё, что передаётся объекту в параметрах конструктора или через свойства. Потому что они не передают параметры, а инжектять зависимости.

фанатикам бесполезно что-то объяснять
Помните!!! ваш говнокод кому-то предстоит разгребать.
Re[7]: Необходимость интерфейсов
От: Tom Россия http://www.RSDN.ru
Дата: 17.12.13 22:31
Оценка:
Поскипано.
Игорь давай ты воспроизведи полностью пример а потом поговорим о плюсах каждого подхода.
Иначе это опять ковыряние вносу на киселе...
Народная мудрось
всем все никому ничего(с).
Re[8]: Необходимость интерфейсов
От: Tom Россия http://www.RSDN.ru
Дата: 17.12.13 22:32
Оценка:
IT>Ну тогда давай и ты напиши свой пример полностью. Как минимум в нём нехватает то, а чём идёт спор — тестового метода.
В чём проблема полностью повторить мой код но с использованием твоего подхода?
Если ты этого сделать не можеть не получится предметный разговор а получиться как обычно языкочесание.
Народная мудрось
всем все никому ничего(с).
Re: Необходимость интерфейсов
От: Silver_S Ниоткуда  
Дата: 29.12.13 17:01
Оценка:
Здравствуйте, Аноним, Вы писали:

А>А вот когда проект внутренний. Когда есть в них необходимость?

А>Можно простой пример, который будет понятен?

Интерфейсы имеет смысл использовать там где большие объемы кода. Поэтому простых примеров нет. Зависит от метрик кода.
Очевидный случай для применения интерфейса, когда высокая вероятность, что будет несколько очень разных реализаций, и реализации нет смысла наследовать.

А другие причины могут быть такими:

Например. если есть большое кусок кода, который обозначим функцией F:

void F(int[] p){...}
И если параметр можно заменить на более абстрактный интерфейс:
void F(IEnumerable<int> p){...}
То этот вариант лучше по 2 причинам:
1) Функция станет более универсальная, т.к. зависит от более абстрактного объекта. Легче найти новые применения. Больше повторная используемость.
2) Даже если известно, что только массивы будут передаваться.Сама функция легче читается,понимается. Т.к. в IEnumerable меньше деталей, чем в массиве — это снижает общую сложность функции.
Это актуально, если в функции не 10 строк кода, а 500 (даже не в самой, а всего вместе с вызываемым из нее кодом).

Пример для встроенных интерфейсов, а для своих тоже самое.
Если есть объект. И если образовалось 2 куска кода, в каждом по 1000 строк. Эти куски используют разные подмножества объекта. Объект разделить нельзя. Например, один кусок использует объект как readOnly, второй с записью.
Тогда имеет смысл ввести 2 интерфейса, для каждого куска. Даже если у интерфейсов только одна реализация планируется. Если в этих кусках кода не 1000, а 50 строк, то здесь от введения интерфейсов будет больше вреда.
Re[6]: Необходимость интерфейсов
От: Kudriako Украина  
Дата: 29.12.13 17:51
Оценка:
Здравствуйте, Аноним, Вы писали:

А>>>как без глобального контекста (httpcontext) обойтись в asp.net mvc?


IT>>Для чего он конкретно нужен в конкретном asp.net mvc проекте?


А>из него берется данные о юзере. Своя реализация от IIdentity


Не понимаю, в чем там такая трудность то? Вот пример кода тестирующего контроллер. И именно на предмет работы с IIdentity
Код изменен в сторону упрощения.

using Moq;

...
var userName = "Vasya";
var contextMock = new Mock<ControllerContext>();
contextMock.SetupGet(p => p.HttpContext.User.Identity.Name).Returns(userName);
contextMock.SetupGet(p => p.HttpContext.Request.IsAuthenticated).Returns(true);
var controller = new HomeController() {
    СontrollerContext = contextMock.Object,
};
Re[4]: Необходимость интерфейсов
От: Аноним  
Дата: 30.12.13 07:59
Оценка:
Здравствуйте, IT, Вы писали:

IT>Здравствуйте, MozgC, Вы писали:


IT>Никого не слушай. У DI весьма специфическое реальное применение — в плагинных архитектурах и приложения, которые к моменту своего выполнения понятия не имеют чего они там будут выполнять. Остальное — overdesign. DI для тестов это очень чёткий и вполне одназначный признак такой архитектуры.


IT>А судя по нашим оппонентам на этом форуме, у меня складывается впечатление, что DI — это ещё и ловушка для ума, эдакая петля захвата. Если в неё попадает неокрепший ум, то выбраться из неё крайне сложно, потому что у таких умов возникает чувство собственной просветлённости, хотя по сути речь идёт о косвенном вызове метода. В результате получаются люди с искалеченной DI'ем судьбой


а можно пример как должен выглядеть код класса Репозиторий, чтобы он был тестируем независимо от контекста и при этом не привязан к DI?


public class MyRepository : IRepository 
{

  private readonly IDbLinqContext _context;
  public MyRepository(IDbLinqContext context)
  {
    _context = context;
  }

  public IQueryable<My> Get()
  {
    return _context.My.All();
  }
}
Re[6]: Необходимость интерфейсов
От: Аноним  
Дата: 30.12.13 15:47
Оценка:
Здравствуйте, IT, Вы писали:

IT>Здравствуйте, Аноним, Вы писали:


А>>а можно пример как должен выглядеть код класса Репозиторий, чтобы он был тестируем независимо от контекста и при этом не привязан к DI?


IT>А можно объяснить зачем мне репозиторий и почему именно в таком неприглядном виде?


к одной базе могут подключаться: сайт, экзе и мобильное приложение.

а чем он непригляден?
Re[8]: Необходимость интерфейсов
От: Аноним  
Дата: 30.12.13 18:14
Оценка:
Здравствуйте, IT, Вы писали:

IT>Здравствуйте, Аноним, Вы писали:


IT>>>А можно объяснить зачем мне репозиторий и почему именно в таком неприглядном виде?

А>>к одной базе могут подключаться: сайт, экзе и мобильное приложение.

IT>И...?


как один DAL использовать в разных приложениях?
мобильное приложение разрабатывает другая компания вообще, так что они видят только dll в Nuget


А>>а чем он непригляден?


IT>Тем что он гвоздями прибит к Linq, а Linq устраняет необходимости в этом паттерне, так же как и в DAL.


название неудачно тут написал. так я интерфейс передаю IDbcontext
Re[9]: Необходимость интерфейсов
От: IT Россия linq2db.com
Дата: 30.12.13 18:23
Оценка:
Здравствуйте, Аноним, Вы писали:

А>как один DAL использовать в разных приложениях?


Так это не DAL, это репозиторий.

А>мобильное приложение разрабатывает другая компания вообще, так что они видят только dll в Nuget


DLL в которой перечислен список сущностей со стандартным набором методов общего назначения типа GetAll? И как интересно такая мобилка делает какой-нибудь JOIN? высасывает с сервера через мобильный трафик две таблицы и джоинит их у себя в мобильной памяти?

IT>>Тем что он гвоздями прибит к Linq, а Linq устраняет необходимости в этом паттерне, так же как и в DAL.

А>название неудачно тут написал. так я интерфейс передаю IDbcontext

Дело не в контексте, а в IQueryable.

Кстати, каким образом используется IQueryable на мобилке? Неужели там уже заработал Expression Tree?
Если нам не помогут, то мы тоже никого не пощадим.
Re[4]: Необходимость интерфейсов
От: akasoft Россия  
Дата: 08.01.14 10:53
Оценка:
Здравствуйте, Tom, Вы писали:

Tom>Понимание этих принципов идёт через понимание проблем которые они призваны решать.


Это, кстати, везде так.

Tom>Вообще я не видел ещё ни одного девелопера который бы сразу проникса этой идеей.

Tom>Просветление наступает по поим наблюдениям от полу года до пары лет.
Tom>Причём чем младше девелопер тем проще ему перестраиваться.
Tom>Некоторые никогда не перестраиваются.

Человек с годами всё больше доверяет собственному накопленному опыту, накапливает собственную харизму и переубедить его совсем не просто. И это нормально. Но опять же, это характерно для людей вообще, а никак не исключительно для программистов или IoC/DI.
... << RSDN@Home 1.2.0 alpha 5 rev. 66>> SQL Express 2012
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.