Attualmente sto provando a progettare un'applicazione web Java EE.
Le viste sono piuttosto complesse, ad esempio diversi menu a discesa dinamici. Il contenuto di questi drop down può dipendere dallo stato interno del modello, dai privilegi dell'utente, ecc., Solo per menzionare una cosa qui.
Per evitare la logica nel livello di presentazione, ho introdotto un livello di facciata del servizio, in cui tutte le decisioni condizionali che i dati da spedire al cliente sono eseguiti, nonché la conversione in DTO.
Per evitare dozzine di chiamate del mio bean back-up JSF / CDI al livello di servizio, ho pensato di raccogliere tutti i dati necessari per la visualizzazione in un grande DTO, quindi il client deve fare solo una chiamata per initialzation. Vedo il vantaggio che tutti i dati possono essere raccolti in un'unica transazione, il che assicura che sia facile spedire dati coerenti al cliente. lo strato di presentazione diventa molto leggero e intuitivo. Il livello di presentazione non deve preoccupare da dove provengono i dati, è tutto disponibile nella facciata del servizio personalizzato singolo.
Ma sto anche affrontando il problema che sto accoppiando strettamente il mio servizio con il punto di vista che sembra essere terribilmente sbagliato. Infine finirei in un servizio facciata per vista, che fornisce al DTO una visione speciale e che sta recuperando e delegando tutte le azioni che il client sta attivando. Ora, se ci sono cambiamenti nella vista (ad esempio un campo di input aggiuntivo), dovrei modificare anche la facciata del servizio e il DTO spedito.
I vantaggi di un tale servizio di facciata in sovrappeso sono piuttosto trascurabili? Hai qualche suggerimento per il design qui?
In sostanza, quale approccio preferire e perché?
Metodo 1:
@Named @ViewScoped
public class MyBacking implements Serializable {
@Inject private Service service;
@PostConstruct
private void init() {
this.dto = servive.find();
}
}
@Stateless
@Local(Service.class)
public class ServiceFacadeImpl implements Service {
@Inject private ServiceA serviceA;
@Inject private ServiceB serviceB;
public DTO find() {
PartA a = serviceA.find();
PartB b = serviceB.find(a);
return Mapper.map(a,b);
}
}
Approccio 2:
@Named @ViewScoped
public class MyBacking implements Serializable {
@Inject private ServiceA serviceA;
@Inject private ServiceB serviceB;
@PostConstruct
private void init() {
this.aDTO = serviveA.find();
this.bDTO = serviceB.find(aDTO.foo);
}
}
@Stateless
@Local(ServiceA.class)
public class ServiceAImpl implements ServiceA {
public ADTO find() {
Part a = ...
return Mapper.map(a);
}
}
@Stateless
@Local(ServiceB.class)
public class ServiceBImpl implements ServiceB {
public BDTO find(ADTO a) {
Foo foo = a.foo ...
PartB b = ...
return Mapper.map(b);
}
}