Позвольте мне пройтись по каждой из ваших идей:
1) Плохая идея - вы связываете все свое приложение вместе через один объект.Это затрудняет ремонтопригодность и является противоположностью модульности.
2) Это путь ИМХО.Поскольку кажется, что каждый графический интерфейс имеет уникальную логику в сценарии сбоя, то вполне понятно, что объект, который лучше всего понимает, что делать, это сам объект графического интерфейса.
Другой версией этой идеи было бы созданиеадаптер для каждого графического интерфейса, чтобы положить эту логику сбоя.Преимущество будет в том, что у вас будет меньше зависимости между вашей прикладной средой и вашим графическим интерфейсом.Недостатком является то, что это дополнительный уровень сложности.Если ваш графический интерфейс уже тесно связан с вашим приложением, я бы выбрал метод интерфейса.Если вы хотите повторно использовать свой графический интерфейс в другом приложении, то вам может помочь способ адаптера.
3) Это прекрасно дополняет # 2.Итак, позвольте мне получить это прямо - у вас будет 3 потока: поток ввода-вывода, поток монитора и поток пользовательского интерфейса.Я не знаю, нужна ли вам нить монитора.Исходя из того, что вы говорили, поток ввода-вывода мог бы самостоятельно обнаружить проблему с подключением (возможно, потому, что была обнаружена некоторая форма исключения IOException).Когда обнаружена проблема с подключением, поток ввода-вывода не занят, так как он скоро собирается отключиться, так что он может просто нести ответственность за уведомление графического интерфейса о наличии проблемы.В любом случае у guis должен быть вызван их интерфейсный метод в потоке пользовательского интерфейса, поэтому поток ввода-вывода просто вызывает несколько вызовов invokeLater () (или asyncExec () для SWT), а затем поток ввода-вывода может просто отключиться.
4) (Ваше редактирование) Вы в основном описываете шаблон посетителя.Я не думаю, что это хорошее решение, потому что вызов из потока ввода-вывода в графический интерфейс, а не наоборот.Я не уверен, как передача объекта посетителя поможет в этом случае.
Одна заключительная мысль.Если вы сделаете свой интерфейс универсальным (не специфичным для графического интерфейса пользователя), вы можете применить этот шаблон к другим ресурсам.Например, вы можете захотеть сбросить свои учетные данные пользователя, когда вы потеряете соединение (так как вы говорили о переходе на экран входа в систему снова).Это не совсем логика графического интерфейса и не должна быть сделана из класса графического интерфейса.
Редактировать: Я бы использовал модель событий.Допустим, вы создаете интерфейс, подобный следующему:
public interface ConnectionFailureListener {
void handleConnectionFailure(); // Add an event object if you need it
}
Затем вы можете иметь методы регистрации в каком-либо объекте (может быть, Runnable для потока ввода-вывода или где-то еще, что вам удобно).Эти методы будут довольно стандартными:
public void addConnectionFailureListener(ConnectionFailureListener l) {}
public void removeConnectionFailureListener(ConnectionFailureListener l) {}
Когда вы показываете графический интерфейс на экране, вы добавляете его в свой объект регистрации, а когда вы закрываете графический интерфейс, вы удаляете его из объекта регистрации.Вы можете добавлять другие типы объектов по мере необходимости - например, когда вы входите в систему, вы можете добавить прослушиватель для вашей системы учетных данных и снова удалить его при обработке выхода из системы.
Таким образом, если у вас возникла ошибкапросто прокрутите текущие зарегистрированные слушатели, и слушатель делает свое дело.