Применение шаблона внедрения зависимостей без DI-контейнера - это практика, обычно называемая Pure DI .При таком подходе вы применяете те же принципы и практики объектно-ориентированного проектирования и DI.Но вместо того, чтобы подключать все с помощью DI-контейнера, а по пути запуска приложения, вы строите свои графы объектов вручную, используя ключевое слово new
.
Pure DI - это распространенный и правильный подходпрактика DI - контейнеры DI полезны, но необязательные инструменты.
Это, однако, не тот подход, который вы практикуете в настоящее время.Вы не вводите свои зависимости своим потребителям.Создав BookRepositoryImpl
внутри класса BookService
, вы применяете анти-паттерн Control Freak с особой формой нарушения Принцип инверсии зависимостей .Это тесно связывает класс BookRepositoryImpl
с классом BookService
, что, вероятно, вызовет проблемы с удобством обслуживания, поскольку BookRepositoryImpl
является изменчивой зависимостью .Изменчивые зависимости - это причина, по которой мы вводим абстракции и используем Dependency Injection.
Кроме того, использование статических полей только усиливает боль, поскольку это может вызвать проблемы безопасности потоков в случае BookRepositoryImpl
(или одной из его зависимостей).) не ориентирован на многопотоковое исполнение.
Таким образом, вместо сильной связи BookRepositoryImpl
с BookService
, вы должны вставить абстракцию BookRepository
в конструктор BookService
.Это обеспечивает слабую связь двух компонентов и дает вам все преимущества, которые дает слабая связь:
@Path("/books")
public class BookService {
private final BookRepository bookRepository;
public BookService(BookRepository bookRepository) {
this.bookRepository = bookRepository;
}
@POST
@Path("")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Book registerBook(Book b) {
return bookRepository.saveBook(b);
}
}
Это, однако, означает, что вам следует переопределить способ, которым ваша веб-платформа REST API создает эту службу.Такая структура обычно может создавать экземпляры только от вашего имени, если у них есть конструктор по умолчанию.Я должен признать, что у меня нет опыта работы с JAX-RS, но большинство сред позволяют переопределять создание своих корневых классов.Например, с помощью инфраструктуры ASP.NET MVC вы можете реализовать пользовательский IControllerFactory
и заменить реализацию платформы по умолчанию.Внутри вашей собственной фабрики вы создадите полное дерево вручную с простой старой Java:
public IController Create(Type controllerType)
{
if (controllerType == typeof(HomeController))
return new HomeController(new PersonsRepositoryImpl(this.connectionString));
if (controllerType == typeof(BooksController))
return new BooksController(new BookRepositoryImpl(this.connectionString));
if (...)
throw new InvalidOperationException(controllerType.FullName + " unknown.");
}
Я ожидаю, что JAX-RS содержит аналогичную модель расширения, которая позволяет вам практиковать Pure DI.