Архитектура Java - должны ли обычно используемые классы передаваться в конструкторах? - PullRequest
3 голосов
/ 18 июля 2011

Я разрабатываю настольное приложение с графическим интерфейсом на Java, которое имеет интерфейс с вкладками (как вкладки в вашем браузере).

Класс MainWindow создает окно с вкладками, загружая другие классы SWT, которые имеюткод для каждой вкладки, например, Tab1Composite, Tab2Composite.Существуют также классы, которые обрабатывают действия для меню панели инструментов и поэтому полагаются на MainWindow для таких вещей, как локализация (связки), переключение между вкладками и т. Д.

До сих пор я пропускал экземпляр MainWindowвокруг в конструкторе для других классов.Это похоже на «хорошую практику», но я не могу не заметить, насколько проще был бы мой код, если бы я просто сделал все необходимые переменные и методы статичными.

Есть мысли о том, какой подход мне следует использовать?

Ответы [ 8 ]

4 голосов
/ 18 июля 2011

«Хорошая практика» означает написание кода, который можно понять, использовать повторно и расширить.Иногда быстрое и грязное имеет больше смысла, но код, как правило, живет дольше и сложнее, чем мы ожидаем, и делать это правильно - хорошая практика, даже если это не так.

Ваше главное окно - хорошая идея для начала,Это набор данных, необходимых во многих местах.Необходимость прохождения его «через 9 промежуточных слоев» выглядит неловко, но ясно дает понять, что каждый из этих 9-слойных методов, рассматриваемых как единое целое, действительно нуждается информация в MainWindow.Использование глобальных переменных скрыло бы эту необходимость и стало бы своего рода практической шуткой для любого, кто пытается поддерживать или улучшать код.

Однако MainWindow также создает окна, вкладки и тому подобное.Это не нужно передавать , поэтому я бы создал другой класс для передачи информации.Это упрощает вещи.Нашему будущему специалисту по техническому обслуживанию (это может быть вы), который просматривает вызов с уровня 4 на уровень 5, больше не нужно ломать голову над тем, почему слою 5 необходимо создавать вкладки.Возможно, имеет смысл создать несколько таких классов, чтобы минимизировать объем информации, которая отправляется туда, где она не нужна.

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

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

(Обратите внимание, что открытые поля и статические методы не работают хорошо с интерфейсами Java! Избегайте их.)

2 голосов
/ 18 июля 2011

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

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

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

С другой стороны, Java не является моим предпочтительным языком, поэтому я могу смешать несколько понятий.

2 голосов
/ 18 июля 2011

Если вы не будете создавать какие-либо экземпляры вашего класса MainWindow, я бы сделал общие члены статическими.Однако на нестатические члены нельзя ссылаться из статического контекста, поэтому, если в ваших теперь статических методах вы используете другие нестатические методы и переменные, они также должны быть статическими.

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

Старайтесь избегать создания чего-либо статического (кроме констант).Отделение вашего GUI от «работы» - это то, что нужно делать.Рассматривайте вашу программу как дерево и структурируйте ее так, чтобы создаваемому объекту не нужно было вызывать что-то над ним в дереве.Конечно, это не всегда возможно, но облегчает тестирование, расширение и отладку (в большинстве случаев).

1 голос
/ 18 июля 2011

Я немного работаю с графическим интерфейсом, но я думал об этой проблеме. Я думаю, что правильный способ сделать это - сначала убедиться, что у вас есть четкое разделение между вашими презентационными классами (виджетами / компонентами) и логикой, лежащей в их основе, в основном используя интерфейсы обратного вызова, которые позволяют вам обмениваться сообщениями между уровнями. Для приложений хорошего размера я бы использовал DI-фреймворк для управления «логическими» объектами в фоновом режиме. Тогда все, что нужно, - это некоторый каркасный код - для этого, возможно, уже есть структура, о которой я не знаю, - которая позволяет легко связывать ваши объекты презентации с bean-компонентами, управляемыми вашим DI-контейнером. Избегайте статичных вещей любой ценой. Это совершенно неправильное приложение, если вы не заботитесь о тестировании.

1 голос
/ 18 июля 2011

Вы можете определить MainWindow как синглтон.

0 голосов
/ 19 июля 2011

Что-то очень удобное для вашего случая, я только что подумал сегодня вечером:

http://download.oracle.com/javase/1.4.2/docs/api/javax/swing/JComponent.html#getRootPane()

0 голосов
/ 18 июля 2011

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

0 голосов
/ 18 июля 2011

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

...