Инъекция зависимостей только для объектов типа службы и синглетонов? (а НЕ для графического интерфейса?) - PullRequest
5 голосов
/ 02 июня 2010

Я сейчас экспериментирую с хитрой инверсией Google контрольного контейнера. Ранее у меня были синглтоны практически для любой службы (базы данных, активной директории), которую использовало мое приложение. Теперь я реорганизовал код: все зависимости приведены в качестве параметров для конструкторов. Все идет нормально. Теперь самое сложное - это графический интерфейс пользователя. Я сталкиваюсь с этой проблемой: у меня есть таблица (JTable) продуктов, завернутая в ProductFrame. Я даю зависимости как параметры (EditProductDialog).

@Inject
public ProductFrame(EditProductDialog editProductDialog) {
  // ...
}

// ...

@Inject
public EditProductDialog(DBProductController productController, Product product) {
  // ...
}

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

Внедрение зависимостей является довольно вирусным (если я изменяю один класс для использования внедрения зависимостей, мне также нужно изменить все другие классы, с которыми он взаимодействует), поэтому мой вопрос заключается в том, должен ли я непосредственно создавать экземпляр EditProductDialog? Но тогда мне придется вручную передать DBProductController в EditProductDialog, и мне также нужно будет передать его в ProductFrame, и все это сводится к тому, чтобы вообще не использовать внедрение зависимостей.

Или мой дизайн несовершенен, и из-за этого я не могу адаптировать проект к внедрению зависимости?

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

Ответы [ 5 ]

1 голос
/ 03 июня 2010

Из того, что я вижу в вашем примере кода, я не уверен, что передача Product в EditProductDialog - лучший дизайн, это означает, что вы не можете повторно использовать одно и то же диалоговое окно для 2 разных продуктов.

В общем, я бы лучше добавил setProduct(Product) к EditProductDialog, чтобы:

  • включить повторное использование того же диалога
  • разрешить внедрение в конструктор самого диалога

Кроме того, вы также можете, если хотите сохранить текущие аргументы конструктора, взглянуть на Guice Assisted Injection , который позволит вам внедрить все зависимости в конструктор, при этом предоставляя продукт явно.

Наконец, вы можете взглянуть на Guts-GUI , среду с открытым исходным кодом для создания Swing GUI с Guice (все еще в работе, но готова к использованию на сегодняшний день). В нем есть пример приложения, которое содержит примеры многоразовых диалогов.

1 голос
/ 03 июня 2010

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

Использовать внедрение зависимостей для зависимостей, которые могут быть разрешены Guice (при запуске приложения). Используйте аргументы метода для установки любого состояния ваших сервисов, которое определяется логикой приложения и поэтому известно только позже, во время выполнения.

В этом конкретном случае код, который решает, какой продукт показать (предположительно, ProductFrame, который знает выбор в таблице), вызовет метод SetProduct в диалоговом окне перед его отображением.

1 голос
/ 02 июня 2010

A составной GUI , безусловно, может использовать DI. Тем не менее, вы должны быть догматичными в отношении сохранения составной ориентации. Любая прямая связь между элементами интерфейса вызовет много головной боли.

0 голосов
/ 02 июня 2010

Зависит от того, что мы подразумеваем под «GUI».

Я бы не использовал DI для JSP, но я бы использовал контроллеры, взаимодействующие с ними. Я считаю контроллеры частью пользовательского интерфейса. Я внедряю валидаторы, картографы и сервисы, которые им нужны для выполнения запросов и составления ответов.

Если вы согласны, тогда DI подходит для слоя просмотра.

0 голосов
/ 02 июня 2010

Я полагаю, использование Guice в разработке Desktop GUI лучше всего подходит для настройки сервиса.

При таком подходе вам необходимо правильно настроить области взаимодействия, чтобы иметь возможность правильно вводить объекты служб пользователя, которые выбраны в графическом интерфейсе, в службы.

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

SelectionService может быть что-то вроде этого

public interface SelectionService {

    Product getSelectedProduct();

    // ...

}

При разработке веб-интерфейса, например, у вас есть Session и Request scope. Я полагаю, что в программировании GUI для настольных компьютеров область видимости сложнее, поэтому я бы выбрал DI для одноэлементных сервисов, а также для подключения статических компонентов GUI и создания экземпляров вручную для всего остального.

И если вам нужно сделать данные выбора доступными в качестве службы, фрагмент кода может помочь.

...