Абстракции не должны зависеть от деталей. Детали должны зависеть от абстракций? - PullRequest
22 голосов
/ 10 ноября 2009

В последние пару дней я много читал о внедрении зависимости / инверсии управления / инверсии зависимости. Я думаю , что теперь мое понимание концепции намного лучше. Но я все еще не получаю следующее из Википедии:

A. Модули высокого уровня не должны зависит от низкоуровневых модулей. И то и другое должно зависеть от абстракций. Б. Абстракции не должны зависеть от деталей. Подробности должны зависит от абстракций.

Я понимаю часть Высокоуровневые модули не должны зависит от низкоуровневых модулей. Но меня смущают абстракции и детали. Может кто-нибудь, пожалуйста, упростите их для меня. Спасибо.

Ответы [ 4 ]

35 голосов
/ 10 ноября 2009

Это означает, что если детали меняются, они не должны влиять на абстракцию. Абстракция - это способ, которым клиенты видят объект. То, что происходит внутри объекта, не важно. Возьмем, к примеру, автомобиль, педали, рулевое колесо и рычаг переключения передач являются абстракцией того, что происходит внутри двигателя. Они не зависят от деталей, потому что, если кто-то поменяет мой старый двигатель на новый, я все равно смогу вести машину, не зная, что двигатель изменился.

Детали с другой стороны ДОЛЖНЫ соответствовать тому, что говорит абстракция. Я не хотел бы реализовать двигатель, который внезапно заставляет тормоза удваивать скорость автомобиля. Я могу повторно установить тормоза любым способом, каким хочу, если внешне они ведут себя одинаково.

3 голосов
/ 20 июня 2014

Интересный случай, когда абстракция зависит от деталей, - это когда вы определяете интерфейс, который наследуется от IDisposable . Взгляните на следующую абстракцию:

public interface ICustomerRepository : IDisposable
{
    Customer GetById(Guid id);
    Customer[] GetAll();
}

Примечание : IDisposable - это интерфейс, специфичный для .NET, но вы можете легко представить, что ваш интерфейс содержит сам метод Dispose вместо того, чтобы наследовать от такого интерфейса.

Может показаться удобным для ICustomerRepository реализовать IDisposable. Таким образом, любой вызывающий объект может утилизировать репозиторий, и таким образом реализация может распоряжаться внутренним соединением или единицей работы, которые оно использует.

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

1 голос
/ 21 ноября 2009

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

Абстракции перемещают эту позицию ближе к коду, который вы пишете. Например, если вам нужно вызвать веб-сервис, вы можете либо: 1) написать вызывающий код непосредственно там, где вам нужно его использовать, либо 2) поместить эти детали за абстракцией (например, интерфейсом).

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

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

Ого, это было абстрактно.

1 голос
/ 10 ноября 2009

Пример абстракции и подробностей: поток предоставляет интерфейс для чтения токена. Это абстракция.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...