Mais Enumeração em Java

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.

Anúncios

Deixe uma Resposta

Preencha os seus detalhes abaixo ou clique num ícone para iniciar sessão:

Logótipo da WordPress.com

Está a comentar usando a sua conta WordPress.com Terminar Sessão /  Alterar )

Google photo

Está a comentar usando a sua conta Google Terminar Sessão /  Alterar )

Imagem do Twitter

Está a comentar usando a sua conta Twitter Terminar Sessão /  Alterar )

Facebook photo

Está a comentar usando a sua conta Facebook Terminar Sessão /  Alterar )

Connecting to %s