Il mio spazio di dominio è Java + RxJava ma penso che questo si applichi a qualsiasi framework reattivo
Ho una pila che assomiglia al diagramma qui sotto. Solo per motivi di esempio sto descrivendo un flusso di login ma qualsiasi flusso di UI --> web request --> UI
sarebbe lo stesso.
+-----------------+
| |
| UI |
| |
+-----------------+
| wasSuccessful (boolean)
| name
+-----------------+
| |
| DataManager |
| |
+-----------------+ response code
| userID
| name
+-----------------+
| |
| ApiManager |
| |
+-----------------+ response code (i.e. 200)
| {
| "user_id":123,
+-----------------+ "name":"Bob",
| | "auth_token":"asdf"
| web client | }
| |
+-----------------+
- Il livello dell'interfaccia utente effettua una chiamata a DataManager per accedere a un utente
- DataManager chiama ApiManager per effettuare una richiesta Web per l'accesso dell'utente
- ApiManager chiama il client Web per accedere all'utente
- il client web restituisce l'utente come json
- ApiManager deserializza json, mantiene il token di autenticazione (dal momento che il livello di DataManager non ha bisogno di sapere su auth) e passa il codice di risposta, userId e il nome utente a DataManager
- DataManager mantiene userId (dal momento che l'interfaccia utente non ha bisogno di conoscere userId) e passa il nome utente e un valore booleano (che rappresenta la richiesta riuscita) al livello dell'interfaccia utente
- Il livello dell'interfaccia utente visualizza l'errore se la richiesta non è riuscita o visualizza il nome utente
Sto usando un flusso reattivo per realizzare tutto questo: ogni livello parla con quelli sopra e sotto con osservabili. Ogni livello conosce solo gli strati su entrambi i lati per avere una buona separazione dei problemi.
Parte del framework RxJava è che lo stream può emettere solo singoli oggetti. Quindi devo raggruppare tutti questi dati in classi:
class WebClientLogin {
int responseCode;
String userId;
String name;
String authToken;
}
class ApiLogin {
int responseCode;
String userId;
String name;
}
class Login {
boolean wasSuccessful;
String name;
}
Il problema è che sto creando tutte le piccole classi che sono appena utilizzate per raggruppare insieme dati disparati. Non si traducono in astrazioni significative come una classe User
.
Anch'io non ho una buona convenzione di denominazione per loro. Se un altro sviluppatore dovesse venire in seguito, non saprebbero cosa fosse ApiLogin
o come / perché / dove usarlo. Dovevano andare a vedere dove era attualmente utilizzato per avere un'idea di cosa avrebbe dovuto fare. Confronta questo con una classe chiamata PizzaToppingIterator
che descrive che è e quando potresti voler usare.
C'è un modo migliore per raggiungere questo obiettivo? O un modo migliore per organizzare questa struttura?
Ho pensato forse a rendere Login
, ApiLogin
e WebClientLogin
come classi interne statiche nell'oggetto più grande che li ha creati: DataManager.Login
, ApiManager.Login
, WebClient.Login
so che era più chiaro quando sarebbero stati usati. Ma questo non è ancora giusto. DataManager
, ApiManager
e WebClient
finirebbero con molte di queste classi interne.
Sicuramente voglio mantenere le divisioni di livello (veramente utile altrove e per i test) e voglio davvero mantenere i flussi reattivi tra i livelli.