Принцип инверсии зависимости
От: Аноним  
Дата: 04.12.13 16:29
Оценка:
здесь


Принцип инверсии зависимостей (англ. Dependency Inversion Principle, DIP) — важный принцип объектно-ориентированного программирования, используемый для уменьшения связанности в компьютерных программах. Входит в пятёрку
принципов SOLID.

Формулировка
Модули верхних уровней не должны зависеть от модулей нижних уровней. Оба типа модулей должны зависеть от абстракций.
Абстракции не должны зависеть от деталей. Детали должны зависеть от абстракций.



Модули верхних уровней не должны зависеть от модулей нижних уровней. Оба типа модулей должны зависеть от абстракций.
Это как , т.е. моя программа не должна зависеть от библиотек .net ?


Абстракции не должны зависеть от деталей. Детали должны зависеть от абстракций.

Абстракция — что такое ?

IUnknown — это абстракция.

А вот ISome
{
void Some();

}

Это уже детали.что есть метод Some типа void и который не принимает параметров.

Ведь мог быть int Some( string data ).
Re: Принцип инверсии зависимости
От: Sinix  
Дата: 05.12.13 05:27
Оценка: 77 (4) +1
Здравствуйте, Аноним, Вы писали:

А>Модули верхних уровней не должны зависеть от модулей нижних уровней. Оба типа модулей должны зависеть от абстракций.

А>Это как , т.е. моя программа не должна зависеть от библиотек .net ?
Нет. Если конечно у вас нет цели запускать код в произвольной версии фреймворка/mono/xamarin Тогда придётся ограничиться portable class library.

Речь о том, что код в каждом уровне не должен закапываться в детали реализации нижнего. Это важно по двум причинам:
1. В коде смешиваются ответственности, например, один и тот же метод начинает настраивать соединение к БД, показывать окно соединения и поздравлять пользователя с днём рождения (не придумываю, я такое видел ).
2. В принципе универсальный код начинает подстраиваться под используемый фреймворк. Например, в стандартном TraceSource логирование вложенных операций сделано мягко говоря фигово, т.е. никак. В результате посреди бизнес-кода начинается копание в кишках аля
            try
            {
                Trace.CorrelationManager.StartLogicalOperation();
                traceSource.TraceEvent(TraceEventType.Start, 0, "...");

                // ...
            }
            finally
            {
                traceSource.TraceEvent(TraceEventType.Stop, 0, "...");
                Trace.CorrelationManager.StopLogicalOperation();
            }


вместо вполне логичного
            using (tracer.BeginOp("..."))
            {
                // ...
            }


Бизнес-код не интересуют кишки. Для биз-кода важно, чтобы всё, что ниже, имело интуитивно простой контракт и чтобы этот контракт покрывал основные сценарии использования. Если такого контракта нет, то оборачивай в интерфейсы, не оборачивай — толку не будет никакого.


А>Абстракции не должны зависеть от деталей. Детали должны зависеть от абстракций.


А>Абстракция — что такое ?

Контракт. Т.е. то, что должен уметь некоторый класс с точки зрения внешнего кода. При этом (в идеале) внутренние детали реализации просвечивать не должны. Например, Dictionary<,> никак не намекает, что у него внутри 2 массива, счётчик версий и объект для блокировок (SyncRoot)

Если контракт одинаков для нескольких реализаций — ничего не мешает выделить контракт в интерфейс и подменять реализации по мере необходимости. Однако само по себе наличие/отсутствие интерфейса ничего не гарантирует, за "качество" абстракции отвечает разработчик. Поэтому контракт Dictionary хорош сам по себе, вне зависимости от наличия/отсутствия IDictionary, а TraceSource (даже если его спрятать за ITraceSource) — нет. Почему — см. код выше.

А>IUnknown — это абстракция.

