Интерфейсная интерпретация инверсии управления (IOC)

JavaScript

предисловие

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

определение МОК

Сначала посмотрите определение в Википедии:
Инверсия управления (сокращенно IoC) — это принцип проектирования в объектно-ориентированном программировании, который можно использовать для уменьшения связи между компьютерными кодами. Наиболее распространенный способ называется внедрение зависимостей (DI), и есть еще один способ, называемый «поиск зависимостей». Посредством инверсии управления при создании объекта внешний объект, управляющий всеми объектами в системе, передает ему ссылку на объект, от которого он зависит. Можно также сказать, что зависимости внедряются в объекты.

в общем

  1. Модули высокого уровня не должны зависеть от модулей низкого уровня. Оба должны полагаться на абстракцию
  2. Абстракция не должна зависеть от конкретной реализации
  3. Программирование для интерфейса, а не для реализации

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

Цель

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

кодовое соединение

Так называемая связь может быть представлена ​​следующим образом:Это относительно ясно и ясно, а связь между кодами слишком прямая: Если obj2 сообщает об ошибке, то вся система также сообщает об ошибке.
Итак, наша цель состоит в том, чтобы уменьшить связь между двумя,
По картинке понятно,
Если они не связаны так непосредственно, то вероятность взаимного влияния намного меньше.

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

Таким образом, МОК должен решить вышеуказанные проблемы. Распространенным способом является внедрение зависимостей и поиск зависимостей. Самым известным в области js является широкое использование внедрения зависимостей в angular. Текст относительно бледный, это видно на примерах.

пример

Что касается НБА, есть какие-то звезды, мы хотим знать, к какой команде он принадлежит, тогда может быть такая ситуация:

//球队信息
class RTeam {
    constructor(){
        this.name = '火箭'
    }
}
// 球员信息
class Player{
    constructor(){
        this.team = new RTeam()
    }
    info(){
        console.log(this.team.name)
    }
}
// 球员ym
let ym = new Player()
ym.info() // ‘火箭’

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

Если в это время игрок обменивается, информация о команде меняется, и команда переключается на команду 2.
В это время нам нужно модифицировать код в плеере, потому что плеер напрямую пишет зависимость от RTeam, а эта масштабируемость очень плохая. Это не то, чего мы хотим, и нам нужно переосмыслить обработку зависимостей.
Нужно ли быть таким прямым и грубым между игроками и командами?
Если игрок соответствует команде, вероятность изменений в будущем слишком велика, ведь есть не одна команда.
Если между ними нет прямой связи, посередине необходим промежуточный модуль для обработки связи между ними.
Игрокам все равно, откуда команда, лишь бы они отдали ее мне.
Таким образом, право управления не падает непосредственно на игрока, что и является дизайнерской идеей IOC.

Улучшения согласно МОК

Ссылаясь на несколько принципов IOC, мы вносим следующие улучшения.

  1. Модули высокого уровня не должны зависеть от модулей низкого уровня. Оба должны полагаться на абстракцию Здесь игрок — высокоуровневый модуль, который напрямую зависит от низкоуровневого модуля команды. Таким образом, мы отделяем их друг от друга, и игрок больше не зависит напрямую от класса команды.

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

Нагляднее смотреть на код напрямую:

// 球队信息不依赖具体实现
// 面向接口即面向抽象编程
class TeamInfo {
    constructor(name) {
        this.name = name
    }
}
class Player {
    // 此处的参数,是teamInfo的一个实例,不直接依赖具体的实例
    // 面向抽象
    constructor(team) {
        this.team = team
    }
    info() {
        console.log(this.team.name)
    }
}
// 将依赖关系放到此处来管理,控制权也放到此处
// Player和TeamInfo之间不再有直接依赖
// 原本直接掌握teaminfo控制权的player不再直接依赖
// 将依赖控制,落在此处(第三方模块专门管理)即为控制反转
var ym = new Player(new TeamInfo('火箭'))
ym.info()
var kobe = new Player(new TeamInfo('湖人'))
kobe.info()

Здесь обнаруживается, что между TeamInfo и Player нет прямой связи, а зависимости объединены в getTeamInfo.
Так называемая инверсия управления — это то же самое, что и выше, передача управления зависимостями от игрока в другие места, то есть наше выделенное управление зависимостями. Таким образом добавляется еще одна team3, и изменения не большие, просто переиспользование. Связь между ними показана на следующем рисунке:Они не связаны друг с другом напрямую, а управление зависимостями осуществляется в среднем модуле, что более понятно.

выполнить

Вышеприведенное на самом деле является самой простой реализацией IOC.Основываясь на идее программирования IOC, в основном существует два метода реализации: внедрение зависимостей и поиск зависимостей. Проверка зависимостей встречается реже, а внедрение зависимостей распространено.

внедрение зависимости

Внедрение зависимостей распространено в js. Из названия так называемое внедрение зависимостей, то есть зависимость между компонентами определяется контейнером во время выполнения, а визуально говоря, то есть контейнер динамически внедряет определенную зависимость в компонент.

Реализация загрузчика модулей в RequireJS/AMD основана на внедрении зависимостей, и знаменитый angular также использует множество внедрений зависимостей.

заключительные замечания

По поводу инверсии управления, резюме в одном предложении: Инверсия управления, где управление передается от самого пользователя стороннему контейнеру, а не вызываемому, здесь нужно быть ясным и не путать. Инверсия управления — это идея, а внедрение зависимостей — это шаблон проектирования. Это может звучать абстрактно, но на самом деле многое мы видим и используем в своем повседневном развитии, и оно может не соответствовать ему изначально. Что касается внедрения зависимостей, то оно больше используется во фронтенде.Ниже я объединим свою собственную практику для перевода статьи, которую я считаю очень хорошей Dependency-injection-in-JavaScript, чтобы глубже погрузиться во внедрение зависимостей. На этом обмен личными мнениями завершен, и я надеюсь учиться и развиваться вместе.Больше статей, пожалуйста, переместите мой блог