Design Pattern: Implementando o Decorator

Posted by Alberto Leal on June 23rd, 2009

Photo: http://static.howstuffworks.com/gif/teen-bedroom-decorating-ideas-2.jpg

O último livro que terminei de ler era sobre Design Pattern. Então, resolvi fazer alguns posts contendo algumas implementações. O padrão de projeto da vez é o Decorator.

——–

O poder da composição

Têm quem ame, e têm quem odeie herança. Existem casos que não há como fugir da herança, mas, sempre que possível, prefira composição a herança. Quando utilizamos herança em uma parte da nossa aplicação, e alguns comportamentos são herdados, estes  são definidos estaticamente em tempo de compilação. Por outro lado, se você estender o comportamento de um objeto por meio de composição, você consegue fazer isso dinamicamente, ou seja, consegue compôr os objetos de forma dinâmica. Com isso, se torna fácil adicionar novas funcionalidades escrevendo um código novo ao invés de alterar o código existente. Isso é bacana, pois o comportamento anterior não é modificado, assim as chances de introdução de erros no código que já estava funcionando é menor. Se algo der errado, basta remover a nova classe que foi criada, por exemplo. Resumindo, mantenha as classes abertas para extensão e fechadas para alteração.

O padrão de projeto decorator anexa novas responsabilidades em um objeto dinamicamente, utilizando  do poder da composição.

Vamos ver como isso funciona na prática. O exemplo que lhe será apresentado é a construção de uma pizza. No momento do pedido, o cliente poderá pedir ao Pizzaiolo que adicione  novos ingredientes na pizza, tais como: orégano e tomate. Exemplo simples e direto, apenas para ilustrar.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package br.eti.albertoleal.decorator;
 
public abstract class Pizza {
 
private String description = "Unknown Pizza";
 
public void setDescription(String desc) {
description = desc;
}
 
public String getDescription(){
return description;
}
 
public abstract double cost();
 
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package br.eti.albertoleal.decorator;
 
public class Cheese extends Pizza {
 
	public Cheese(){
		setDescription("Cheese Pizza")
	}
 
	@Override
	public double cost() {
		return 19.90;
	}
 
}

As classes decorator devem ser espelhos das classes que elas vão decorar. Vamos utilizar da herança em nossos objetos do tipo CondimentDecorator. O motivo de se usar herança na classe Decorator é  pelo simples fato de se ter o mesmo tipo dos objetos que vão ser decorados. O uso de herança é justamente para atingir  essa correspondência de tipo.

1
2
3
4
5
package br.eti.albertoleal.decorator;
 
public abstract class CondimentDecorator extends Pizza {
 
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package br.eti.albertoleal.decorator;
 
public class Oregano extends CondimentDecorator {
	Pizza pizza;
 
	public Oregano(Pizza pz) {
		pizza = pz;
	}
 
	@Override
	public String getDescription() {
		return pizza.getDescription() + ", Oregano";
	}
 
	@Override
	public double cost() {
		return .50 + pizza.cost();
	}
 
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package br.eti.albertoleal.decorator;
 
public class Tomato extends CondimentDecorator {
	Pizza pizza;
 
	public Tomato(Pizza pz){
		pizza = pz;
	}
 
	@Override
	public String getDescription() {
		return pizza.getDescription() + ", Tomato ";
	}
 
	@Override
	public double cost() {
		return .10 + pizza.cost();
	}
 
}

Se você estava atento reparou que a cada condimento que é adicionado na pizza um valor correspondente ao condimento é somado ao valor da pizza. Essa é a idéia do decorator. Estou decorando um objeto pizza com diversos outros componentes. Um outro exemplo, bastante comum de se encontrar pela internet, são as janelas gráficas. O ato de decorar uma janela gráfica com diversos componentes de apresentação, tais como: barra de rolagem, campos de texto e por aí vai.

Chegou a hora de testarmos o nosso código, criar uma pizza e adicionar alguns condimentos a ela e constatar se a nossa “decoração” funciona:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package br.eti.albertoleal.decorator;
 
public class Pizzaiolo {
 
