Что означает «абстракции не должны зависеть от деталей. Детали должны зависеть от абстракций» в смысле принципа инверсии зависимости [DIP]? - PullRequest
0 голосов
/ 17 октября 2018

Прежде чем задать этот вопрос, я хотел бы сказать, что этот вопрос в stackoverflow очень похож на мой вопрос, но, тем не менее, концепция не совсем ясна и очень запутанна.

Я пытаюсь понять принцип инверсии зависимости, но не могу понять его полностью?

Ниже приведены два пункта, которые DIP говорит

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

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

Рассмотрим пример:

Рассмотрим класс SalaryCalculator [модуль высокого уровня], который используется для расчета заработной платы сотрудника.Который использует BonusCalculator [модуль высокого уровня] для расчета зарплаты, как показано ниже.Поскольку SalaryCalculator использует BonusCalculator, он нарушает первый пункт «Модули высокого уровня не должны зависеть от модулей низкого уровня.Оба должны зависеть от абстракций ».

enter image description here

Поэтому мы ввели абстракцию между ними, как показано ниже:

enter image description here

Здесь детали [Модули низкого и высокого уровня] зависят от абстракции, а абстракция не зависит от деталей.Так в DIP, что пытается сказать вторая точка? Если оба они одинаковы, почему это сделано в виде двух точек?

Если кто-нибудь даст мне пример кода , это будет очень полезно.

Ответы [ 2 ]

0 голосов
/ 19 октября 2018

Давайте разберем эту часть B дальше.

Абстракции не должны зависеть от деталей. Это может означать, что объявление вашего интерфейса (ваша абстракция) должно избегать включения конкретных типов.Подумайте о разнице между distance(int X1, int Y1, int X2, int Y2) и distance(Point A, Point B).Что если у вас есть координаты, измеренные в плавающей точке, широте или долготе или в полярных системах координат?Что если вы перейдете в 3D-пространство?Вам нужно будет переопределить каждую подпрограмму, которая использует вашу функцию расстояния.

Подробности должны зависеть от абстракций. Насколько это возможно, продолжайте использовать слой абстракции, чтобы избежать зависимостей от конкретных типов.,

Это все о минимизации воздействия изменений.Чем меньше ваш код зависит от других вещей, тем больше он позволяет изменить этот другой код.

0 голосов
/ 17 октября 2018

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

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

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

Итак, возвращаясь к исходным вопросам:

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

  • «Абстрагируя» функциональность, содержащуюся в модуле низкого уровня (Bonus Calculator), вы сможете относительно легко переключиться на чужой бонусный калькулятор, есливы считаете мой сервис мусором.
  • Это потому, что вы защитили себя от "деталей" моего кода с помощью абстракции.

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

  • Если ваша абстракция зависела от деталей моего кода, то вам пришлось бы переписать все, чтобы переключиться на новый бонусный калькулятор!Это победило бы цель.

Пример кода (javascript):

  • Скажем, у нас есть абстракция под названием «сумма», которая просто вычисляет сумму двух чисел.Вы являетесь пользователем этой функции и хотите использовать ее следующим образом: sum (2,2) = 4.
  • Теперь предположим, что есть два разных модуля (функции), которые вычисляют сумму.

    1. function sum(a, b) { return a + b }
    2. function sum(b, a) { return b + a }
  • Очевидно, что эти функции точно такие же, но представьте, если это был комплексвычисления с множеством различных способов достижения результата, и каждый из них имеет разную производительность во время выполнения.Вы можете свободно проверить, какая функция работает лучше для вас, используя тот же интерфейс: просто вызывая sum ().Абстракция не зависит от деталей.

  • Делая так, ваш модуль высокого уровня также больше не зависит от модуля низкого уровня, так как вы можете попробовать другой модуль низкого уровня с относительнымлегкость.

Извините, этот ответ немного грязный.Надеюсь, это поможет!

...