Atualmente, estou trabalhando em um aplicativo da Web em que geralmente precisamos condicionar alguma lógica do servidor com base na página que será devolvida ao usuário.
Cada página recebe um código de página de 4 letras e, atualmente, esses códigos de página estão listados em uma classe como Strings estáticas:
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, muitas vezes, no código, vemos códigos como este ( 1º formulário ):
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
}
O que é meio horrível de ler porque não mostra que propriedade comum dessas páginas levou o autor do código a reuni-las aqui. Temos que ler o código no if
ramo para entender.
Solução atual
Estes if
s foram parcialmente simplificados usando listas de páginas que são declaradas por pessoas diferentes em classes diferentes. Isso faz com que o código pareça ( 2º formulário ):
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
}
... que expressa a intenção muito melhor. Mas...
Problema atual
O problema aqui é que, se adicionarmos uma página, em teoria, precisaremos percorrer toda a base de código para descobrir se precisamos adicionar nossa página a uma if()
ou a uma lista como essa.
Mesmo se movermos todas essas listas para a PageCodes
classe como constantes estáticas, ainda será necessário disciplina dos desenvolvedores para verificar se a nova página se encaixa em alguma dessas listas e incluí-la de acordo.
Nova solução
Minha solução foi criar uma enumeração (porque existe uma lista bem conhecida finita de códigos de página) em que cada página contém algumas propriedades que precisamos definir:
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
}
Então o código condicional agora se parece com este ( terceiro formulário ):
if (destinationPage.hasShoppingCart()) {
// add some shopping-cart-related data to the response
}
if (destinationPage.isAvailabilityPage()) {
// add some info related to flight availability
}
O que é muito legível. Além disso, se alguém precisar adicionar uma página, ele será forçado a pensar em cada booleano e se isso é verdadeiro ou falso para a nova página.
Novo Problema
Um problema que vejo é que haverá talvez 10 booleanos como este, o que torna o construtor realmente grande e pode ser difícil obter a declaração correta ao adicionar uma página. Alguém tem uma solução melhor?
false
e modifiquem um ou dois (provavelmente o errado, pois é tão difícil acompanhar isso). Não existe uma proteção perfeita contra o estúpido, e chega um momento em que você deve confiar nos seus desenvolvedores para fazer a coisa certa.