	public static void main(String[] args) {
 
		Pizza pz = new Cheese();
 
		pz = new Tomato(pz);
		pz = new Tomato(pz);
		pz = new Oregano(pz);
		pz = new Tomato(pz);
		pz = new Oregano(pz);
		pz = new Tomato(pz);
 
		System.out.println(pz.getDescription());		
 
	}
 
}

Concluindo:

  • A herança é uma maneira de estender comportamentos, mas não é a melhor maneira de obter flexibilidade;
  • Composição e delegação são boas maneiras de se adicionar funcionalidades em tempo de execução;
  • A utilização de um componente decorator é simplesmente decorar um objeto, e o objeto decorado não precisa conhecer os decoradores;
  • É muito importante que os objetos decoradores sejam espelhos do objeto que vão decorar, justamente para ter uma correspondência de tipo.

Mentawai - Template: “Bloqueando” chamada a JSP

Posted by Alberto on March 4th, 2008

Como já leram aqui no blog, escolhi o Mentawai para desenvolver um projeto em Java. Mas, como nem tudo são flores, meses atrás eu tive um problema com a utilização de “template” no menta. Por acreditar que outras pessoas já passaram pelo mesmo problema, vou passar adiante uma dica que o felipowsky me passou lá no fórum.

Para conhecer como funciona o recurso de template, basta acessar o site aqui. O próprio site do mentawai explica passo a passo, portanto, não mostrarei aqui como criar um template simples.

O PROBLEMA

Quando se trabalha com “template” no mentawai é permitido configurar a extensão dos arquivos e a forma como serão acessados (Desde que não seja “jsp”, senão ele lança exceção).

Ao acessar uma página com a extensão que foi definida, o recurso de template do framework incluirá a página dentro das tags definidas. Porém, se o usuário renomear na barra de endereço a extensão, passando “.JSP”, o arquivo será acessado e exibido sem qualquer formatação de layout.


A SOLUÇÃO

Tentei de “n” maneiras resolver este problema, e como sou marinheiro de primeira viagem não tive muito sucesso.

A idéia passada pelo felipowsky foi a seguinte:

Cria-se uma classe que estende ConventionController, chame-a de CustomConventionController:

import org.mentawai.template.ConventionController;

public class CustomConventionController extends ConventionController {

@Override
public String getRoot() {
return "/WEB-INF/Administracao";
}
}

E, no TemplateManager, ao invés de chamar ConventionController, chama-se a classe customizada ConventionControllerCustom:

import org.mentawai.template.Page;

import com.mentawaiexe.template.CustomConventionController;

public class TemplateManager extends org.mentawai.template.TemplateManager {

private static final String WEBINF_FOLDER = "/WEB-INF/";
private static final String DEFAULT_JSP_FOLDER = WEBINF_FOLDER + "Administracao/";

public void configurePages() {
Page page = new Page("Administracao/.*", DEFAULT_JSP_FOLDER + "home.jsp",  CustomConventionController.class);
add(page);
}
}

Está foi a solução que utilizei no meu projeto, e funciona perfeitamente.

Valeu felipowsky!

Atenção, atenção: O Java vai acabar!

Posted by Alberto on March 3rd, 2008

Acalmem-se, o título deste post é proposital!

Tudo começou quando saiu essa notícia aqui. E, foi suficiente para começar uma “revolução” no GUJ.

É fato que JAVA não vai acabar pelo menos nos próximos anos. Há quem diz que sistemas em Java são legados, já que RoR está conquistando mercado, assim como .Net (arghh..=X) . Basta “surgir” um novo amor na vida das pessoas para que elas mudem de opinião da noite para o dia. Ruby, e RoR estão no mercado ai há anos e nunca fizeram tanto sucesso como hoje. Agora, como muitos falam por ai, que Java vai acabar por causa de RoR, .Net, PHP, etc.. não dá para acreditar!

Tem mercado para todas as linguagens! Afinal, Cobol, por exemplo, está na ativa até hoje.

Basta ler a matéria com atenção que você perceberá o marketing da plataforma .Net:

“A Microsoft, porém, fez da sua plataforma .Net um player sério no cenário corporativo. Um relatório da Info-Tech Research Group datado de novembro de 2007 apontou que .Net estava se tornando mais popular do que a plataforma Java nas empresas.”

Ah, tem essa aqui que saiu na MeioBit também:

“E o quinhão da Microsoft é enorme: 80% dos novos servidores sendo que a .Net Framework também está ganhando mais da metade da preferência no desenvolvimento de novas aplicações rodando em servidor. Isso mostra que a criação de compiladores para Python, Ruby e PHP podem servir, na verdade, para aumentar a oferta de mão de obra para as empresas. “

É até interessante ver essas “brigas” no mercado. Mas, ao ver é totalmente irrelevante, já que não interessa se você desenvolveu em cobol, pascal, java, ruby, php, .net…, se você agradou ao seu cliente e o software funciona bem, pouco importa a tecnologia utilizada.

Um pouco sobre Hibernate

Posted by Alberto on January 16th, 2008

 

 

Como no post anterior eu citei o Annotations do hibernate, pensei em falar um pouco sobre o assunto e, posteriormente, mapear uma aplicação de exemplo.

– –

Afinal, o que é hibernate? Para que serve? Tenho mesmo que aprender mais um framework Java? …

São tantas as perguntas para quem está iniciando em Java, aliás, não somente para os iniciantes. Basta tomar conhecimento de uma nova ferramenta que tem como propósito aumentar a produtividade no desenvolvimento que dúvidas e mais dúvidas parecem “pipocar” na mente.

O Hibernate é um framework de persistência objeto relacional para aplicações Java. Ele faz o mapeamento das classes java para tabelas no banco de dados relacional (por exemplo: mysql, DB2, postgres..). Além de fornecer total liberdade e suporte para programar as classes seguindo as características do paradigma OO ( associação, polimorfismo, herança, coleções..).

O framework não serve apenas para fazer o MOR - Mapeamento Objeto Relacional. Todas as operações que envolvem banco de dados (CRUD, Select) podem ser feitas de forma transparente pelo hibernate.

E onde é que entram os Annotations ” ?..

Annotations são metadados que aparecem no código fonte e que são ignorados pelo compilador. Este recurso somente foi adicionado na versão Java SE 5.0 e sua utilização agrega significados especiais ao código fonte.

Atualmente, hibernate é um dos frameworks de persistência Java mais utilizados no mercado. Mas, não é o único e você não é obrigado a utilizá-lo se não gostar/desejar.

Screencast - Refatoração na Prática

Posted by Alberto on January 14th, 2008

Preparem a pipoca!!

É com muita satisfação que apresento à vocês o primeiro screencast do Blog.

Este é o primeiro de muitos. A idéia é publicar uma série de vídeos com dicas sobre desenvolvimento de software.

Para iniciar a nossa série de screencast, apresento-lhes o primeiro: “Refatoração na Prática”, onde mostro como aplicar técnicas de refactoring com o auxíio de uma IDE.

PS: Não pensava que daria tanto trabalho. Para quem nunca mexeu com edição de vídeo até que está muito bom. Por isso, peço que aliviem o meu lado nos primeiros vídeos.. =D

Espero que gostem…

Link no YouTube: http://www.youtube.com/watch?v=WPF6qriM8wo

Link para Download: http://www.albertoleal.eti.br/Screencast/ScreenCast-Refatoracao_na_Pratica.avi


Copyright © 2007 Alberto Leal. All rights reserved.