А>А вот ISome
{
void Some();
}
А>Это уже детали.что есть метод Some типа void и который не принимает параметров.
Нет. Детали — это когда в справке к ISome указано, что для вызова Some() нужно сначала прокастить ISome к MyAwesome и задать пару свойств. Или когда бизнес-логика начинает доставать значения из контролов на форме вместо того, чтобы обращаться к свойству передаваемого класса.
Re: Принцип инверсии зависимости
От: SergeyT. США http://sergeyteplyakov.blogspot.com/
Дата: 05.12.13 09:49
Оценка: 40 (3) +2
Здравствуйте, Аноним, Вы писали:

А>Принцип инверсии зависимостей (англ. Dependency Inversion Principle, DIP) — важный принцип объектно-ориентированного программирования, используемый для уменьшения связанности в компьютерных программах. Входит в пятёрку

А>принципов SOLID.

ИМХО, принцип инверсии зависимостей весьма неоднозначный, особенно из уст такого парня как Боб Мартин — очень большого любителя крайностей.

Вот, может быть будет интересным: Критический взгляд на принцип инверсии зависимостей.
Re: Принцип инверсии зависимости
От: Baudolino  
Дата: 05.12.13 09:56
Оценка: +1
Приведу пример:

Модуль "Предикаты и функции" (приведены только абстракции):
interface Function<K,V> {
     V apply(K object);
}
interface Predicate<T> extends Function<T,Boolean> {
}

Модуль "Коллекции" (коллекция и список — абстракции, список на основе массива — деталь реализации):
interface Collection<T> { 
     Collection<T> filter(Predicate predicate); 
}

interface List<T> extends Collection<T> { }

class ArrayList<T> implements List<T> { }

