Ερώτηση java API design

12 views
Skip to first unread message

George Georgovassilis

unread,
May 18, 2019, 6:14:15 AM5/18/19
to jhug

Αγαπητοί,

μπορείτε να με βοηθήσετε σε ένα API design;


Ίσως θυμάστε από το Swing ή το GWT τα event handlers. Η ιδέα είναι πως απεμπλέκεις δυο κομμάτια Α και Β που έχουν λειτουργική αναφορά το ένα στο άλλο. Δηλ πες πως στην έχεις κάτι του στυλ:


class A{
 
void logUserEnteredWrongPassword(String user){
     logger
.warn("user "+user+" entered wrong password");
 
}
}

class B{
 
 A a
;
 
 
void login(String user, String password){
     
if (!...) a.logUserEnteredWrongPassword(user);
 
}
}


Εδώ το Β έχει μια εξάρτηση από το Α. Με events αυτό γράφεται:


class A implements UserAuthenticationEventListener{
 
 
public A(EventBus bus){
     bus
.addListener(this);
 
}
 
 
@Override
 
void onUserEnteredWrongPassword(UserAuthenticationEvent e){
     logger
.warn("user "+e.user+" entered wrong password");
 
}
}

class B{

EventBus bus;
 
void login(String user, String password){
     
if (!...) bus.fireEvent(new UserAuthenticationEvent(fail, user))M
 
}
}


Για κάθε λειτουργία πρέπει να:

- φτιάξεις μια event κλάση
- φτιάξεις ένα listener
- θες ένα event bus
- να τα δέσεις

Επειδή (εδώ) υπάρχει 1:1 αντιστοιχεία μεταξύ events και listeners βρήκα τρόπο με java 8 lambdas να απλοποιήσω το event bus και να δουλεύει χωρίς events, πετυχαίνοντας όμως την ανεξαρτητοποίηση του Α από το Β.

Ο κώδικας του event bus είναι εδώ: https://github.com/ggeorgovassilis/superstartrek/tree/gh-pages/src/main/java/superstartrek/client/bus


Τα unit tests είναι εδώ:

https://github.com/ggeorgovassilis/superstartrek/tree/gh-pages/src/test/java/genericsbus


Παρά την σημαντική απλοποίηση παραμένει το κάπως πολύπλοκο συντακτικό όταν στέλνεις events:

bus.invoke(Events.EVENT2, (Callback<Handler2>) ((h) -> h.method2("p1","p2")));



Το casting στο lambda callback χρειάζεται για να ξέρει ο compiler τι είδους interface είναι το h. Βλέπετε κάτι απλούστερο;

George Georgovassilis

unread,
May 18, 2019, 8:32:47 AM5/18/19
to jhug
Βρέθηκε λύση :)

Αν το event από String γίνει template με το τύπο του handler, τότε ο compiler ξέρει και τον τύπο της παραμέτρου του λ.

interface SomeHandler{

void method1(int a, int b);

}

...

Event<SomeHandler> SOME_EVENT = new Event<>();

...
bus
.invoke(SOME_EVENT, (h)->h.method1(77,88));



Reply all
Reply to author
Forward
0 new messages