[java-интервью] Что такое IOC Spring и каковы его преимущества?

интервью Java Spring дизайн

Эта статья воспроизведена из Zhihu, чтобы ответить на вопрос: каковы преимущества Spring IoC? Добавить Автора

7 принципов шаблонов проектирования

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

  • принцип открыто-закрыто

  • Принцип единой ответственности

  • Принцип инверсии зависимости

  • принцип минимума знаний

  • Принцип разделения интерфейса

  • Принцип мультиплексирования синтеза/агрегации

  • Принцип подстановки Лисков, где может появиться любой базовый класс, должен появиться подкласс

Инверсия зависимости

Предположим, мы проектируем автомобиль: сначала проектируем колеса, затем проектируем шасси в соответствии с размером колес, затем проектируем кузов в соответствии с шасси и, наконец, проектируем весь автомобиль в соответствии с кузовом. Здесь есть отношение «зависимости»: автомобиль зависит от кузова, кузов зависит от шасси, а шасси зависит от колес.

Такая конструкция выглядит нормально, но ремонтопригодность низкая. Предположим, что после завершения проектирования начальник вдруг сказал, что в соответствии с изменениями рыночного спроса мы должны изменить дизайн колес автомобиля на один размер. На этот раз мы мучаемся: потому что мы проектируем шасси в соответствии с размером колес, если размер колес изменяется, конструкция шасси должна быть изменена; также потому, что мы проектируем кузов в соответствии с шасси, то кузов тоже надо дорабатывать, и то же самое приходится менять и дизайн автомобиля - менять надо почти весь дизайн! Давайте сейчас передумаем. Сначала мы проектируем общий вид автомобиля, затем проектируем кузов в соответствии с внешним видом автомобиля, проектируем шасси в соответствии с кузовом и, наконец, проектируем колеса в соответствии с шасси. В этот момент зависимости меняются местами: колеса зависят от шасси, шасси зависит от кузова, а кузов зависит от автомобиля.

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

Инверсия контроля

Это идея дизайна кода, основанная на принципе инверсии зависимостей. Конкретным используемым методом является так называемая инъекция зависимостей. На самом деле, эти понятия впервые покажутся туманными. Грубо говоря, соотношение между этими понятиями примерно следующее:

Чтобы понять эти концепции, давайте воспользуемся приведенным выше примером с автомобилем. Только на этот раз с кодом. Сначала мы определяем четыре класса: автомобиль, кузов, шасси и шины. Затем инициализируйте машину и, наконец, запустите машину. Структура кода следующая:

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

Так как мы модифицировали определение шин, для правильной работы всей программы нам необходимо внести следующие изменения:

Из этого мы видим, что только для того, чтобы изменить конструктор шины, в этом проекте необходимо изменить конструкторы всех классов во всем верхнем слое! В программной инженерии такой дизайн почти не поддерживается — в реальных инженерных проектах некоторые классы могут быть нижним слоем тысяч классов.Если мы каждый раз модифицируем этот класс, нам придется модифицировать все зависимости, которые от него зависят. стоимость обслуживания слишком высока. Итак, нам нужно сделать инверсию управления (IoC), и верхний уровень управляет нижним уровнем, а не нижний уровень управляет верхним уровнем. Мы используем Dependency Injection для достижения инверсии управления. Так называемая инъекция зависимости заключается в передаче базового класса в качестве параметра верхнему классу для реализации «контроля» верхнего класса над низшим классом. Здесь мы переписываем определение класса автомобиля с методом внедрения зависимостей, переданным конструктором:

Здесь мы снова делаем размер шин динамическим, и чтобы вся система работала без сбоев, нам нужно внести следующие изменения:

Ты видел? Здесь мне нужно только изменить класс шин, не изменяя какой-либо другой верхний класс. Это, очевидно, легче поддерживать код. Мало того, что в реальном проектировании этот шаблон проектирования также способствует совместной работе и модульному тестированию различных групп: например, разработка этих четырех классов осуществляется в четырех разных группах, тогда, пока интерфейс определен, четыре разные группы могут разрабатываться одновременно, не ограничиваясь друг другом; и для модульного тестирования, если мы хотим написать модульный тест класса Car, нам нужно только смоделировать класс Framework и передать его в Car, вместо того, чтобы ставить все Каркас, Днище и Шины новыми.Создавайте Машину снова и снова. Здесь мы используем метод передачи конструктора для внедрения зависимостей. На самом деле есть два других метода: доставка через сеттер и доставка через интерфейс. Я не буду много говорить здесь, основные идеи те же, все для достижения инверсии управления.

Инверсия контейнера управления (контейнер IoC)

На самом деле, в приведенном выше примере место, где появляется код, инициализирующий класс car, — это инверсия контейнера управления.

Очевидно, вы также должны заметить, что из-за внедрения зависимостей неизбежно писать много нового в процессе инициализации. Здесь контейнер IoC решает эту проблему. Этот контейнер может автоматически инициализировать ваш код, вам нужно только поддерживать конфигурацию (это может быть xml или кусок кода), вместо того, чтобы писать большой кусок кода инициализации каждый раз, когда вы инициализируете машину. Это первое преимущество внедрения контейнера IoC. Второе преимущество контейнера IoC заключается в том, что нам не нужно знать подробности при создании экземпляра. В приведенном выше примере, когда мы вручную создаем экземпляр автомобиля, он создается снизу вверх:

В этом процессе нам нужно понять, как определяется весь конструктор класса Car/Framework/Bottom/Tire, чтобы мы могли шаг за шагом создавать/внедрять его. Когда IoC-контейнер выполняет эту работу, он работает в обратном порядке: он начинает с верхнего уровня для поиска зависимостей, а после достижения нижнего уровня он шаг за шагом поднимается вверх (немного похоже на обход в глубину):

Контейнер IoC может напрямую скрывать конкретные детали создания экземпляра.

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

Связанное Чтение