Attualmente sto lavorando a una webapp in cui spesso è necessario condizionare alcune logiche del server in base alla pagina che verrà restituita all'utente.
A ogni pagina viene assegnato un codice di pagina di 4 lettere e questi codici di pagina sono attualmente elencati in una classe come stringhe statiche:
public class PageCodes {
public static final String FOFP = "FOFP";
public static final String FOMS = "FOMS";
public static final String BKGD = "BKGD";
public static final String ITCO = "ITCO";
public static final String PURF = "PURF";
// etc..
}
E spesso nel codice vediamo un codice come questo ( 1 ° modulo ):
if (PageCode.PURF.equals(destinationPageCode) || PageCodes.ITCO.equals(destinationPageCode)) {
// some code with no obvious intent
}
if (PageCode.FOFP.equals(destinationPageCode) || PageCodes.FOMS.equals(destinationPageCode)) {
// some other code with no obvious intent either
}
Che è orribile da leggere perché non mostra quale proprietà comune di queste pagine abbia portato l'autore del codice a metterle insieme qui. Dobbiamo leggere il codice nel ramo if
per capire.
Soluzione corrente
Questi if
s sono stati parzialmente semplificati utilizzando elenchi di pagine dichiarate da persone diverse in classi diverse. Questo rende il codice simile ( 2 ° modulo ):
private static final List<String> pagesWithShoppingCart = Collections.unmodifiableList(Arrays.asList(PageCodes.ITCO, PageCodes.PURF));
private static final List<String> flightAvailabilityPages = Collections.unmodifiableList(Arrays.asList(PageCodes.FOMS, PageCodes.FOFP));
// later in the same class
if (pagesWithShoppingCart.contains(destinationPageCode)) {
// some code with no obvious intent
}
if (flightAvailabilityPages.contains(destinationPageCode)) {
// some other code with no obvious intent either
}
... che esprime molto meglio l'intento. Ma ...
Problema corrente
Il problema qui è che se aggiungessimo una pagina, avremmo in teoria bisogno di esaminare tutti i codici base per scoprire se abbiamo bisogno di aggiungere la nostra pagina a if()
o ad una lista come quella.
Anche se spostassimo tutti questi elenchi nella classe PageCodes
come costanti statiche, è necessario disciplinare gli sviluppatori per verificare se la loro nuova pagina si adatta a uno di questi elenchi e aggiungerla di conseguenza.
Nuova soluzione
La mia soluzione era creare un enum (perché esiste un elenco ben noto di codici di pagina) in cui ogni pagina contiene alcune proprietà che è necessario impostare:
public enum Page {
FOFP(true, false),
FOMS(true, false),
BKGD(false, false),
PURF(false, true),
ITCO(false, true),
// and so on
private final boolean isAvailabilityPage;
private final boolean hasShoppingCart;
PageCode(boolean isAvailabilityPage, boolean hasShoppingCart) {
// field initialization
}
// getters
}
Quindi il codice condizionale ora appare come questo ( 3 ° modulo ):
if (destinationPage.hasShoppingCart()) {
// add some shopping-cart-related data to the response
}
if (destinationPage.isAvailabilityPage()) {
// add some info related to flight availability
}
Che è molto leggibile. Inoltre, se qualcuno ha bisogno di aggiungere una pagina, lui / lei è forzato a pensare a ogni booleano e se è vero o falso per la sua nuova pagina.
Nuovo problema
Un problema che vedo è che ci saranno forse 10 booleani come questo, il che rende il costruttore veramente grande e potrebbe essere difficile ottenere la dichiarazione giusta quando si aggiunge una pagina. Qualcuno ha una soluzione migliore?