Mam aplikację, która składa się z dwóch procesów, jednego procesu klienta z GUI (opartym na SWT) i jednego procesu serwera. Proces klienta jest bardzo lekki, co oznacza, że wiele operacji GUI będzie musiało wysłać zapytanie do procesu serwera lub poprosić o coś, na przykład w odpowiedzi na kliknięcie przycisku przez użytkownika lub wybranie elementu menu. Oznacza to, że nie będzie dużo obsługi zdarzeń, który wygląda tak:Wzorzec dla przepływu żądanie-odpowiedź z klasami wewnętrznymi
// Method invoked e.g. in response to the user choosing a menu item
void execute(Event event) {
// This code is executed on the client, and now we need some info off the server:
server.execute(new RemoteRequest() {
public void run() {
// This code is executed on the server, and we need to update the client
// GUI with current progress
final Result result = doSomeProcessing();
client.execute(new RemoteRequest() {
public void run() {
// This code is again executed on the client
updateUi(result);
}
}
}
});
}
Jednakże, ponieważ server.execute
implikuje serializacji (jest on wykonywany na komputerze zdalnym), wzór ten nie jest możliwe bez dokonywania całość klasa serializowalna (ponieważ klasy wewnętrzne RemoteRequest
nie są statyczne (aby było jasne: nie jest wymagane, aby implementacja Request
mogła uzyskać dostęp do instancji nadrzędnej, ze względu na aplikację mogą być statyczne). jednym z rozwiązań jest utworzenie oddzielnych (prawdopodobnie statycznych wewnętrznych) klas dla Żądania i Odpowiedzi, ale to boli czytelności i utrudnia wymazać przepływ wykonania.
Próbowałem znaleźć jakiś standardowy wzorzec do rozwiązania tego problemu, ale nie znalazłem niczego, co by odpowiadało na moją obawę co do czytelności.
Aby było jasne, będzie wiele takich operacji, a operacje często są dość krótkie. Zauważ, że obiekty Future
nie są tutaj w pełni użyteczne, ponieważ w wielu przypadkach jedno żądanie do serwera będzie wymagało wielu rzeczy na kliencie (często różniących się), a także nie zawsze jest zwracany wynik.
Idealnie chciałabym, aby móc napisać kod tak: (oczywiste pseudo-kod teraz należy lekceważyć oczywistych błędów w szczegóły)
String personName = nameField.getText();
async exec on server {
String personAddress = database.find(personName);
async exec on client {
addressField.setText(personAddress);
}
Order[] orders = database.searchOrderHistory(personName);
async exec on client {
orderListViewer.setInput(orders);
}
}
teraz chcę być jasne, że pod spodem architektura jest na miejscu i działa dobrze, powodem tego rozwiązania jest oczywiście nie powyższy przykład. Jedyne, czego szukam, to sposób napisania kodu jak wyżej, bez konieczności definiowania klas statycznych dla każdej zmiany procesu. Mam nadzieję, że nie tylko komplikowałem sprawę, podając ten przykład ...
W jaki sposób odnosi się to do jms? Czy ten kod jest wykonywany na kliencie, serwerze lub innej maszynie? – Andrejs
Tak, jest. Istnieją przypadki, w których kod jest wykonywany na kliencie i serwerze. Istnieją również przypadki, w których klient wykonuje coś na serwerze, który z kolei wykonuje coś na kliencie. – Krumelur
Myślę, że potrzebujemy trochę więcej szczegółów. Czy prośba/odpowiedź są twoimi własnymi zajęciami, czy są częścią jakiegoś frameworka? Co dokładnie robi execute? – Andrejs