SlideShare a Scribd company logo
1 of 21
Управление зависимостями
   в программном коде
     (dependency injection &
   Inversion of Control includes)
Agenda
•   Качество архитектуры приложения
•   Что такое зависимый код?
•   Что такое инъекция зависимости?
•   Инверсия зависимости
•   IoC-контейнеры
Это вам знакомо?
• Изменения в одном месте приводят к
  поломкам в другом
• Методы и классы сложно повторно
  использовать
• Изменения идут «со скрипом». Трудно что-
  либо добавить или изменить.
• «Без пол литра не разобраться» или
  «покажите мне умника, который так
  пишет?»
Признаки плохой архитектуры
• Хрупкость (изменения ведут к поломкам)
• Монолитность (сопротивление к
  повторному использованию)
• Жесткость (сопротивление к изменениям)
• Чрезмерная сложность (ничего непонятно)
• Вязкость («грязные» приемы работают
  лучше: Copy-Paste, «Объект Бога»,
  «Спагетти код» и т.д.)
Одна из причин
Сильное связывание кода (Tight Coupling)
Что такое зависимый код?
• public class User {
     private MessageService transport = new
            SmtpMessageService();

      public void sendMessage() {
            transport.send();
      }
  }
Зависимость!
• public class User {
     private MessageService transport = new
            SmtpMessageService();

      public void sendMessage() {
            transport.send();
      }
  }
Проблемы с классом User
• Мы не можем изменить реализацию
  MessageService
• Мы не можем протестировать класс User
  отдельно от класса SmtpMessageService
• Необходимо создавать новый класс или
  наследовать от класса User, чтобы добавить
  новую реализацию.
Как избавиться от зависимости?
• Передать объект через set-метод:
        public void setMessageService(MessagService messageService) {
                 this.messageService = messageService;
        }

• Передать объект через конструктор:
    public User(MessageService transport) {
                this.transport = transport;
    }
Решение найдено
Инъекция зависимости
Инъекция!
• Передать объект через set-метод:
        public void setMessageService(MessagService transport) {
                 this.transport = transport;
        }

• Передать объект через конструктор:
    public User(MessageService transport) {
                this.transport = transport;
    }
Программирование основано на
             интерфейсах
•   public interface MessageService {
         public void send(String message);
    }
•   public class SmtpMessageService implements MessageService {
         public void send(String message) {
                   System.out.println(“Via smtp: ” + message);
         }
    }
•   public class JabberMessageService implements MessageService {
    public void send(String message) {
                   System.out.println(“Via jabber: ” + message);
         }
    }
Пример использования
•   User userWithSmtp = new User();
    userWithSmtp.setMessageService(new SmtpMessageService()) ;
    userWithSmtp.send(“you can do it”); // print “Via smtp: you can do it”

•   User userWithJabber= new User();
    userWithJabber.setMessageService(new SmtpMessageService()) ;
    userWithJabber.send(“ yes, you can”); // print “Via jabber: yes, you can”
Что это нам дает?
• Менее связанный код (low coupling)
• Небольшие, сильно зацепленные классы
  (high cohesion)
• Возможность повторного использования
  (reuse)
• Расширяемость
Ответственность перешла другому классу
Инверсия зависимости
Кто-то должен это делать
•   User userWithSmtp = new User();
    userWithSmtp.setMessageService(new SmtpMessageService()) ;
    userWithSmtp.send(“you can do it”); // print “Via smtp: you can do it”

•   User userWithJabber= new User();
    userWithJabber.setMessageService(new SmtpMessageService()) ;
    userWithJabber.send(“ yes, you can”); // print “Via jabber: yes, you can”




    Ответственность переходит классам верхнего уровня в соответствии
    принципом инверсии зависимости.
Принцип инверсии
• Зависимости внутри системы стоятся на
  основе абстракций (интерфейсы или
  абстрактные классы).
• Модули верхнего уровня не зависят от
  модулей нижнего уровня.
• Абстракции не зависят от подробностей.
IoC контейнеры
• IoC (Inversion of Control) контейнер – это специальный
  объект-сборщик, который на основании схемы
  зависимостей между классами и абстракциями может
  создать граф объектов. Любой IoC контейнер реализует
  принцип инверсии зависимостей
