Obecnie pracuję nad aplikacją internetową, w której często musimy uwarunkować logikę serwera na podstawie strony, która zostanie zwrócona użytkownikowi.
Każda strona otrzymuje 4-literowy kod strony, a te kody stron są obecnie wymienione w klasie jako ciągi statyczne:
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..
}
I często w kodzie widzimy kod taki jak ten ( 1. formularz ):
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
}
Co jest trochę okropne do przeczytania, ponieważ nie pokazuje, jaką wspólną własność tych stron skłonił autor kodu do złożenia ich tutaj. if
Aby zrozumieć, musimy przeczytać kod w oddziale.
Aktualne rozwiązanie
Te if
zostały częściowo uproszczone dzięki listom stron zadeklarowanych przez różne osoby z różnych klas. To sprawia, że kod wygląda ( 2. forma ):
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
}
... co wyraża zamiar znacznie lepiej. Ale...
Aktualny problem
Problem polega na tym, że jeśli dodamy stronę, teoretycznie musielibyśmy przejrzeć całą bazę kodu, aby dowiedzieć się, czy musimy dodać naszą stronę do takiej if()
listy lub do takiej listy.
Nawet jeśli przenieśliśmy wszystkie te listy do PageCodes
klasy jako stałe statyczne, nadal wymaga dyscypliny od programistów, aby sprawdzić, czy ich nowa strona pasuje do którejkolwiek z tych list i odpowiednio ją dodać.
Nowe rozwiązanie
Moim rozwiązaniem było utworzenie wyliczenia (ponieważ istnieje skończona dobrze znana lista kodów stron), w których każda strona zawiera pewne właściwości, które musimy ustawić:
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
}
Następnie kod warunkowy wygląda teraz tak ( trzeci formularz ):
if (destinationPage.hasShoppingCart()) {
// add some shopping-cart-related data to the response
}
if (destinationPage.isAvailabilityPage()) {
// add some info related to flight availability
}
Co jest bardzo czytelne. Ponadto, jeśli ktoś musi dodać stronę, jest zmuszony pomyśleć o każdej wartości logicznej i czy jest to prawda, czy fałsz dla nowej strony.
Nowy problem
Jeden z problemów, jaki widzę, polega na tym, że może być 10 boolanów takich jak ten, co czyni konstruktora naprawdę dużym i może być trudno uzyskać prawidłową deklarację podczas dodawania strony. Czy ktoś ma lepsze rozwiązanie?
false
, a następnie zmodyfikują jeden lub dwa (prawdopodobnie niewłaściwy, ponieważ tak trudno jest śledzić). Nie ma doskonałej ochrony przed głupotami i przychodzi moment, w którym musisz zaufać swoim programistom, aby postępowali właściwie.