Принцип инверсии зависимостей (DIP) и внедрение зависимостей (DI) — связанные концепции, но они имеют разные значения. Давайте обсудим разницу между ними и приведем пример для каждого.
Принцип инверсии зависимостей (DIP)
Принцип инверсии зависимостей — это принцип проектирования, который гласит, что классы высокого уровня не должны напрямую зависеть от классов низкого уровня. Вместо этого как высокоуровневые, так и низкоуровневые модули должны зависеть от абстракций (интерфейсов или абстрактных классов). Этот принцип обеспечивает слабую связанность и модульность за счет разделения модулей и упрощения обслуживания и расширяемости.
Пример DIP:
Рассмотрим пример платежной системы. У нас есть класс PaymentService
, который зависит от конкретного класса PaymentGateway
.
public class PaymentService { private PaymentGateway paymentGateway; public PaymentService() { this.paymentGateway = new PaymentGateway(); } public void processPayment(double amount) { paymentGateway.processPayment(amount); } }
В этом примере класс PaymentService
напрямую зависит от класса PaymentGateway
, что нарушает принцип инверсии зависимостей. Если мы хотим изменить реализацию платежного шлюза или ввести новые платежные шлюзы, нам нужно изменить класс PaymentService
.
Чтобы придерживаться принципа инверсии зависимостей, мы вводим абстракцию (интерфейс) PaymentProvider
и зависим от этой абстракции как высокоуровневый PaymentService
, так и низкоуровневый PaymentGateway
:
public interface PaymentProvider { void processPayment(double amount); } public class PaymentGateway implements PaymentProvider { public void processPayment(double amount) { // Process payment using the payment gateway } } public class PaymentService { private PaymentProvider paymentProvider; public PaymentService(PaymentProvider paymentProvider) { this.paymentProvider = paymentProvider; } public void processPayment(double amount) { paymentProvider.processPayment(amount); } public static void main(String[] args){ paymentProvider = new PaymentGateway(); PaymentService paymentService= new PaymentService(paymentProvider); paymentService.processPayment(1000); } }
Внедрив интерфейс PaymentProvider
, класс PaymentService
теперь зависит от абстракции, а не от конкретной реализации. Он больше не тесно связан с классом PaymentGateway
, что упрощает переключение или введение новых платежных шлюзов без изменения класса PaymentService
.
Внедрение зависимости
Внедрение зависимостей — это способ внедрить зависимость компонента фреймворка с помощью внедрения конструктора и внедрения сеттера, что обеспечивает слабую связь между классами.
Внедрение зависимостей конструктора (CDI). В этом случае DI будет внедряться с помощью конструкторов.
public interface UserRepository { void save(User user); } @Repository public class UserRepositoryImpl implements UserRepository { public void save(User user) { // Save user to the database } } @Service public class UserService { private UserRepository userRepository; // Dependency Injection via Constructor public UserService(UserRepository userRepository) { this.userRepository = userRepository; } public void registerUser(User user) { // Perform user registration logic userRepository.save(user); } } public class User { // User class implementation }
Внедрение зависимостей установщика (SDI). В этом случае DI будет внедряться с помощью методов установщика.
@Service public class UserService { private UserRepository userRepository; // Dependency Injection via Setter Method public void setUser(UserRepository userRepository) { this.userRepository = userRepository; } public void registerUser(User user) { // Perform user registration logic userRepository.save(user); } }
С помощью Autowire. В приложении Spring Boot вы можете использовать аннотацию @Autowired
для внедрения зависимостей в ваши классы. Spring Boot автоматически создает и внедряет необходимые зависимости на основе аннотаций и конфигураций.
@RestController public class UserController { @Autowired private UserService userService; @PostMapping("/users") public void registerUser(@RequestBody User user) { userService.registerUser(user); } }
Заключение
Внедрение зависимостей больше сосредоточено на структуре кода, его основное внимание уделяется сохранению слабосвязанного кода. с другой стороны, внедрение зависимостей — это то, как функционально работает код. При программировании с помощью Spring Framework Spring использует внедрение зависимостей для сборки приложения.
Обратитесь по ссылкам для других концепций Spring Boot:
Ролевой доступ Spring Security с Spring Boot
Аутентификация и авторизация Spring Security с помощью JWT
Учебник по логированию Spring Boot
Централизованная конфигурация в Spring Boot
Пользовательские проверки в Spring Boot
Джавинпол Доменико Николи Трей Хаффин Мехмет Арсл Мехмет Озкая Образовательная команда