Поток графического интерфейса оповещения о потоке ввода-вывода при возникновении ошибки

У меня вопрос клиент / сервер, для которого я пытаюсь найти лучшее решение.

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

То, как я думал об этом до сих пор:

1) Создайте объект, который создает и показывает каждый графический интерфейс. Таким образом, вместо вызова invokeLater ... SomeGui.CreateAndShoGui () ... за этот объект должен отвечать этот объект, т. Е. GuiObject.showSomeGui ();

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

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

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

Спасибо

РЕДАКТИРОВАТЬ: Другой вариант, с которым я играю, это наличие объекта в потоке ввода-вывода, который также передается каждому новому графическому интерфейсу при его открытии. Этот объект возвращает текущую открытую ссылку guis обратно в поток io, так что поток io может предупредить его, если что-то пойдет не так. Я опираюсь на это решение, потому что кажется, что было бы легче читать, если бы у вас был один объект, который был выделен для этой работы (как вышеупомянутое решение), вместо того, чтобы передавать какой-то непонятный объект каждому графическому интерфейсу.

1
задан vimalloc 19 August 2010 в 22:17
поделиться

1 ответ

Позвольте мне просто рассмотреть каждую из ваших идей:

1) Плохая идея - вы связываете все свое приложение вместе с помощью одного объекта. Это затрудняет ремонтопригодность и является полной противоположностью модульности.

2) Это путь ИМХО. Поскольку кажется, что каждый графический интерфейс имеет уникальную логику в сценарии сбоя, логично предположить, что объектом, который лучше всего понимает, что делать, будет сам объект графического интерфейса.

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

3) Это прекрасно дополняет №2. Итак, позвольте мне сказать прямо - у вас будет 3 потока: поток ввода-вывода, поток монитора и поток пользовательского интерфейса. Я не знаю, нужен ли вам поток монитора. Из того, что вы говорили, поток ввода-вывода сможет сам обнаружить проблему с подключением (вероятно, потому, что была обнаружена какая-то форма IOException). Когда обнаруживается проблема с подключением, поток ввода-вывода не занят, так как он просто скоро отключится, поэтому он может просто уведомить guis о том, что возникла проблема.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) {}

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

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

2
ответ дан 2 September 2019 в 21:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: