Quando estamos construindo qualquer tipo de aplicação complexa, desejamos reutilizar o máximo de código possível. O problema é, podemos nos sentir impossibilitados de reutilizar código devido a componentes que são apenas um pouco diferentes, mas a ponto de requerer que os construamos do zero. Neste segundo artigo da série, veremos como o Wicket contorna tal problema reduzindo bastante a quantidade de código que você precisa copiar e colar.
Esta série, que começou com o artigo sobre os modos de desenvolvimento do Wicket stateful e stateless, agora parte para a máquina de renderização que é construída neste estado abstrato. O que ela faz para criar componentes customizados, e como eles facilitam o reuso? Para entender isso, iremos usar a aplicação de exemplo da calculadora apresentada no artigo anterior desta série e refatorá-la para eliminar seu código de layout redundante e então avançar para aplicar permutações de calculadoras para um conjunto de páginas da aplicação.
public abstract class CalcPanel extends Panel {
public CalcPanel(String id) {
super(id);
}
enum Op { ...
O próximo passo é criar a subclasse a partir das duas páginas variantes movendo o código principal para novos panels, mudando apenas os construtores. A Listagem 2 descreve as declarações e construtores das classes.
public class StatelessCalcPanel extends CalcPanel {
protected BigDecimal buf = BigDecimal.ZERO;
protected BigDecimal input = BigDecimal.ZERO;
protected Op op;
public StatelessCalcPanel(String id) {
super(id);
add(new CalcForm("form"));
}
class CalcForm extends StatelessForm {
...
}
}
public class StatelessCalcPanel extends CalcPanel {
protected BigDecimal buf = BigDecimal.ZERO;
protected BigDecimal input = BigDecimal.ZERO;
protected Op op;
public StatelessCalcPanel(String id) {
super(id);
add(new CalcForm("form"));
}
class CalcForm extends StatelessForm {
...
}
}
Neste ponto, poderíamos fazer ajustes superficiais similares para os templates de marcação e ter dois panels que replicam a funcionalidade das duas páginas originais. Mas em vez disso, neste artigo veremos uma implementação que melhorará a funcionalidade original com hierarquia de marcação do Wicket, uma técnica simples para reutilizar layout que provê um ponto de extensão para subclasses.
Marcações, faça bom uso deste recurso
O mecanismo de binding para Wicket é flexível com respeito à hierarquia de classe. Uma classe não precisa obrigatoriamente ter um template caso um esteja definido para uma superclasse (classe-mãe). Sem hierarquia de marcação, um template encontrado para uma subclasse substitui o template na superclasse. Com hierarquia de marcação, o template é inserido dentro do template da superclasse.
No código de exemplo apresentado na primeira parte desta série, a única diferença entre dois templates de página foi a presença de campos de formulário escondidos (hidden) na versão stateless da página. Mas agora iremos mover o template inteiro para a classe base, substituindo os campos escondidos com um ponto de extensão, como mostra a Listagem 3.
<?xml version="1.0" encoding="utf-8"?>
<html>
<wicket:panel>
<form wicket:id="form">
<wicket:child/>
<div>
<span wicket:id="display">0</span>
</div>
<div>
<input id="input-field" type="text" value="0" wicket:id="input" />
<input wicket:id="eq" value="=" type="submit" />
<input type="submit" wicket:id="clear" value="c" />
</div><div>
<input wicket:id="div" value="÷" type="submit" />
<input wicket:id="mult" value="×" type="submit" />
<input wicket:id="sub" value="-" type="submit" />
<input wicket:id="add" value="+" type="submit" />
</div>
</form>
</wicket:panel>
</html>
...