• IoC контейнеры появились в Java
   – Spring
   – Pico container
• IoC контейнеры используются на самых верхних уровнях
  приложений для инициализации объектов с учетом всех
  зависимостей
Java: Spring Framework
• Позиционируется как complete dependency
  injection tool
• Позволяет описывать зависимости в коде
  или через XML-файл
Пример для Spring Framework
• XML файл описания (dependency.xml)
<beans>
 <bean id=“messageService" class="com.my_app.StmpMessageService"/>
 <bean id="client" class="com.my_app.User">
  <property name=“transport">
   <ref bean="messageService"/>
  </property>
 </bean>
</beans>

• Получение объектов с учетом зависимостей
BeanFactory factory = new XmlBeanFactory(new
   FileInputStream("dependency.xml"));
User user= (User)factory.getBean(“user");
user.send();
Хорошая архитектура
• Простота – чем меньше архитектурных решений, тем
  проще
• Очевидность использования – минимум движений, чтобы
  получить результат
• Расширяемость – когда есть требования, система легко
  вбирает в себя функционал
• Устойчивость – разделение ролей позволяет быстро
  локализировать ошибки
• Повторное использование – низкая зависимость
  определяет возможности по использованию

More Related Content

Similar to Управление зависимостями в программном коде

МАИ, Сети ЭВМ, Лекция №4
МАИ, Сети ЭВМ, Лекция №4МАИ, Сети ЭВМ, Лекция №4
МАИ, Сети ЭВМ, Лекция №4Dima Dzuba
 
Windows Azure Service Bus
Windows Azure Service BusWindows Azure Service Bus
Windows Azure Service BusPavel Revenkov
 
Trainspotting Transporting: RabbitMQ, Akka.NET, Rx, MVI, Cycle.js
Trainspotting Transporting: RabbitMQ, Akka.NET, Rx, MVI, Cycle.jsTrainspotting Transporting: RabbitMQ, Akka.NET, Rx, MVI, Cycle.js
Trainspotting Transporting: RabbitMQ, Akka.NET, Rx, MVI, Cycle.jsDevOWL Meetup
 
Сергей Константинов — Что интересного готовит нам W3C
Сергей Константинов — Что интересного готовит нам W3CСергей Константинов — Что интересного готовит нам W3C
Сергей Константинов — Что интересного готовит нам W3CYandex
 
Модульная структура. Цветцих Денис D2D Just.NET
Модульная структура. Цветцих Денис D2D Just.NETМодульная структура. Цветцих Денис D2D Just.NET
Модульная структура. Цветцих Денис D2D Just.NETDev2Dev
 
Модульная структура
Модульная структураМодульная структура
Модульная структураDenis Tsvettsih
 
Moxy – реализация MVP под Android. С щепоткой магии
Moxy – реализация MVP под Android. С щепоткой магииMoxy – реализация MVP под Android. С щепоткой магии
Moxy – реализация MVP под Android. С щепоткой магииYuri Shmakov
 
сергей спиридонов
сергей спиридоновсергей спиридонов
сергей спиридоновkuchinskaya
 
Konstantin slisenko - Spring Framework
Konstantin slisenko - Spring FrameworkKonstantin slisenko - Spring Framework
Konstantin slisenko - Spring Frameworkbeloslab
 
Dependency injection
Dependency injectionDependency injection
Dependency injectionGetDev.NET
 
ВВЕДЕНИЕ В NODE.JS
ВВЕДЕНИЕ В NODE.JS ВВЕДЕНИЕ В NODE.JS
ВВЕДЕНИЕ В NODE.JS Pavel Tsukanov
 
Объять необъятное, или как использовать несколько MVVM фреймворков в одном XA...
Объять необъятное, или как использовать несколько MVVM фреймворков в одном XA...Объять необъятное, или как использовать несколько MVVM фреймворков в одном XA...
Объять необъятное, или как использовать несколько MVVM фреймворков в одном XA...Denis Tsvettsih
 
RDSDataSource: Promises
RDSDataSource: PromisesRDSDataSource: Promises
RDSDataSource: PromisesRAMBLER&Co
 
АРК-ПЗ-1.pptx
АРК-ПЗ-1.pptxАРК-ПЗ-1.pptx
АРК-ПЗ-1.pptxrobete3065
 
Проблемы точечной застройки в больших городах или зачем нужен Dagger
Проблемы точечной застройки в больших городах или зачем нужен DaggerПроблемы точечной застройки в больших городах или зачем нужен Dagger
Проблемы точечной застройки в больших городах или зачем нужен DaggerValeriya Atamanova
 

Similar to Управление зависимостями в программном коде (20)

МАИ, Сети ЭВМ, Лекция №4
МАИ, Сети ЭВМ, Лекция №4МАИ, Сети ЭВМ, Лекция №4
МАИ, Сети ЭВМ, Лекция №4
 
Windows Azure Service Bus
Windows Azure Service BusWindows Azure Service Bus
Windows Azure Service Bus
 
Design Principles
Design PrinciplesDesign Principles
Design Principles
 
Trainspotting Transporting: RabbitMQ, Akka.NET, Rx, MVI, Cycle.js
Trainspotting Transporting: RabbitMQ, Akka.NET, Rx, MVI, Cycle.jsTrainspotting Transporting: RabbitMQ, Akka.NET, Rx, MVI, Cycle.js
Trainspotting Transporting: RabbitMQ, Akka.NET, Rx, MVI, Cycle.js
 
Сергей Константинов — Что интересного готовит нам W3C
Сергей Константинов — Что интересного готовит нам W3CСергей Константинов — Что интересного готовит нам W3C
Сергей Константинов — Что интересного готовит нам W3C
 
Модульная структура. Цветцих Денис D2D Just.NET
Модульная структура. Цветцих Денис D2D Just.NETМодульная структура. Цветцих Денис D2D Just.NET
Модульная структура. Цветцих Денис D2D Just.NET
 
Модульная структура
Модульная структураМодульная структура
Модульная структура
 
Moxy – реализация MVP под Android. С щепоткой магии
Moxy – реализация MVP под Android. С щепоткой магииMoxy – реализация MVP под Android. С щепоткой магии
Moxy – реализация MVP под Android. С щепоткой магии
 
сергей спиридонов
сергей спиридоновсергей спиридонов
сергей спиридонов
 
servlets.pdf
servlets.pdfservlets.pdf
servlets.pdf
 
Tdd php
Tdd phpTdd php
Tdd php
 
Konstantin slisenko - Spring Framework
Konstantin slisenko - Spring FrameworkKonstantin slisenko - Spring Framework
Konstantin slisenko - Spring Framework
 
Dependency injection
Dependency injectionDependency injection
Dependency injection
 
ВВЕДЕНИЕ В NODE.JS
ВВЕДЕНИЕ В NODE.JS ВВЕДЕНИЕ В NODE.JS
ВВЕДЕНИЕ В NODE.JS
 
Объять необъятное, или как использовать несколько MVVM фреймворков в одном XA...
Объять необъятное, или как использовать несколько MVVM фреймворков в одном XA...Объять необъятное, или как использовать несколько MVVM фреймворков в одном XA...
Объять необъятное, или как использовать несколько MVVM фреймворков в одном XA...
 
RDSDataSource: Promises
RDSDataSource: PromisesRDSDataSource: Promises
RDSDataSource: Promises
 
АРК-ПЗ-1.pptx
АРК-ПЗ-1.pptxАРК-ПЗ-1.pptx
АРК-ПЗ-1.pptx
 
MWWM
MWWMMWWM
MWWM
 
Android service
Android serviceAndroid service
Android service
 
Проблемы точечной застройки в больших городах или зачем нужен Dagger
Проблемы точечной застройки в больших городах или зачем нужен DaggerПроблемы точечной застройки в больших городах или зачем нужен Dagger
Проблемы точечной застройки в больших городах или зачем нужен Dagger
 

Recently uploaded (9)

Cyberprint. Dark Pink Apt Group [RU].pdf
Cyberprint. Dark Pink Apt Group [RU].pdfCyberprint. Dark Pink Apt Group [RU].pdf
Cyberprint. Dark Pink Apt Group [RU].pdf
 
Malware. DCRAT (DARK CRYSTAL RAT) [RU].pdf
Malware. DCRAT (DARK CRYSTAL RAT) [RU].pdfMalware. DCRAT (DARK CRYSTAL RAT) [RU].pdf
Malware. DCRAT (DARK CRYSTAL RAT) [RU].pdf
 
Ransomware_Q3 2023. The report [RU].pdf
Ransomware_Q3 2023.  The report [RU].pdfRansomware_Q3 2023.  The report [RU].pdf
Ransomware_Q3 2023. The report [RU].pdf
 
ИСТОЧНИКИ ИННОВАЦИОННОСТИ КИТАЯ (ПО ВЕРСИИ DGAP) | The Sources of China’s Inn...
ИСТОЧНИКИ ИННОВАЦИОННОСТИ КИТАЯ (ПО ВЕРСИИ DGAP) | The Sources of China’s Inn...ИСТОЧНИКИ ИННОВАЦИОННОСТИ КИТАЯ (ПО ВЕРСИИ DGAP) | The Sources of China’s Inn...
ИСТОЧНИКИ ИННОВАЦИОННОСТИ КИТАЯ (ПО ВЕРСИИ DGAP) | The Sources of China’s Inn...
 
Cyber Defense Doctrine Managing the Risk Full Applied Guide to Organizational...
Cyber Defense Doctrine Managing the Risk Full Applied Guide to Organizational...Cyber Defense Doctrine Managing the Risk Full Applied Guide to Organizational...
Cyber Defense Doctrine Managing the Risk Full Applied Guide to Organizational...
 
СИСТЕМА ОЦЕНКИ УЯЗВИМОСТЕЙ CVSS 4.0 / CVSS v4.0 [RU].pdf
СИСТЕМА ОЦЕНКИ УЯЗВИМОСТЕЙ CVSS 4.0 / CVSS v4.0 [RU].pdfСИСТЕМА ОЦЕНКИ УЯЗВИМОСТЕЙ CVSS 4.0 / CVSS v4.0 [RU].pdf
СИСТЕМА ОЦЕНКИ УЯЗВИМОСТЕЙ CVSS 4.0 / CVSS v4.0 [RU].pdf
 
2023 Q4. The Ransomware report. [RU].pdf
2023 Q4. The Ransomware report. [RU].pdf2023 Q4. The Ransomware report. [RU].pdf
2023 Q4. The Ransomware report. [RU].pdf
 
CVE. The Fortra's GoAnywhere MFT [RU].pdf
CVE. The Fortra's GoAnywhere MFT [RU].pdfCVE. The Fortra's GoAnywhere MFT [RU].pdf
CVE. The Fortra's GoAnywhere MFT [RU].pdf
 
MS Navigating Incident Response [RU].pdf
MS Navigating Incident Response [RU].pdfMS Navigating Incident Response [RU].pdf
MS Navigating Incident Response [RU].pdf
 

Управление зависимостями в программном коде

  • 1. Управление зависимостями в программном коде (dependency injection & Inversion of Control includes)
  • 2. Agenda • Качество архитектуры приложения • Что такое зависимый код? • Что такое инъекция зависимости? • Инверсия зависимости • IoC-контейнеры
  • 3. Это вам знакомо? • Изменения в одном месте приводят к поломкам в другом • Методы и классы сложно повторно использовать • Изменения идут «со скрипом». Трудно что- либо добавить или изменить. • «Без пол литра не разобраться» или «покажите мне умника, который так пишет?»
  • 4. Признаки плохой архитектуры • Хрупкость (изменения ведут к поломкам) • Монолитность (сопротивление к повторному использованию) • Жесткость (сопротивление к изменениям) • Чрезмерная сложность (ничего непонятно) • Вязкость («грязные» приемы работают лучше: Copy-Paste, «Объект Бога», «Спагетти код» и т.д.)
  • 5. Одна из причин Сильное связывание кода (Tight Coupling)
  • 6. Что такое зависимый код? • public class User { private MessageService transport = new SmtpMessageService(); public void sendMessage() { transport.send(); } }
  • 7. Зависимость! • public class User { private MessageService transport = new SmtpMessageService(); public void sendMessage() { transport.send(); } }
  • 8. Проблемы с классом User • Мы не можем изменить реализацию MessageService • Мы не можем протестировать класс User отдельно от класса SmtpMessageService • Необходимо создавать новый класс или наследовать от класса User, чтобы добавить новую реализацию.
  • 9. Как избавиться от зависимости? • Передать объект через set-метод: public void setMessageService(MessagService messageService) { this.messageService = messageService; } • Передать объект через конструктор: public User(MessageService transport) { this.transport = transport; }
  • 11. Инъекция! • Передать объект через set-метод: public void setMessageService(MessagService transport) { this.transport = transport; } • Передать объект через конструктор: public User(MessageService transport) { this.transport = transport; }
  • 12. Программирование основано на интерфейсах • public interface MessageService { public void send(String message); } • public class SmtpMessageService implements MessageService { public void send(String message) { System.out.println(“Via smtp: ” + message); } } • public class JabberMessageService implements MessageService { public void send(String message) { System.out.println(“Via jabber: ” + message); } }
  • 13. Пример использования • User userWithSmtp = new User(); userWithSmtp.setMessageService(new SmtpMessageService()) ; userWithSmtp.send(“you can do it”); // print “Via smtp: you can do it” • User userWithJabber= new User(); userWithJabber.setMessageService(new SmtpMessageService()) ; userWithJabber.send(“ yes, you can”); // print “Via jabber: yes, you can”
  • 14. Что это нам дает? • Менее связанный код (low coupling) • Небольшие, сильно зацепленные классы (high cohesion) • Возможность повторного использования (reuse) • Расширяемость
  • 15. Ответственность перешла другому классу Инверсия зависимости
  • 16. Кто-то должен это делать • User userWithSmtp = new User(); userWithSmtp.setMessageService(new SmtpMessageService()) ; userWithSmtp.send(“you can do it”); // print “Via smtp: you can do it” • User userWithJabber= new User(); userWithJabber.setMessageService(new SmtpMessageService()) ; userWithJabber.send(“ yes, you can”); // print “Via jabber: yes, you can” Ответственность переходит классам верхнего уровня в соответствии принципом инверсии зависимости.
  • 17. Принцип инверсии • Зависимости внутри системы стоятся на основе абстракций (интерфейсы или абстрактные классы). • Модули верхнего уровня не зависят от модулей нижнего уровня. • Абстракции не зависят от подробностей.
  • 18. IoC контейнеры • IoC (Inversion of Control) контейнер – это специальный объект-сборщик, который на основании схемы зависимостей между классами и абстракциями может создать граф объектов. Любой IoC контейнер реализует принцип инверсии зависимостей • IoC контейнеры появились в Java – Spring – Pico container • IoC контейнеры используются на самых верхних уровнях приложений для инициализации объектов с учетом всех зависимостей
  • 19. Java: Spring Framework • Позиционируется как complete dependency injection tool • Позволяет описывать зависимости в коде или через XML-файл
  • 20. Пример для Spring Framework • XML файл описания (dependency.xml) <beans> <bean id=“messageService" class="com.my_app.StmpMessageService"/> <bean id="client" class="com.my_app.User"> <property name=“transport"> <ref bean="messageService"/> </property> </bean> </beans> • Получение объектов с учетом зависимостей BeanFactory factory = new XmlBeanFactory(new FileInputStream("dependency.xml")); User user= (User)factory.getBean(“user"); user.send();
  • 21. Хорошая архитектура • Простота – чем меньше архитектурных решений, тем проще • Очевидность использования – минимум движений, чтобы получить результат • Расширяемость – когда есть требования, система легко вбирает в себя функционал • Устойчивость – разделение ролей позволяет быстро локализировать ошибки • Повторное использование – низкая зависимость определяет возможности по использованию