De forma a completar um pouco mais o artigo anterior Enumeração em Java vou agora exemplificar o uso de enum em Java para criar enumerações que executam acções encapsuladas em cada uma delas.
Para começar vamos implementar a enumeração, neste caso o nosso objectivo é o de ter vários formatadores de texto e ao passar um determinado texto para um formatador ele deve devolver esse texto formatado consoante a implementação desse formatador.
Esta solução poderia ser implementada de outras formas, mas neste caso vamos recorrer a uma enum
import java.io.InvalidClassException;
/**
* Conjunto de formatadores de texto.
* @author magician
*
*/
public enum Formater {
/**
* Formatação do texto em HTML
*/
HTML(1){
@Override
public String format(String text) {
return String.format("<html>\n\t<head>\n\t\t<title>FORMATED TEXT</title>\n\t</head>\n\t<body>\n\t\t%s\n\t</body>\n</html>", text);
}
},
/**
* Formatação do texto em XML
*/
XML(2){
@Override
public String format(String text) {
return String.format("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<page>\n\t<head>\n\t\t<title>FORMATED TEXT</title>\n\t</head>\n\t<body>\n\t\t%s\n\t</body>\n</page>", text);
}
},
/**
* Formatação do texto em JSON
*/
JSON(3){
@Override
public String format(String text) {
return String.format("{\n\tpage:{\n\t\thead:{\n\t\t\ttitle:'FORMATED TEXT'\n\t\t},\n\t\tbody:'%s'\n\t}\n}", text);
}
};
/**
* Identificar numérico do Formater
*/
private final int ID;
private Formater(int id){
ID = id;
}
/**
* Devolve o identificador numérico associado ao formater
* @return identificador numérico
*/
public int getID() {
return ID;
}
/**
* Procura por um Formater especifico através do identificador ao
* invés do nome
* @param id identificador numérico do formater pretendido
* @return Formater que corresponde ao id dado
* @throws InvalidClassException Ocorre caso não exista nenhum Formater com o id dado
*/
public static Formater getFormater(int id) throws InvalidClassException {
for(Formater f : values()){
if(f.ID == id){
return f;
}
}
throw new InvalidClassException(String.format("Enum with id %d not found.", id));
}
/**
* Procura por um Formater especifico através do identificador ao
* invés do nome, em seguida formata o texto com a implementação
* desse formater.
* @param id identificador numérico do formater pretendido
* @param text String com o texto a ser formatado
* @return String com texto formatado
* @throws InvalidClassException
*/
public static String formatText(int id, String text) throws InvalidClassException {
return getFormater(id).format(text);
}
/**
* Formata o texto enviado seguindo a implementação escolhida.
* @param text String com o texto a ser formatado
* @return String com o texto formatado.
*/
public abstract String format(String text);
}
Como podemos ver para além da típica enumeração de um conjunto de nomes (HTML,XML,JSON….) temos também métodos implementados em cada um desses nomes. Podemos pensar como se o Formater fosse uma classe abstract e o HTML, XML e JSON fosse subclasses da Formater mas “dentro” da classe formater.
Para esta implementação basta na base da enum declarar métodos abstract e estes são implementados em cada um dos nomes que existem na enum. Para além disso temos também um construtor que vai ser usado na declaração dos nomes (HTML(1), XML(2), JSON(3)) e os métodos static que permitem fazer operações sobre a enum genérica ao invés de cada um dos nomes.
Vejamos agora como utilizar o nosso Formater implementado com enum.
import java.io.InvalidClassException;
public class Main {
private static final int HTML_ID = 1;
private static final int XML_ID = 2;
private static final int JSON_ID = 3;
public static void main(String[] args) {
String text = "Hello World xD";
String HTML = Formater.HTML.format(text);
System.out.println("-----------------------HTML----------------------");
System.out.println(HTML);
String XML = Formater.XML.format(text);
System.out.println("-----------------------XML-----------------------");
System.out.println(XML);
String JSON = Formater.JSON.format(text);
System.out.println("-----------------------JSON----------------------");
System.out.println(JSON);
try {
String XML_FROM_ID = Formater.getFormater(XML_ID).format(text);
System.out.println("------------------XML_FROM_ID--------------------");
System.out.println(XML_FROM_ID);
String JSON_FROM_ID = Formater.formatText(JSON_ID, text);
System.out.println("------------------JSON_FROM_ID--------------------");
System.out.println(JSON_FROM_ID);
Formater INVALID_ID = Formater.getFormater(100);
} catch (InvalidClassException e) {
System.err.println(e.getMessage());
}
}
}
No bloco [12-22] utilizamos o Formater especificando o nome da implementação a ser usada e chamamos o método format da implementação escolhida, neste caso recorremos às três implementações.
Em seguida no bloco [25-27] usamos o método static getFormater para através de um id devolver o formater com esse id ao invés de recorrer ao nome como foi feito antes. Esta forma pode ser útil quando temos identificadores externos à enum ou quando queremos tornar a escolha mais dinâmica ao invés de recorrer a uma cadeia de if-else ou switch.
O método static formatText (bloco [29-31]) recorremos ao método static formatText que no fundo faz o mesmo que o método getFormater mas a chamada ao método format fica oculta.
Para finalizar na linha 33 enviamos um id que não existe e neste caso é lançada uma exception a informar que não existe nenhum Formater com o id enviado.
Após a execução temos o seguinte output
-----------------------HTML----------------------
<html>
<head>
<title>FORMATED TEXT</title>
</head>
<body>
Hello World xD
</body>
</html>
-----------------------XML-----------------------
<?xml version="1.0" encoding="UTF-8"?>
<page>
<head>
<title>FORMATED TEXT</title>
</head>
<body>
Hello World xD
</body>
</page>
-----------------------JSON----------------------
{
page:{
head:{
title:'FORMATED TEXT'
},
body:'Hello World xD'
}
}
------------------XML_FROM_ID--------------------
<?xml version="1.0" encoding="UTF-8"?>
<page>
<head>
<title>FORMATED TEXT</title>
</head>
<body>
Hello World xD
</body>
</page>
------------------JSON_FROM_ID--------------------
{
page:{
head:{
title:'FORMATED TEXT'
},
body:'Hello World xD'
}
}
Enum with id 100 not found.
Como referi existem outras formas de implementar este mesmo mecanismo esta é apenas mais uma fazendo uso dos recursos da linguagem Java.