Модуль "Бизнес-логика" (:
class Item { }
class ValidItemPredicate implements Predicate<Item> {
}
class SomeService {    
     static Predicate<Item> VALID_ITEMS = new ValidItemPredicate();
     int countValidItems(List<Item> items) {
          return items.filter(VALID_ITEMS).size();
     }
}

Модуль верхнего уровня ("Бизнес-логика") зависит только от абстракций в модулях нижнего уровня: в самом деле, ему не важно, какая именно реализация списка прилетит в сервис.
Модуль нижнего уровня ("Коллекции") хотя в итоге и получает в качестве параметра реализацию модуля верхнего уровня (предикат ValidItem), но ничего не знает о ее особенностях, поскольку работает с абстракцией Predicate.
Re[2]: Принцип инверсии зависимости
От: Sinix  
Дата: 05.12.13 10:46
Оценка:
Здравствуйте, SergeyT., Вы писали:

ST>Вот, может быть будет интересным: Критический взгляд на принцип инверсии зависимостей.

Чуть упрощенная, но все еще весьма действенная интерпретация принципа DIP выражается простым эвристическим правилом: «Зависеть надо от абстракций». Оно гласит, что не должно быть зависимостей от конкретных классов; все связи в программе должны вести на абстрактный класс или интерфейс.

Вот этого я вообще не понял DIP в принципе о другом говорит, и нет никакой разницы, абстрактный класс или нет.
Всё равно внутренности или торчат наружу, или спрятаны за пристойным API.

Приведет ли к хорошему дизайну буквальное следование принципу инверсии зависимостей? Как нам понять, что он означает, если в его определении такие термины как абстракция трактуются по-своему, а проблемы транзитивности зависимостей взяты из С++?

подписываюсь
Re[3]: Принцип инверсии зависимости
От: SergeyT. США http://sergeyteplyakov.blogspot.com/
Дата: 05.12.13 12:30
Оценка:
Здравствуйте, Sinix, Вы писали:

ST>>Вот, может быть будет интересным: Критический взгляд на принцип инверсии зависимостей.


S>

S>Чуть упрощенная, но все еще весьма действенная интерпретация принципа DIP выражается простым эвристическим правилом: «Зависеть надо от абстракций». Оно гласит, что не должно быть зависимостей от конкретных классов; все связи в программе должны вести на абстрактный класс или интерфейс.


S>Вот этого я вообще не понял DIP в принципе о другом говорит, и нет никакой разницы, абстрактный класс или нет.

S>Всё равно внутренности или торчат наружу, или спрятаны за пристойным API.

Проблема ведь в том, что приведенная цитата — это не моя мысль, а фраза из книги Боба Мартина! Поэтому из уст Мартина (автора этого чудо-принципа), в чудо книге, DIP говорит именно об этом. Но вот согласиться с этим никак нельзя!

По поводу чудо-книги, там отдельный разговор. Если интересно, могу собрать в одном месте все косяки Мартинов (старшего и младшего), как с точки зрения дизайна, так и с точки зрения C#-а.
Re[4]: Принцип инверсии зависимости
От: Sinix  
Дата: 05.12.13 12:35
Оценка: 1 (1)
Здравствуйте, SergeyT., Вы писали:

ST>Проблема ведь в том, что приведенная цитата — это не моя мысль, а фраза из книги Боба Мартина! Поэтому из уст Мартина (автора этого чудо-принципа), в чудо книге, DIP говорит именно об этом. Но вот согласиться с этим никак нельзя!

Угу. Я может непонятно написал, но тоже имел в виду именно это

ST>По поводу чудо-книги, там отдельный разговор. Если интересно, могу собрать в одном месте все косяки Мартинов (старшего и младшего), как с точки зрения дизайна, так и с точки зрения C#-а.

Ойненадо — и так вокруг хватает примеров "нафиг логику, делаем по Фаулеру"
Re[4]: Принцип инверсии зависимости
От: Docker Канада  
Дата: 09.12.13 22:08
Оценка:
ST>По поводу чудо-книги, там отдельный разговор. Если интересно, могу собрать в одном месте все косяки Мартинов (старшего и младшего), как с точки зрения дизайна, так и с точки зрения C#-а.

А вот мне было бы интересно, и самому посмотреть, и любителям авторитетов послать ссылку когда надо
Re[4]: Принцип инверсии зависимости
От: IT Россия linq2db.com
Дата: 09.12.13 22:58
Оценка: +1
Здравствуйте, SergeyT., Вы писали:

ST>По поводу чудо-книги, там отдельный разговор. Если интересно, могу собрать в одном месте все косяки Мартинов (старшего и младшего), как с точки зрения дизайна, так и с точки зрения C#-а.


Давай.
Если нам не помогут, то мы тоже никого не пощадим.
Re[5]: Принцип инверсии зависимости
От: SergeyT. США http://sergeyteplyakov.blogspot.com/
Дата: 23.12.13 21:52
Оценка: 124 (5)
Здравствуйте, IT, Вы писали:

ST>>По поводу чудо-книги, там отдельный разговор. Если интересно, могу собрать в одном месте все косяки Мартинов (старшего и младшего), как с точки зрения дизайна, так и с точки зрения C#-а.


IT>Давай.


Итак, что мы имеем? Вот три статые статьи:

Контракты, состояние и юнит-тесты
Боб Мартин известный сторонник TDD, я же предпочитаю думать о дизайне в терминах контрактов. В результате, в коде книги есть несколько багов, поскольку реализация "драйвилась" тестами, а не предусловиями и постусловиями. В этой статье также приведен пример просто ужасных тестов Мартина, за которые нужно отрывать руки по самые колени!
Интересно, что по этой же теме, контракты vs. юнит тесты, есть интересное видео на InfoQ с участием Мартина и Коплиена: Coplien and Martin Debate TDD, CDD and Professionalism.

Критический взгляд на принцип инверсии зависимостей
Боб Мартин известен популяризацией принципа Инверсии Зависимостей, но мало кто обращал внимание, что при его описании используются неверные термины. В приведенной статье содержится более подробная критика паттерна, а точнее его интерпретация Бобом Мартином.

Тестируемый дизайн vs. хороший дизайн
В своей книге Боб Мартин показывает, как обеспечить тестируемость некоего кода путем выделения интерфейсов для всех классов, я же привожу альтернативный вариант тестируемого дизайна, который не требует обилия интерфейсов и моков.

И одна новая, Критика книги Боба Мартина "Принципы, паттерны и методики гибкой разработки на языке C#", в которой собрано все остальные претензии к книге, которых набралось на 12 (!) страниц.

 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.