Decorator Pattern (padrão de desenho)/Exercício 2: Textos Formatados (take 2)

From Wiki**3

< Decorator Pattern (padrão de desenho)

Problema

Um texto é constituído por palavras. Quando o texto é apresentado, através do método render, cada palavra pode aparecer sem qualquer modificação de aspecto (utiliza-se o método render correspondente). É ainda possível modificar dinamicamente o aspecto das palavras, permitindo que sejam apresentadas em negrito, itálico, sublinhado, ou em combinações variadas (e.g. negrito e itálico ou itálico sublinhado, etc.). No entanto, a apresentação é sempre realizada da mesma forma (sempre através do método render).

Além de apresentável graficamente, um texto pode ser convertido numa cadeia de caracteres, contendo a sua informação textual (String). Esta operação é realizada através do método text (invocado sobre cada um dos elementos designados acima).

Implemente as classes que permitem representar o texto completo, as palavras, respectivas modificações gráficas. Implemente ainda uma aplicação que ilustre o comportamento. Represente as características gráficas da seguinte forma:

  • normal <span>normal</span>
  • negrito <b>negrito</b>
  • itálico <i>itálico</i>
  • sublinhado <u>sublinhado</u>

Solução

A solução apresentada abaixo não contempla o método text. Deixa-se como exercício para o leitor.

Interface TextItem

Esta interface representa um item textual genérico, formatado ou não.

/**
 * Interface representing a text item.
 */
public interface TextItem {
	/**
	 * Text items can be rendered.
	 * 
	 * @return rendered text item.
	 */
	String render();
}

Class TextSpan

/**
 * A text span contains some text.
 */
public class TextSpan implements TextItem {

	/**
	 * The text in this span.
	 */
	private String _text;

	/**
	 * @param text
	 *            the text in this span.
	 */
	public TextSpan(String text) {
		_text = text;
	}

	/**
	 * @see TextItem#render()
	 */
	@Override
	public String render() {
		return "<span>" + _text + "</span>";
	}

}

Class TextFormat

The abstract format (root class for other formatting items).

Esta classe é menos geral que a apresentada no exercício 1.

/**
 * A text format may be applied to any text item.
 */
public abstract class TextFormat implements TextItem {

	/** The text item to format. */
	private TextItem _textItem;

        /** XML tag for delimiting text item. */
        private String _xmlTag;

	/**
	 * @param textItem
	 *            the text item to format.
	 */
	public TextFormat(TextItem textItem, String xmlTag) {
		_textItem = textItem;
                _xmlTag = xmlTag;
	}

	/**
	 * @see TextItem#render()
	 */
	public String render() {
		return "<" + _xmlTag + ">" + _textItem.render() + "</" + _xmlTag + ">";
	}

}

Class Bold

public class Bold extends TextFormat {

	/**
	 * @param textItem the text item to format.
	 */
	public Bold(TextItem textItem) {
		super(textItem, "b");
	}

}

Class Italic

public class Italic extends TextFormat {

	/**
	 * @param textItem the text item to format.
	 */
	public Italic(TextItem textItem) {
		super(textItem, "i");
	}

}

Class Underline

public class Underline extends TextFormat {

	/**
	 * @param textItem the text item to format.
	 */
	public Underline(TextItem textItem) {
		super(textItem, "u");
	}

}

Class App

Simple demo application.

public class App {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		TextItem span1 = new TextSpan("BATATA");
		TextItem text1 = new Bold(new Italic(span1));
		System.out.println(text1.render());
		
		TextItem span2 = new TextSpan("CEBOLA");
		TextItem text2 = new Underline(new Bold(new Italic(span2)));
		System.out.println(text2.render());
	}

}

Compiling and Running